Make use of PHY port numbers as targets for the drives instead
of the internal PhysDriveNum. Also change ENXIO to EINVAL in
one case.
--- mpii.c- Tue Feb 9 19:07:12 2010
+++ mpii.c Tue Feb 9 19:11:22 2010
@@ -1346,44 +1346,43 @@ struct mpii_cfg_raid_vol_pg1 {
u_int32_t reserved2;
u_int32_t reserved3;
} __packed;
#define MPII_CFG_RAID_PHYS_DISK_ADDR_NUMBER (1<<28)
struct mpii_cfg_raid_physdisk_pg0 {
struct mpii_cfg_hdr config_header;
- u_int8_t phys_disk_id;
- u_int8_t phys_disk_bus;
- u_int8_t phys_disk_ioc;
+ u_int16_t dev_handle;
+ u_int8_t reserved1;
u_int8_t phys_disk_num;
u_int8_t enc_id;
u_int8_t enc_bus;
u_int8_t hot_spare_pool;
u_int8_t enc_type;
#define MPII_CFG_RAID_PHYDISK_0_ENCTYPE_NONE (0x0)
#define MPII_CFG_RAID_PHYDISK_0_ENCTYPE_SAFTE (0x1)
#define MPII_CFG_RAID_PHYDISK_0_ENCTYPE_SES (0x2)
- u_int32_t reserved1;
+ u_int32_t reserved2;
u_int8_t vendor_id[8];
u_int8_t product_id[16];
u_int8_t product_rev[4];
u_int8_t serial[32];
- u_int32_t reserved2;
+ u_int32_t reserved3;
u_int8_t phys_disk_state;
#define MPII_CFG_RAID_PHYDISK_0_STATE_NOTCONFIGURED (0x00)
#define MPII_CFG_RAID_PHYDISK_0_STATE_NOTCOMPATIBLE (0x01)
#define MPII_CFG_RAID_PHYDISK_0_STATE_OFFLINE (0x02)
#define MPII_CFG_RAID_PHYDISK_0_STATE_ONLINE (0x03)
#define MPII_CFG_RAID_PHYDISK_0_STATE_HOTSPARE (0x04)
#define MPII_CFG_RAID_PHYDISK_0_STATE_DEGRADED (0x05)
#define MPII_CFG_RAID_PHYDISK_0_STATE_REBUILDING (0x06)
#define MPII_CFG_RAID_PHYDISK_0_STATE_OPTIMAL (0x07)
@@ -1402,23 +1401,23 @@ struct mpii_cfg_raid_physdisk_pg0 {
#define MPII_CFG_RAID_PHYDISK_0_STATUS_OUTOFSYNC (1<<0)
#define MPII_CFG_RAID_PHYDISK_0_STATUS_QUIESCED (1<<1)
u_int64_t dev_max_lba;
u_int64_t host_max_lba;
u_int64_t coerced_max_lba;
u_int16_t block_size;
- u_int16_t reserved3;
+ u_int16_t reserved4;
- u_int32_t reserved4;
+ u_int32_t reserved5;
} __packed;
struct mpii_cfg_raid_physdisk_pg1 {
struct mpii_cfg_hdr config_header;
u_int8_t num_phys_disk_paths;
u_int8_t phys_disk_num;
u_int16_t reserved1;
u_int32_t reserved2;
@@ -2188,20 +2186,21 @@ void mpii_reorder_boot_device(struct
mpii_softc *);
#if NBIO > 0
int mpii_ioctl(struct device *, u_long, caddr_t);
int mpii_ioctl_inq(struct mpii_softc *, struct bioc_inq *);
int mpii_ioctl_vol(struct mpii_softc *, struct bioc_vol *);
int mpii_ioctl_disk(struct mpii_softc *, struct bioc_disk *);
int mpii_bio_hs(struct mpii_softc *, struct bioc_disk *, int,
u_int8_t, int *);
int mpii_bio_disk(struct mpii_softc *, struct bioc_disk *,
u_int8_t);
+int mpii_bio_getphy(struct mpii_softc *, u_int16_t, u_int16_t *);
#ifndef SMALL_KERNEL
int mpii_bio_volstate(struct mpii_softc *, struct bioc_vol *);
int mpii_create_sensors(struct mpii_softc *);
void mpii_refresh_sensors(void *);
#endif /* SMALL_KERNEL */
#endif /* NBIO > 0 */
#define DEVNAME(s) ((s)->sc_dev.dv_xname)
#define dwordsof(s) (sizeof(s) / sizeof(u_int32_t))
@@ -5351,21 +5350,21 @@ mpii_bio_hs(struct mpii_softc *sc, struct bioc_disk *b
printf("%s: unable to allocate space for raid config page 0\n",
DEVNAME(sc));
return (ENOMEM);
}
if (mpii_req_cfg_page(sc, MPII_CFG_RAID_CONFIG_ACTIVE_CONFIG,
MPII_PG_EXTENDED, &ehdr, 1, cpg, pagelen) != 0) {
printf("%s: unable to fetch raid config page 0\n",
DEVNAME(sc));
free(cpg, M_TEMP);
- return (ENXIO);
+ return (EINVAL);
}
el = (struct mpii_raid_config_element *)(cpg + 1);
for (i = 0; i < cpg->num_elements; i++, el++) {
if (ISSET(el->element_flags,
MPII_RAID_CONFIG_ELEMENT_FLAG_HSP_PHYS_DISK) &&
el->hot_spare_pool == hsmap) {
/*
* diskid comparison is based on the idea that all
* disks are counted by the bio(4) in sequence, thus
@@ -5406,22 +5405,22 @@ mpii_bio_disk(struct mpii_softc *sc, struct bioc_disk
hdr.page_number = 0;
hdr.page_type = MPII_CONFIG_REQ_PAGE_TYPE_RAID_PD;
if (mpii_req_cfg_page(sc, MPII_CFG_RAID_PHYS_DISK_ADDR_NUMBER | dn, 0,
&hdr, 1, &ppg, sizeof(ppg)) != 0) {
printf("%s: unable to fetch raid drive page 0\n",
DEVNAME(sc));
return (EINVAL);
}
- bd->bd_channel = ppg.phys_disk_bus;
- bd->bd_target = ppg.phys_disk_num;
+ if (mpii_bio_getphy(sc, ppg.dev_handle, &bd->bd_target))
+ bd->bd_target = ppg.phys_disk_num;
switch (ppg.phys_disk_state) {
case MPII_CFG_RAID_PHYDISK_0_STATE_ONLINE:
case MPII_CFG_RAID_PHYDISK_0_STATE_OPTIMAL:
bd->bd_status = BIOC_SDONLINE;
break;
case MPII_CFG_RAID_PHYDISK_0_STATE_OFFLINE:
bd->bd_status = BIOC_SDOFFLINE;
break;
case MPII_CFG_RAID_PHYDISK_0_STATE_DEGRADED:
@@ -5438,20 +5437,46 @@ mpii_bio_disk(struct mpii_softc *sc, struct bioc_disk
break;
case MPII_CFG_RAID_PHYDISK_0_STATE_NOTCOMPATIBLE:
bd->bd_status = BIOC_SDINVALID;
break;
}
bd->bd_size = letoh64(ppg.dev_max_lba) * letoh16(ppg.block_size);
scsi_strvis(bd->bd_vendor, ppg.product_id, sizeof(ppg.product_id));
scsi_strvis(bd->bd_serial, ppg.serial, sizeof(ppg.serial));
+
+ return (0);
+}
+
+int
+mpii_bio_getphy(struct mpii_softc *sc, u_int16_t dh, u_int16_t *port)
+{
+ struct mpii_cfg_sas_dev_pg0 spg;
+ struct mpii_ecfg_hdr ehdr;
+
+ if (!port)
+ return (EINVAL);
+
+ bzero(&ehdr, sizeof(ehdr));
+ ehdr.page_type = MPII_CONFIG_REQ_PAGE_TYPE_EXTENDED;
+ ehdr.ext_page_length = sizeof(spg) / 4;
+ ehdr.ext_page_type = MPII_CONFIG_REQ_PAGE_TYPE_SAS_DEVICE;
+
+ if (mpii_req_cfg_page(sc, MPII_CFG_SAS_DEV_ADDR_HANDLE | dh,
+ MPII_PG_EXTENDED, &ehdr, 1, &spg, sizeof(spg)) != 0) {
+ printf("%s: unable to fetch sas device page 0\n",
+ DEVNAME(sc));
+ return (EINVAL);
+ }
+
+ *port = spg.phy_num;
return (0);
}
#ifndef SMALL_KERNEL
int
mpii_bio_volstate(struct mpii_softc *sc, struct bioc_vol *bv)
{
struct mpii_cfg_raid_vol_pg0 *vpg;
struct mpii_cfg_hdr hdr;