diff -uNr linux-campbell/drivers/scsi/qla2xxx/qla2x00.c linux-hotswap-gamap-ng/drivers/scsi/qla2xxx/qla2x00.c --- linux-campbell/drivers/scsi/qla2xxx/qla2x00.c Fri Jun 21 13:56:35 2002 +++ linux-hotswap-gamap-ng/drivers/scsi/qla2xxx/qla2x00.c Mon Jul 22 15:52:09 2002 @@ -244,6 +244,8 @@ STATIC uint8_t qla2x00_register_with_Linux(scsi_qla_host_t *ha, uint8_t maxchannels); STATIC int qla2x00_done(scsi_qla_host_t *); STATIC void qla2x00_select_queue_depth(struct Scsi_Host *, Scsi_Device *); +int qla2x00_get_scsi_info_from_wwn (int mode, unsigned long long wwn, int *host, int *channel, int *lun, int *id); +int qla2x00_get_wwn_from_scsi_info (int host, int id, unsigned long long *wwn); STATIC void qla2x00_timer(scsi_qla_host_t *); @@ -2036,6 +2038,9 @@ host->can_queue = max_srbs; /* default value:-MAX_SRBS(4096) */ host->cmd_per_lun = 1; host->select_queue_depths = qla2x00_select_queue_depth; + host->hostt->get_scsi_info_from_wwn = qla2x00_get_scsi_info_from_wwn; + host->hostt->get_wwn_from_scsi_info = qla2x00_get_wwn_from_scsi_info; + host->n_io_port = 0xFF; #if MEMORY_MAPPED_IO @@ -3983,6 +3988,107 @@ } +union wwnmap { + unsigned long long wwn; + unsigned char wwn_u8[8]; +}; + +int qla2x00_get_scsi_info_from_wwn (int mode, + unsigned long long wwn, + int *host, + int *channel, + int *lun, + int *id) { + +scsi_qla_host_t *list; +Scsi_Device *scsi_device; +union wwnmap wwncompare; +union wwnmap wwncompare2; +int i, j, k; + + /* + * Retrieve big endian version of world wide name + */ + wwncompare2.wwn = wwn; + for (j = 0, k=7; j < 8; j++, k--) { + wwncompare.wwn_u8[j] = wwncompare2.wwn_u8[k]; + } + + /* + * query all hosts searching for WWN + */ + for (list = qla2x00_hostlist; list; list = list->next) { + for (i = 0; i < MAX_FIBRE_DEVICES; i++) { + /* + * Scan all devices in FibreChannel database + * if WWN match found, return SCSI device information + */ + if (memcmp (wwncompare.wwn_u8, list->fc_db[i].wwn, 8) == 0) { + /* + * If inserting, avoid scan for channel and lun information + */ + if (mode == 0) { + *channel = 0; + *lun = 0; + *host = list->host->host_no; + *id = i; + return (0); + } + + + /* + * WWN matches, find channel and lun information from scsi + * device + */ + for (scsi_device = list->host->host_queue; scsi_device; scsi_device = scsi_device->next) { + if (scsi_device->id == i) { + *channel = scsi_device->channel; + *lun = scsi_device->lun; + break; + } + } + if (scsi_device == 0) { + return (-ENOENT); + } + /* + * Device found, return all data + */ + *host = list->host->host_no; + *id = i; + return (0); + } /* memcmp */ + } /* i < MAXFIBREDEVICES */ + } + return (-ENOENT); +} + +int qla2x00_get_wwn_from_scsi_info (int host, int id, unsigned long long *wwn) { +scsi_qla_host_t *list; +union wwnmap wwnendian; +union wwnmap wwnendian2; +int j, k; + + /* + * Examine all QLogic hosts + */ + for (list = qla2x00_hostlist; list; list = list->next) { + if (host == list->host->host_no) { + /* + * Get endian corrected 64 bit WWN + */ +printk ("host %d list id %d\n", host, id); + memcpy (&wwnendian2.wwn, list->fc_db[id].wwn, 8); + for (j = 0, k=7; j < 8; j++, k--) { + wwnendian.wwn_u8[j] = wwnendian2.wwn_u8[k]; + } + *wwn = wwnendian.wwn; + printk ("Returning WWN %08llx\n", *wwn); + return (0); + } + } + return (-ENOENT); +} + /************************************************************************** * qla2x00_select_queue_depth *