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;

Reply via email to