diff options
Diffstat (limited to 'drivers/scsi/device_handler/scsi_dh_rdac.c')
-rw-r--r-- | drivers/scsi/device_handler/scsi_dh_rdac.c | 82 |
1 files changed, 43 insertions, 39 deletions
diff --git a/drivers/scsi/device_handler/scsi_dh_rdac.c b/drivers/scsi/device_handler/scsi_dh_rdac.c index 2e7c136bb805..27c9d65d54a9 100644 --- a/drivers/scsi/device_handler/scsi_dh_rdac.c +++ b/drivers/scsi/device_handler/scsi_dh_rdac.c @@ -128,25 +128,7 @@ struct c4_inquiry { u8 reserved[2]; }; -struct rdac_controller { - u8 subsys_id[SUBSYS_ID_LEN]; - u8 slot_id[SLOT_ID_LEN]; - int use_ms10; - struct kref kref; - struct list_head node; /* list of all controllers */ - union { - struct rdac_pg_legacy legacy; - struct rdac_pg_expanded expanded; - } mode_select; - u8 index; - u8 array_name[ARRAY_LABEL_LEN]; - spinlock_t ms_lock; - int ms_queued; - struct work_struct ms_work; - struct scsi_device *ms_sdev; - struct list_head ms_head; -}; - +#define UNIQUE_ID_LEN 16 struct c8_inquiry { u8 peripheral_info; u8 page_code; /* 0xC8 */ @@ -159,12 +141,31 @@ struct c8_inquiry { u8 vol_user_label_len; u8 vol_user_label[60]; u8 array_uniq_id_len; - u8 array_unique_id[16]; + u8 array_unique_id[UNIQUE_ID_LEN]; u8 array_user_label_len; u8 array_user_label[60]; u8 lun[8]; }; +struct rdac_controller { + u8 array_id[UNIQUE_ID_LEN]; + int use_ms10; + struct kref kref; + struct list_head node; /* list of all controllers */ + union { + struct rdac_pg_legacy legacy; + struct rdac_pg_expanded expanded; + } mode_select; + u8 index; + u8 array_name[ARRAY_LABEL_LEN]; + struct Scsi_Host *host; + spinlock_t ms_lock; + int ms_queued; + struct work_struct ms_work; + struct scsi_device *ms_sdev; + struct list_head ms_head; +}; + struct c2_inquiry { u8 peripheral_info; u8 page_code; /* 0xC2 */ @@ -369,16 +370,17 @@ static void release_controller(struct kref *kref) kfree(ctlr); } -static struct rdac_controller *get_controller(u8 *subsys_id, u8 *slot_id, - char *array_name) +static struct rdac_controller *get_controller(int index, char *array_name, + u8 *array_id, struct scsi_device *sdev) { struct rdac_controller *ctlr, *tmp; spin_lock(&list_lock); list_for_each_entry(tmp, &ctlr_list, node) { - if ((memcmp(tmp->subsys_id, subsys_id, SUBSYS_ID_LEN) == 0) && - (memcmp(tmp->slot_id, slot_id, SLOT_ID_LEN) == 0)) { + if ((memcmp(tmp->array_id, array_id, UNIQUE_ID_LEN) == 0) && + (tmp->index == index) && + (tmp->host == sdev->host)) { kref_get(&tmp->kref); spin_unlock(&list_lock); return tmp; @@ -389,16 +391,11 @@ static struct rdac_controller *get_controller(u8 *subsys_id, u8 *slot_id, goto done; /* initialize fields of controller */ - memcpy(ctlr->subsys_id, subsys_id, SUBSYS_ID_LEN); - memcpy(ctlr->slot_id, slot_id, SLOT_ID_LEN); + memcpy(ctlr->array_id, array_id, UNIQUE_ID_LEN); + ctlr->index = index; + ctlr->host = sdev->host; memcpy(ctlr->array_name, array_name, ARRAY_LABEL_LEN); - /* update the controller index */ - if (slot_id[1] == 0x31) - ctlr->index = 0; - else - ctlr->index = 1; - kref_init(&ctlr->kref); ctlr->use_ms10 = -1; ctlr->ms_queued = 0; @@ -444,7 +441,7 @@ done: } static int get_lun_info(struct scsi_device *sdev, struct rdac_dh_data *h, - char *array_name) + char *array_name, u8 *array_id) { int err, i; struct c8_inquiry *inqp; @@ -463,6 +460,8 @@ static int get_lun_info(struct scsi_device *sdev, struct rdac_dh_data *h, *(array_name+i) = inqp->array_user_label[(2*i)+1]; *(array_name+ARRAY_LABEL_LEN-1) = '\0'; + memset(array_id, 0, UNIQUE_ID_LEN); + memcpy(array_id, inqp->array_unique_id, inqp->array_uniq_id_len); } return err; } @@ -504,16 +503,20 @@ static int check_ownership(struct scsi_device *sdev, struct rdac_dh_data *h) } static int initialize_controller(struct scsi_device *sdev, - struct rdac_dh_data *h, char *array_name) + struct rdac_dh_data *h, char *array_name, u8 *array_id) { - int err; + int err, index; struct c4_inquiry *inqp; err = submit_inquiry(sdev, 0xC4, sizeof(struct c4_inquiry), h); if (err == SCSI_DH_OK) { inqp = &h->inq.c4; - h->ctlr = get_controller(inqp->subsys_id, inqp->slot_id, - array_name); + /* get the controller index */ + if (inqp->slot_id[1] == 0x31) + index = 0; + else + index = 1; + h->ctlr = get_controller(index, array_name, array_id, sdev); if (!h->ctlr) err = SCSI_DH_RES_TEMP_UNAVAIL; } @@ -835,6 +838,7 @@ static int rdac_bus_attach(struct scsi_device *sdev) unsigned long flags; int err; char array_name[ARRAY_LABEL_LEN]; + char array_id[UNIQUE_ID_LEN]; scsi_dh_data = kzalloc(sizeof(*scsi_dh_data) + sizeof(*h) , GFP_KERNEL); @@ -849,11 +853,11 @@ static int rdac_bus_attach(struct scsi_device *sdev) h->lun = UNINITIALIZED_LUN; h->state = RDAC_STATE_ACTIVE; - err = get_lun_info(sdev, h, array_name); + err = get_lun_info(sdev, h, array_name, array_id); if (err != SCSI_DH_OK) goto failed; - err = initialize_controller(sdev, h, array_name); + err = initialize_controller(sdev, h, array_name, array_id); if (err != SCSI_DH_OK) goto failed; |