Commit a1358083 authored by Doug Ledford's avatar Doug Ledford Committed by Doug Ledford

Convert from host->host_queue to host->my_devices list usage

Add in usage of new same_target_siblings list
Add scsi_release_commandblocks() call to scsi_free_sdev()
Make all scsi device freeing use scsi_free_sdev()
parent 10c30c0f
...@@ -1513,7 +1513,7 @@ NCR_700_intr(int irq, void *dev_id, struct pt_regs *regs) ...@@ -1513,7 +1513,7 @@ NCR_700_intr(int irq, void *dev_id, struct pt_regs *regs)
host->host_no, SCp, SCp == NULL ? NULL : SCp->host_scribble, dsp, dsp - hostdata->pScript); host->host_no, SCp, SCp == NULL ? NULL : SCp->host_scribble, dsp, dsp - hostdata->pScript);
/* clear all the negotiated parameters */ /* clear all the negotiated parameters */
for(SDp = host->host_queue; SDp != NULL; SDp = SDp->next) list_for_each_entry(SDp, &host->my_devices, siblings)
SDp->hostdata = 0; SDp->hostdata = 0;
/* clear all the slots and their pending commands */ /* clear all the slots and their pending commands */
...@@ -1740,7 +1740,7 @@ NCR_700_proc_directory_info(char *proc_buf, char **startp, ...@@ -1740,7 +1740,7 @@ NCR_700_proc_directory_info(char *proc_buf, char **startp,
len += sprintf(&buf[len],"\ len += sprintf(&buf[len],"\
Target Depth Active Next Tag\n\ Target Depth Active Next Tag\n\
====== ===== ====== ========\n"); ====== ===== ====== ========\n");
for(SDp = host->host_queue; SDp != NULL; SDp = SDp->next) { list_for_each_entry(SDp, &host->my_devices, siblings) {
len += sprintf(&buf[len]," %2d:%2d %4d %4d %4d\n", SDp->id, SDp->lun, SDp->current_queue_depth, NCR_700_get_depth(SDp), SDp->current_tag); len += sprintf(&buf[len]," %2d:%2d %4d %4d %4d\n", SDp->id, SDp->lun, SDp->current_queue_depth, NCR_700_get_depth(SDp), SDp->current_tag);
} }
if((len -= offset) <= 0) if((len -= offset) <= 0)
......
...@@ -865,13 +865,13 @@ static int esp_host_info(struct NCR_ESP *esp, char *ptr, off_t offset, int len) ...@@ -865,13 +865,13 @@ static int esp_host_info(struct NCR_ESP *esp, char *ptr, off_t offset, int len)
copy_info(&info, "Target #\tconfig3\t\tSync Capabilities\tDisconnect\n"); copy_info(&info, "Target #\tconfig3\t\tSync Capabilities\tDisconnect\n");
for(i = 0; i < 15; i++) { for(i = 0; i < 15; i++) {
if(esp->targets_present & (1 << i)) { if(esp->targets_present & (1 << i)) {
Scsi_Device *SDptr = esp->ehost->host_queue; Scsi_Device *SDptr;
struct esp_device *esp_dev; struct esp_device *esp_dev;
while((SDptr->host != esp->ehost) && list_for_each_entry(SDptr, &esp->ehost->my_devices,
(SDptr->id != i) && siblings)
(SDptr->next)) if(SDptr->id == i)
SDptr = SDptr->next; break;
esp_dev = SDptr->hostdata; esp_dev = SDptr->hostdata;
copy_info(&info, "%d\t\t", i); copy_info(&info, "%d\t\t", i);
......
...@@ -4398,7 +4398,7 @@ advansys_proc_info(char *buffer, char **start, off_t offset, int length, ...@@ -4398,7 +4398,7 @@ advansys_proc_info(char *buffer, char **start, off_t offset, int length,
* Display target driver information for each device attached * Display target driver information for each device attached
* to the board. * to the board.
*/ */
for (scd = shp->host_queue; scd; scd = scd->next) list_for_each_entry (scd, &shp->my_devices, siblings)
{ {
if (scd->host == shp) { if (scd->host == shp) {
cp = boardp->prtbuf; cp = boardp->prtbuf;
...@@ -9387,8 +9387,8 @@ asc_prt_scsi_host(struct Scsi_Host *s) ...@@ -9387,8 +9387,8 @@ asc_prt_scsi_host(struct Scsi_Host *s)
#if ASC_LINUX_KERNEL24 #if ASC_LINUX_KERNEL24
printk( printk(
" host_queue 0x%lx, hostt 0x%lx\n", " hostt 0x%lx\n",
(ulong) s->host_queue, (ulong) s->hostt); (ulong) s->hostt);
#elif ASC_LINUX_KERNEL22 #elif ASC_LINUX_KERNEL22
printk( printk(
" host_queue 0x%lx, hostt 0x%lx, block 0x%lx,\n", " host_queue 0x%lx, hostt 0x%lx, block 0x%lx,\n",
......
...@@ -3487,7 +3487,6 @@ static void RevalidateSEST( struct Scsi_Host *HostAdapter, ...@@ -3487,7 +3487,6 @@ static void RevalidateSEST( struct Scsi_Host *HostAdapter,
static void UnblockScsiDevice( struct Scsi_Host *HostAdapter, static void UnblockScsiDevice( struct Scsi_Host *HostAdapter,
PFC_LOGGEDIN_PORT pLoggedInPort) PFC_LOGGEDIN_PORT pLoggedInPort)
{ {
// Scsi_Device *sdev = HostAdapter->host_queue;
CPQFCHBA *cpqfcHBAdata = (CPQFCHBA *)HostAdapter->hostdata; CPQFCHBA *cpqfcHBAdata = (CPQFCHBA *)HostAdapter->hostdata;
Scsi_Cmnd* *SCptr = &cpqfcHBAdata->LinkDnCmnd[0]; Scsi_Cmnd* *SCptr = &cpqfcHBAdata->LinkDnCmnd[0];
Scsi_Cmnd *Cmnd; Scsi_Cmnd *Cmnd;
......
...@@ -2509,20 +2509,13 @@ static void adpt_fail_posted_scbs(adpt_hba* pHba) ...@@ -2509,20 +2509,13 @@ static void adpt_fail_posted_scbs(adpt_hba* pHba)
Scsi_Cmnd* cmd = NULL; Scsi_Cmnd* cmd = NULL;
Scsi_Device* d = NULL; Scsi_Device* d = NULL;
if( pHba->host->host_queue != NULL ) { list_for_each_entry(d, &pHba->host->my_devices, siblings) {
d = pHba->host->host_queue; for(cmd = d->device_queue; cmd ; cmd = cmd->next){
if(!d){ if(cmd->serial_number == 0){
return; continue;
}
while( d->next != NULL ){
for(cmd = d->device_queue; cmd ; cmd = cmd->next){
if(cmd->serial_number == 0){
continue;
}
cmd->result = (DID_OK << 16) | (QUEUE_FULL <<1);
cmd->scsi_done(cmd);
} }
d = d->next; cmd->result = (DID_OK << 16) | (QUEUE_FULL <<1);
cmd->scsi_done(cmd);
} }
} }
} }
......
...@@ -431,11 +431,11 @@ int eata_proc_info(char *buffer, char **start, off_t offset, int length, ...@@ -431,11 +431,11 @@ int eata_proc_info(char *buffer, char **start, off_t offset, int length,
} }
size = sprintf(buffer+len,"Attached devices: %s\n", size = sprintf(buffer+len,"Attached devices: %s\n",
(HBA_ptr->host_queue)?"":"none"); (!list_empty(&HBA_ptr->my_devices))?"":"none");
len += size; len += size;
pos = begin + len; pos = begin + len;
for(scd = HBA_ptr->host_queue; scd; scd = scd->next) { list_for_each_entry(scd, &HBA_ptr->my_devices, siblings) {
proc_print_scsidevice(scd, buffer, &size, len); proc_print_scsidevice(scd, buffer, &size, len);
len += size; len += size;
pos = begin + len; pos = begin + len;
......
...@@ -81,11 +81,11 @@ int eata_pio_proc_info(char *buffer, char **start, off_t offset, int length, ...@@ -81,11 +81,11 @@ int eata_pio_proc_info(char *buffer, char **start, off_t offset, int length,
goto stop_output; goto stop_output;
size = sprintf(buffer+len,"Attached devices: %s\n", size = sprintf(buffer+len,"Attached devices: %s\n",
(HBA_ptr->host_queue)?"":"none"); (!list_empty(&HBA_ptr->my_devices))?"":"none");
len += size; len += size;
pos = begin + len; pos = begin + len;
for(scd = HBA_ptr->host_queue; scd; scd = scd->next) { list_for_each_entry(scd, &HBA_ptr->my_devices; siblings) {
proc_print_scsidevice(scd, buffer, &size, len); proc_print_scsidevice(scd, buffer, &size, len);
len += size; len += size;
pos = begin + len; pos = begin + len;
......
...@@ -1364,13 +1364,13 @@ static int esp_host_info(struct esp *esp, char *ptr, off_t offset, int len) ...@@ -1364,13 +1364,13 @@ static int esp_host_info(struct esp *esp, char *ptr, off_t offset, int len)
copy_info(&info, "Target #\tconfig3\t\tSync Capabilities\tDisconnect\tWide\n"); copy_info(&info, "Target #\tconfig3\t\tSync Capabilities\tDisconnect\tWide\n");
for (i = 0; i < 15; i++) { for (i = 0; i < 15; i++) {
if (esp->targets_present & (1 << i)) { if (esp->targets_present & (1 << i)) {
Scsi_Device *SDptr = esp->ehost->host_queue; Scsi_Device *SDptr;
struct esp_device *esp_dev; struct esp_device *esp_dev;
while ((SDptr->host != esp->ehost) && list_for_each_entry(SDptr, &esp->ehost->my_devices,
(SDptr->id != i) && siblings)
(SDptr->next)) if(SDptr->id == i)
SDptr = SDptr->next; break;
esp_dev = SDptr->hostdata; esp_dev = SDptr->hostdata;
copy_info(&info, "%d\t\t", i); copy_info(&info, "%d\t\t", i);
......
...@@ -229,7 +229,7 @@ int fcal_proc_info (char *buffer, char **start, off_t offset, int length, int ho ...@@ -229,7 +229,7 @@ int fcal_proc_info (char *buffer, char **start, off_t offset, int length, int ho
#endif #endif
SPRINTF ("Initiator AL-PA: %02x\n", fc->sid); SPRINTF ("Initiator AL-PA: %02x\n", fc->sid);
SPRINTF ("\nAttached devices: %s\n", host->host_queue ? "" : "none"); SPRINTF ("\nAttached devices: %s\n", !list_empty(&host->my_devices) ? "" : "none");
for (i = 0; i < fc->posmap->len; i++) { for (i = 0; i < fc->posmap->len; i++) {
unsigned char alpa = fc->posmap->list[i]; unsigned char alpa = fc->posmap->list[i];
...@@ -246,8 +246,8 @@ int fcal_proc_info (char *buffer, char **start, off_t offset, int length, int ho ...@@ -246,8 +246,8 @@ int fcal_proc_info (char *buffer, char **start, off_t offset, int length, int ho
alpa, u1[0], u1[1], u2[0], u2[1]); alpa, u1[0], u1[1], u2[0], u2[1]);
} else { } else {
Scsi_Device *scd; Scsi_Device *scd;
for (scd = host->host_queue ; scd; scd = scd->next) list_for_each_entry (scd, &host->my_devices, siblings)
if (scd->host->host_no == hostno && scd->id == target) { if (scd->id == target) {
SPRINTF (" [AL-PA: %02x, Id: %02d, Port WWN: %08x%08x, Node WWN: %08x%08x] ", SPRINTF (" [AL-PA: %02x, Id: %02d, Port WWN: %08x%08x, Node WWN: %08x%08x] ",
alpa, target, u1[0], u1[1], u2[0], u2[1]); alpa, target, u1[0], u1[1], u2[0], u2[1]);
SPRINTF ("%s ", (scd->type < MAX_SCSI_DEVICE_CODE) ? SPRINTF ("%s ", (scd->type < MAX_SCSI_DEVICE_CODE) ?
......
...@@ -814,7 +814,7 @@ int generic_NCR5380_proc_info(char *buffer, char **start, off_t offset, int leng ...@@ -814,7 +814,7 @@ int generic_NCR5380_proc_info(char *buffer, char **start, off_t offset, int leng
PRINTP(" %d pending writes" ANDP hostdata->pendingw); PRINTP(" %d pending writes" ANDP hostdata->pendingw);
if (hostdata->pendingr || hostdata->pendingw) if (hostdata->pendingr || hostdata->pendingw)
PRINTP("\n"); PRINTP("\n");
for (dev = scsi_ptr->host_queue; dev; dev = dev->next) { list_for_each_entry (dev, &scsi_ptr->my_devices, siblings) {
unsigned long br = hostdata->bytes_read[dev->id]; unsigned long br = hostdata->bytes_read[dev->id];
unsigned long bw = hostdata->bytes_write[dev->id]; unsigned long bw = hostdata->bytes_write[dev->id];
long tr = hostdata->time_read[dev->id] / HZ; long tr = hostdata->time_read[dev->id] / HZ;
......
...@@ -239,7 +239,7 @@ static int scsi_check_device_busy(struct scsi_device *sdev) ...@@ -239,7 +239,7 @@ static int scsi_check_device_busy(struct scsi_device *sdev)
scmd->request->rq_status, scmd->target, scmd->request->rq_status, scmd->target,
scmd->pid, scmd->state, scmd->owner); scmd->pid, scmd->state, scmd->owner);
for (sdev = shost->host_queue; sdev; sdev = sdev->next) { list_for_each_entry(sdev, &shost->my_devices, siblings) {
for (scmd = sdev->device_queue; scmd; scmd = scmd->next) { for (scmd = sdev->device_queue; scmd; scmd = scmd->next) {
if (scmd->request->rq_status == RQ_SCSI_DISCONNECTING) if (scmd->request->rq_status == RQ_SCSI_DISCONNECTING)
scmd->request->rq_status = RQ_INACTIVE; scmd->request->rq_status = RQ_INACTIVE;
...@@ -260,16 +260,17 @@ static int scsi_check_device_busy(struct scsi_device *sdev) ...@@ -260,16 +260,17 @@ static int scsi_check_device_busy(struct scsi_device *sdev)
int scsi_remove_host(struct Scsi_Host *shost) int scsi_remove_host(struct Scsi_Host *shost)
{ {
struct scsi_device *sdev; struct scsi_device *sdev;
struct list_head *le, *lh;
/* /*
* FIXME Do ref counting. We force all of the devices offline to * FIXME Do ref counting. We force all of the devices offline to
* help prevent race conditions where other hosts/processors could * help prevent race conditions where other hosts/processors could
* try and get in and queue a command. * try and get in and queue a command.
*/ */
for (sdev = shost->host_queue; sdev; sdev = sdev->next) list_for_each_entry(sdev, &shost->my_devices, siblings)
sdev->online = FALSE; sdev->online = FALSE;
for (sdev = shost->host_queue; sdev; sdev = sdev->next) list_for_each_entry(sdev, &shost->my_devices, siblings)
if (scsi_check_device_busy(sdev)) if (scsi_check_device_busy(sdev))
return 1; return 1;
...@@ -277,7 +278,7 @@ int scsi_remove_host(struct Scsi_Host *shost) ...@@ -277,7 +278,7 @@ int scsi_remove_host(struct Scsi_Host *shost)
* Next we detach the high level drivers from the Scsi_Device * Next we detach the high level drivers from the Scsi_Device
* structures * structures
*/ */
for (sdev = shost->host_queue; sdev; sdev = sdev->next) { list_for_each_entry(sdev, &shost->my_devices, siblings) {
scsi_detach_device(sdev); scsi_detach_device(sdev);
/* If something still attached, punt */ /* If something still attached, punt */
...@@ -292,14 +293,8 @@ int scsi_remove_host(struct Scsi_Host *shost) ...@@ -292,14 +293,8 @@ int scsi_remove_host(struct Scsi_Host *shost)
/* Next we free up the Scsi_Cmnd structures for this host */ /* Next we free up the Scsi_Cmnd structures for this host */
for (sdev = shost->host_queue; sdev; list_for_each_safe(le, lh, &shost->my_devices) {
sdev = shost->host_queue) { scsi_free_sdev(list_entry(le, Scsi_Device, siblings));
blk_cleanup_queue(&sdev->request_queue);
/* Next free up the Scsi_Device structures for this host */
shost->host_queue = sdev->next;
if (sdev->inquiry)
kfree(sdev->inquiry);
kfree(sdev);
} }
return 0; return 0;
...@@ -309,7 +304,7 @@ int scsi_add_host(struct Scsi_Host *shost) ...@@ -309,7 +304,7 @@ int scsi_add_host(struct Scsi_Host *shost)
{ {
Scsi_Host_Template *sht = shost->hostt; Scsi_Host_Template *sht = shost->hostt;
struct scsi_device *sdev; struct scsi_device *sdev;
int error = 0; int error = 0, saved_error = 0;
printk(KERN_INFO "scsi%d : %s\n", shost->host_no, printk(KERN_INFO "scsi%d : %s\n", shost->host_no,
sht->info ? sht->info(shost) : sht->name); sht->info ? sht->info(shost) : sht->name);
...@@ -317,15 +312,13 @@ int scsi_add_host(struct Scsi_Host *shost) ...@@ -317,15 +312,13 @@ int scsi_add_host(struct Scsi_Host *shost)
device_register(&shost->host_driverfs_dev); device_register(&shost->host_driverfs_dev);
scsi_scan_host(shost); scsi_scan_host(shost);
for (sdev = shost->host_queue; sdev; sdev = sdev->next) { list_for_each_entry (sdev, &shost->my_devices, siblings) {
if (sdev->host->hostt != sht)
continue; /* XXX(hch): can this really happen? */
error = scsi_attach_device(sdev); error = scsi_attach_device(sdev);
if (error) if (error)
break; saved_error = error;
} }
return error; return saved_error;
} }
/** /**
...@@ -689,10 +682,7 @@ void __init scsi_host_init(void) ...@@ -689,10 +682,7 @@ void __init scsi_host_init(void)
* Notes: * Notes:
* Attach a single Scsi_Device to the Scsi_Host - this should * Attach a single Scsi_Device to the Scsi_Host - this should
* be made to look like a "pseudo-device" that points to the * be made to look like a "pseudo-device" that points to the
* HA itself. For the moment, we include it at the head of * HA itself.
* the host_queue itself - I don't think we want to show this
* to the HA in select_queue_depths(), as this would probably confuse
* matters.
* *
* Note - this device is not accessible from any high-level * Note - this device is not accessible from any high-level
* drivers (including generics), which is probably not * drivers (including generics), which is probably not
......
...@@ -373,8 +373,6 @@ struct Scsi_Host ...@@ -373,8 +373,6 @@ struct Scsi_Host
* struct private is a way of marking it in a sort of C++ type of way. * struct private is a way of marking it in a sort of C++ type of way.
*/ */
struct list_head sh_list; struct list_head sh_list;
Scsi_Device * host_queue;
struct list_head all_scsi_hosts;
struct list_head my_devices; struct list_head my_devices;
spinlock_t default_lock; spinlock_t default_lock;
...@@ -599,9 +597,7 @@ static inline Scsi_Device *scsi_find_device(struct Scsi_Host *shost, ...@@ -599,9 +597,7 @@ static inline Scsi_Device *scsi_find_device(struct Scsi_Host *shost,
int channel, int pun, int lun) { int channel, int pun, int lun) {
Scsi_Device *sdev; Scsi_Device *sdev;
for (sdev = shost->host_queue; list_for_each_entry (sdev, &shost->my_devices, siblings)
sdev != NULL;
sdev = sdev->next)
if (sdev->channel == channel && sdev->id == pun if (sdev->channel == channel && sdev->id == pun
&& sdev->lun ==lun) && sdev->lun ==lun)
break; break;
......
...@@ -297,7 +297,7 @@ static void aha152x_config_cs(dev_link_t *link) ...@@ -297,7 +297,7 @@ static void aha152x_config_cs(dev_link_t *link)
for (host = scsi_host_get_next(NULL); host; for (host = scsi_host_get_next(NULL); host;
host = scsi_host_get_next(host)) host = scsi_host_get_next(host))
if (host->hostt == &driver_template) if (host->hostt == &driver_template)
for (dev = host->host_queue; dev; dev = dev->next) { list_for_each_entry (dev, &host->my_devices, siblings) {
u_long arg[2], id; u_long arg[2], id;
kernel_scsi_ioctl(dev, SCSI_IOCTL_GET_IDLUN, arg); kernel_scsi_ioctl(dev, SCSI_IOCTL_GET_IDLUN, arg);
id = (arg[0]&0x0f) + ((arg[0]>>4)&0xf0) + id = (arg[0]&0x0f) + ((arg[0]>>4)&0xf0) +
......
...@@ -261,7 +261,7 @@ static void fdomain_config(dev_link_t *link) ...@@ -261,7 +261,7 @@ static void fdomain_config(dev_link_t *link)
for (host = scsi_host_get_next(NULL); host; for (host = scsi_host_get_next(NULL); host;
host = scsi_host_get_next(host)) host = scsi_host_get_next(host))
if (host->hostt == &driver_template) if (host->hostt == &driver_template)
for (dev = host->host_queue; dev; dev = dev->next) { list_for_each_entry (dev, &host->my_devices, siblings) {
u_long arg[2], id; u_long arg[2], id;
kernel_scsi_ioctl(dev, SCSI_IOCTL_GET_IDLUN, arg); kernel_scsi_ioctl(dev, SCSI_IOCTL_GET_IDLUN, arg);
id = (arg[0]&0x0f) + ((arg[0]>>4)&0xf0) + id = (arg[0]&0x0f) + ((arg[0]>>4)&0xf0) +
......
...@@ -1779,7 +1779,7 @@ static void nsp_cs_config(dev_link_t *link) ...@@ -1779,7 +1779,7 @@ static void nsp_cs_config(dev_link_t *link)
for (host = scsi_hostlist; host != NULL; host = host->next) { for (host = scsi_hostlist; host != NULL; host = host->next) {
#endif #endif
if (host->hostt == &driver_template) { if (host->hostt == &driver_template) {
for (dev = host->host_queue; dev != NULL; dev = dev->next) { list_for_each_entry (dev, &host->my_devices, siblings) {
u_long arg[2], id; u_long arg[2], id;
kernel_scsi_ioctl(dev, SCSI_IOCTL_GET_IDLUN, arg); kernel_scsi_ioctl(dev, SCSI_IOCTL_GET_IDLUN, arg);
id = (arg[0]&0x0f) + ((arg[0]>>4)&0xf0) + id = (arg[0]&0x0f) + ((arg[0]>>4)&0xf0) +
......
...@@ -284,7 +284,7 @@ static void qlogic_config(dev_link_t *link) ...@@ -284,7 +284,7 @@ static void qlogic_config(dev_link_t *link)
for (host = scsi_host_get_next(NULL); host; for (host = scsi_host_get_next(NULL); host;
host = scsi_host_get_next(host)) host = scsi_host_get_next(host))
if (host->hostt == &driver_template) if (host->hostt == &driver_template)
for (dev = host->host_queue; dev; dev = dev->next) { list_for_each_entry (dev, &host->my_devices, siblings) {
u_long arg[2], id; u_long arg[2], id;
kernel_scsi_ioctl(dev, SCSI_IOCTL_GET_IDLUN, arg); kernel_scsi_ioctl(dev, SCSI_IOCTL_GET_IDLUN, arg);
id = (arg[0]&0x0f) + ((arg[0]>>4)&0xf0) + id = (arg[0]&0x0f) + ((arg[0]>>4)&0xf0) +
......
...@@ -364,16 +364,8 @@ static int check_all_luns(struct Scsi_Host *shost, struct scsi_device *myself) ...@@ -364,16 +364,8 @@ static int check_all_luns(struct Scsi_Host *shost, struct scsi_device *myself)
{ {
struct scsi_device *sdev; struct scsi_device *sdev;
for (sdev = shost->host_queue; sdev; sdev = sdev->next) { list_for_each_entry(sdev, &myself->same_target_siblings,
/* same_target_siblings) {
* Only look for other devices on the same bus
* with the same target ID.
*/
if (sdev->channel != myself->channel || sdev->id != myself->id)
continue;
if (sdev == myself)
continue;
if (atomic_read(&sdev->device_active)) if (atomic_read(&sdev->device_active))
return 1; return 1;
} }
...@@ -2033,19 +2025,9 @@ int scsi_register_device(struct Scsi_Device_Template *tpnt) ...@@ -2033,19 +2025,9 @@ int scsi_register_device(struct Scsi_Device_Template *tpnt)
driver_register(&tpnt->scsi_driverfs_driver); driver_register(&tpnt->scsi_driverfs_driver);
for (shpnt = scsi_host_get_next(NULL); shpnt; for (shpnt = scsi_host_get_next(NULL); shpnt;
shpnt = scsi_host_get_next(shpnt)) { shpnt = scsi_host_get_next(shpnt))
for (SDpnt = shpnt->host_queue; SDpnt; list_for_each_entry (SDpnt, &shpnt->my_devices, siblings)
SDpnt = SDpnt->next) { (*tpnt->attach) (SDpnt);
if (tpnt->attach)
/*
* XXX check result when the upper level
* attach return values are fixed, and
* stop attaching on failure.
*/
(*tpnt->attach) (SDpnt);
}
}
return 0; return 0;
} }
...@@ -2063,11 +2045,8 @@ int scsi_unregister_device(struct Scsi_Device_Template *tpnt) ...@@ -2063,11 +2045,8 @@ int scsi_unregister_device(struct Scsi_Device_Template *tpnt)
for (shpnt = scsi_host_get_next(NULL); shpnt; for (shpnt = scsi_host_get_next(NULL); shpnt;
shpnt = scsi_host_get_next(shpnt)) { shpnt = scsi_host_get_next(shpnt)) {
for (SDpnt = shpnt->host_queue; SDpnt; list_for_each_entry(SDpnt, &shpnt->my_devices, siblings)
SDpnt = SDpnt->next) { (*tpnt->detach) (SDpnt);
if (tpnt->detach)
(*tpnt->detach) (SDpnt);
}
} }
/* /*
* Extract the template from the linked list. * Extract the template from the linked list.
......
...@@ -201,7 +201,7 @@ static void scsi_eh_prt_fail_stats(Scsi_Cmnd *sc_list, struct Scsi_Host *shost) ...@@ -201,7 +201,7 @@ static void scsi_eh_prt_fail_stats(Scsi_Cmnd *sc_list, struct Scsi_Host *shost)
int devices_failed = 0; int devices_failed = 0;
for (sdev = shost->host_queue; sdev; sdev = sdev->next) { list_for_each_entry(sdev, &shost->my_devices, siblings) {
for (scmd = sc_list; scmd; scmd = scmd->bh_next) { for (scmd = sc_list; scmd; scmd = scmd->bh_next) {
if (scmd->device == sdev) { if (scmd->device == sdev) {
++total_failures; ++total_failures;
...@@ -246,7 +246,8 @@ static void scsi_eh_get_failed(Scsi_Cmnd **sc_list, struct Scsi_Host *shost) ...@@ -246,7 +246,8 @@ static void scsi_eh_get_failed(Scsi_Cmnd **sc_list, struct Scsi_Host *shost)
Scsi_Device *sdev; Scsi_Device *sdev;
Scsi_Cmnd *scmd; Scsi_Cmnd *scmd;
for (found = 0, sdev = shost->host_queue; sdev; sdev = sdev->next) { found = 0;
list_for_each_entry(sdev, &shost->my_devices, siblings) {
for (scmd = sdev->device_queue; scmd; scmd = scmd->next) { for (scmd = sdev->device_queue; scmd; scmd = scmd->next) {
if (scsi_eh_eflags_chk(scmd, SCSI_EH_CMD_ERR)) { if (scsi_eh_eflags_chk(scmd, SCSI_EH_CMD_ERR)) {
scmd->bh_next = *sc_list; scmd->bh_next = *sc_list;
...@@ -961,7 +962,7 @@ static int scsi_eh_bus_device_reset(Scsi_Cmnd *sc_todo, struct Scsi_Host *shost) ...@@ -961,7 +962,7 @@ static int scsi_eh_bus_device_reset(Scsi_Cmnd *sc_todo, struct Scsi_Host *shost)
SCSI_LOG_ERROR_RECOVERY(3, printk("%s: Trying BDR\n", __FUNCTION__)); SCSI_LOG_ERROR_RECOVERY(3, printk("%s: Trying BDR\n", __FUNCTION__));
for (sdev = shost->host_queue; sdev; sdev = sdev->next) { list_for_each_entry(sdev, &shost->my_devices, siblings) {
for (scmd = sc_todo; scmd; scmd = scmd->bh_next) for (scmd = sc_todo; scmd; scmd = scmd->bh_next)
if ((scmd->device == sdev) && if ((scmd->device == sdev) &&
scsi_eh_eflags_chk(scmd, SCSI_EH_CMD_ERR)) scsi_eh_eflags_chk(scmd, SCSI_EH_CMD_ERR))
...@@ -1015,7 +1016,7 @@ static int scsi_try_bus_reset(Scsi_Cmnd *scmd) ...@@ -1015,7 +1016,7 @@ static int scsi_try_bus_reset(Scsi_Cmnd *scmd)
/* /*
* Mark all affected devices to expect a unit attention. * Mark all affected devices to expect a unit attention.
*/ */
for (sdev = scmd->host->host_queue; sdev; sdev = sdev->next) list_for_each_entry(sdev, &scmd->host->my_devices, siblings)
if (scmd->channel == sdev->channel) { if (scmd->channel == sdev->channel) {
sdev->was_reset = 1; sdev->was_reset = 1;
sdev->expecting_cc_ua = 1; sdev->expecting_cc_ua = 1;
...@@ -1051,7 +1052,7 @@ static int scsi_try_host_reset(Scsi_Cmnd *scmd) ...@@ -1051,7 +1052,7 @@ static int scsi_try_host_reset(Scsi_Cmnd *scmd)
/* /*
* Mark all affected devices to expect a unit attention. * Mark all affected devices to expect a unit attention.
*/ */
for (sdev = scmd->host->host_queue; sdev; sdev = sdev->next) list_for_each_entry(sdev, &scmd->host->my_devices, siblings)
if (scmd->channel == sdev->channel) { if (scmd->channel == sdev->channel) {
sdev->was_reset = 1; sdev->was_reset = 1;
sdev->expecting_cc_ua = 1; sdev->expecting_cc_ua = 1;
...@@ -1457,7 +1458,7 @@ static void scsi_restart_operations(struct Scsi_Host *shost) ...@@ -1457,7 +1458,7 @@ static void scsi_restart_operations(struct Scsi_Host *shost)
* onto the head of the SCSI request queue for the device. There * onto the head of the SCSI request queue for the device. There
* is no point trying to lock the door of an off-line device. * is no point trying to lock the door of an off-line device.
*/ */
for (sdev = shost->host_queue; sdev; sdev = sdev->next) list_for_each_entry(sdev, &shost->my_devices, siblings)
if (sdev->online && sdev->locked) if (sdev->online && sdev->locked)
scsi_eh_lock_door(sdev); scsi_eh_lock_door(sdev);
...@@ -1478,7 +1479,7 @@ static void scsi_restart_operations(struct Scsi_Host *shost) ...@@ -1478,7 +1479,7 @@ static void scsi_restart_operations(struct Scsi_Host *shost)
* requests are started. * requests are started.
*/ */
spin_lock_irqsave(shost->host_lock, flags); spin_lock_irqsave(shost->host_lock, flags);
for (sdev = shost->host_queue; sdev; sdev = sdev->next) { list_for_each_entry(sdev, &shost->my_devices, siblings) {
if ((shost->can_queue > 0 && if ((shost->can_queue > 0 &&
(shost->host_busy >= shost->can_queue)) (shost->host_busy >= shost->can_queue))
|| (shost->host_blocked) || (shost->host_blocked)
......
...@@ -242,7 +242,7 @@ void scsi_queue_next_request(request_queue_t * q, Scsi_Cmnd * SCpnt) ...@@ -242,7 +242,7 @@ void scsi_queue_next_request(request_queue_t * q, Scsi_Cmnd * SCpnt)
* use function pointers to pick the right one. * use function pointers to pick the right one.
*/ */
if (SDpnt->single_lun && blk_queue_empty(q) && SDpnt->device_busy ==0) { if (SDpnt->single_lun && blk_queue_empty(q) && SDpnt->device_busy ==0) {
for (SDpnt = SHpnt->host_queue; SDpnt; SDpnt = SDpnt->next) { list_for_each_entry(SDpnt, &SHpnt->my_devices, siblings) {
if (((SHpnt->can_queue > 0) if (((SHpnt->can_queue > 0)
&& (SHpnt->host_busy >= SHpnt->can_queue)) && (SHpnt->host_busy >= SHpnt->can_queue))
|| (SHpnt->host_blocked) || (SHpnt->host_blocked)
...@@ -265,7 +265,7 @@ void scsi_queue_next_request(request_queue_t * q, Scsi_Cmnd * SCpnt) ...@@ -265,7 +265,7 @@ void scsi_queue_next_request(request_queue_t * q, Scsi_Cmnd * SCpnt)
*/ */
all_clear = 1; all_clear = 1;
if (SHpnt->some_device_starved) { if (SHpnt->some_device_starved) {
for (SDpnt = SHpnt->host_queue; SDpnt; SDpnt = SDpnt->next) { list_for_each_entry(SDpnt, &SHpnt->my_devices, siblings) {
if ((SHpnt->can_queue > 0 && (SHpnt->host_busy >= SHpnt->can_queue)) if ((SHpnt->can_queue > 0 && (SHpnt->host_busy >= SHpnt->can_queue))
|| (SHpnt->host_blocked) || (SHpnt->host_blocked)
|| (SHpnt->host_self_blocked)) { || (SHpnt->host_self_blocked)) {
...@@ -1050,7 +1050,7 @@ void scsi_unblock_requests(struct Scsi_Host * SHpnt) ...@@ -1050,7 +1050,7 @@ void scsi_unblock_requests(struct Scsi_Host * SHpnt)
SHpnt->host_self_blocked = FALSE; SHpnt->host_self_blocked = FALSE;
/* Now that we are unblocked, try to start the queues. */ /* Now that we are unblocked, try to start the queues. */
for (SDloop = SHpnt->host_queue; SDloop; SDloop = SDloop->next) list_for_each_entry(SDloop, &SHpnt->my_devices, siblings)
scsi_queue_next_request(&SDloop->request_queue, NULL); scsi_queue_next_request(&SDloop->request_queue, NULL);
} }
...@@ -1078,7 +1078,7 @@ void scsi_unblock_requests(struct Scsi_Host * SHpnt) ...@@ -1078,7 +1078,7 @@ void scsi_unblock_requests(struct Scsi_Host * SHpnt)
void scsi_report_bus_reset(struct Scsi_Host * SHpnt, int channel) void scsi_report_bus_reset(struct Scsi_Host * SHpnt, int channel)
{ {
Scsi_Device *SDloop; Scsi_Device *SDloop;
for (SDloop = SHpnt->host_queue; SDloop; SDloop = SDloop->next) { list_for_each_entry(SDloop, &SHpnt->my_devices, siblings) {
if (channel == SDloop->channel) { if (channel == SDloop->channel) {
SDloop->was_reset = 1; SDloop->was_reset = 1;
SDloop->expecting_cc_ua = 1; SDloop->expecting_cc_ua = 1;
......
...@@ -281,7 +281,7 @@ static int scsi_proc_info(char *buffer, char **start, off_t offset, int length) ...@@ -281,7 +281,7 @@ static int scsi_proc_info(char *buffer, char **start, off_t offset, int length)
*/ */
for (shost = scsi_host_get_next(NULL); shost; for (shost = scsi_host_get_next(NULL); shost;
shost = scsi_host_get_next(shost)) { shost = scsi_host_get_next(shost)) {
if (shost->host_queue != NULL) { if (!list_empty(&shost->my_devices)) {
break; break;
} }
} }
...@@ -291,7 +291,7 @@ static int scsi_proc_info(char *buffer, char **start, off_t offset, int length) ...@@ -291,7 +291,7 @@ static int scsi_proc_info(char *buffer, char **start, off_t offset, int length)
pos = begin + len; pos = begin + len;
for (shost = scsi_host_get_next(NULL); shost; for (shost = scsi_host_get_next(NULL); shost;
shost = scsi_host_get_next(shost)) { shost = scsi_host_get_next(shost)) {
for (sdev = shost->host_queue; sdev; sdev = sdev->next) { list_for_each_entry(sdev, &shost->my_devices, siblings) {
proc_print_scsidevice(sdev, buffer, &size, len); proc_print_scsidevice(sdev, buffer, &size, len);
len += size; len += size;
pos = begin + len; pos = begin + len;
...@@ -359,7 +359,7 @@ static void scsi_dump_status(int level) ...@@ -359,7 +359,7 @@ static void scsi_dump_status(int level)
shpnt = scsi_host_get_next(shpnt)) { shpnt = scsi_host_get_next(shpnt)) {
printk(KERN_INFO "h:c:t:l (dev sect nsect cnumsec sg) " printk(KERN_INFO "h:c:t:l (dev sect nsect cnumsec sg) "
"(ret all flg) (to/cmd to ito) cmd snse result\n"); "(ret all flg) (to/cmd to ito) cmd snse result\n");
for (SDpnt = shpnt->host_queue; SDpnt; SDpnt = SDpnt->next) { list_for_each_entry(SDpnt, &shpnt->my_devices, siblings) {
for (SCpnt = SDpnt->device_queue; SCpnt; SCpnt = SCpnt->next) { for (SCpnt = SDpnt->device_queue; SCpnt; SCpnt = SCpnt->next) {
/* (0) h:c:t:l (dev sect nsect cnumsec sg) (ret all flg) (to/cmd to ito) cmd snse result %d %x */ /* (0) h:c:t:l (dev sect nsect cnumsec sg) (ret all flg) (to/cmd to ito) cmd snse result %d %x */
printk(KERN_INFO "(%3d) %2d:%1d:%2d:%2d (%6s %4llu %4ld %4ld %4x %1d) (%1d %1d 0x%2x) (%4d %4d %4d) 0x%2.2x 0x%2.2x 0x%8.8x\n", printk(KERN_INFO "(%3d) %2d:%1d:%2d:%2d (%6s %4llu %4ld %4ld %4x %1d) (%1d %1d 0x%2x) (%4d %4d %4d) 0x%2.2x 0x%2.2x 0x%8.8x\n",
......
...@@ -508,15 +508,9 @@ struct scsi_device *scsi_alloc_sdev(struct Scsi_Host *shost, uint channel, ...@@ -508,15 +508,9 @@ struct scsi_device *scsi_alloc_sdev(struct Scsi_Host *shost, uint channel,
init_waitqueue_head(&sdev->scpnt_wait); init_waitqueue_head(&sdev->scpnt_wait);
/* /*
* Add it to the end of the shost->host_queue list. * If there are any same target siblings, add this to the
* sibling list
*/ */
if (shost->host_queue != NULL) {
sdev->prev = shost->host_queue;
while (sdev->prev->next != NULL)
sdev->prev = sdev->prev->next;
sdev->prev->next = sdev;
} else
shost->host_queue = sdev;
list_for_each_entry(device, &shost->my_devices, siblings) { list_for_each_entry(device, &shost->my_devices, siblings) {
if(device->id == sdev->id && if(device->id == sdev->id &&
device->channel == sdev->channel) { device->channel == sdev->channel) {
...@@ -525,6 +519,9 @@ struct scsi_device *scsi_alloc_sdev(struct Scsi_Host *shost, uint channel, ...@@ -525,6 +519,9 @@ struct scsi_device *scsi_alloc_sdev(struct Scsi_Host *shost, uint channel,
break; break;
} }
} }
/*
* Add it to the end of the shost->my_devices list.
*/
list_add_tail(&sdev->siblings, &shost->my_devices); list_add_tail(&sdev->siblings, &shost->my_devices);
} }
return (sdev); return (sdev);
...@@ -540,16 +537,11 @@ struct scsi_device *scsi_alloc_sdev(struct Scsi_Host *shost, uint channel, ...@@ -540,16 +537,11 @@ struct scsi_device *scsi_alloc_sdev(struct Scsi_Host *shost, uint channel,
**/ **/
void scsi_free_sdev(struct scsi_device *sdev) void scsi_free_sdev(struct scsi_device *sdev)
{ {
if (sdev->prev != NULL)
sdev->prev->next = sdev->next;
else
sdev->host->host_queue = sdev->next;
if (sdev->next != NULL)
sdev->next->prev = sdev->prev;
list_del(&sdev->siblings); list_del(&sdev->siblings);
list_del(&sdev->same_target_siblings); list_del(&sdev->same_target_siblings);
blk_cleanup_queue(&sdev->request_queue); blk_cleanup_queue(&sdev->request_queue);
scsi_release_commandblocks(sdev);
if (sdev->host->hostt->slave_destroy) if (sdev->host->hostt->slave_destroy)
sdev->host->hostt->slave_destroy(sdev); sdev->host->hostt->slave_destroy(sdev);
if (sdev->inquiry != NULL) if (sdev->inquiry != NULL)
...@@ -1101,32 +1093,6 @@ static void scsi_load_identifier(Scsi_Device *sdev, Scsi_Request *sreq) ...@@ -1101,32 +1093,6 @@ static void scsi_load_identifier(Scsi_Device *sdev, Scsi_Request *sreq)
return; return;
} }
/**
* scsi_find_scsi_level - return the scsi_level of a matching target
*
* Description:
* Return the scsi_level of any Scsi_Device matching @channel, @id,
* and @shost.
* Notes:
* Needs to issue an INQUIRY to LUN 0 if no Scsi_Device matches, and
* if the INQUIRY can't be sent return a failure.
**/
static int scsi_find_scsi_level(unsigned int channel, unsigned int id,
struct Scsi_Host *shost)
{
int res = SCSI_2;
Scsi_Device *sdev;
for (sdev = shost->host_queue; sdev; sdev = sdev->next)
if ((id == sdev->id) && (channel == sdev->channel))
return (int) sdev->scsi_level;
/*
* FIXME No matching target id is configured, this needs to get
* the INQUIRY for LUN 0, and use it to determine the scsi_level.
*/
return res;
}
/** /**
* scsi_probe_lun - probe a single LUN using a SCSI INQUIRY * scsi_probe_lun - probe a single LUN using a SCSI INQUIRY
* @sreq: used to send the INQUIRY * @sreq: used to send the INQUIRY
...@@ -1927,7 +1893,13 @@ int scsi_add_single_device(uint host, uint channel, uint id, uint lun) ...@@ -1927,7 +1893,13 @@ int scsi_add_single_device(uint host, uint channel, uint id, uint lun)
if (!sdevscan) if (!sdevscan)
goto out; goto out;
sdevscan->scsi_level = scsi_find_scsi_level(channel, id, shost); if(!list_empty(&sdevscan->same_target_siblings)) {
sdev = list_entry(&sdevscan->same_target_siblings, Scsi_Device,
same_target_siblings);
sdevscan->scsi_level = sdev->scsi_level;
sdev = NULL;
} else
sdevscan->scsi_level = SCSI_2;
error = scsi_probe_and_add_lun(sdevscan, &sdev, NULL); error = scsi_probe_and_add_lun(sdevscan, &sdev, NULL);
scsi_free_sdev(sdevscan); scsi_free_sdev(sdevscan);
......
...@@ -1434,23 +1434,21 @@ static int wd7000_proc_info(char *buffer, char **start, off_t offset, int length ...@@ -1434,23 +1434,21 @@ static int wd7000_proc_info(char *buffer, char **start, off_t offset, int length
/* /*
* Display driver information for each device attached to the board. * Display driver information for each device attached to the board.
*/ */
scd = host->host_queue; SPRINTF("\nAttached devices: %s\n", !list_empty(&host->my_devices) ?
"" : "none");
SPRINTF("\nAttached devices: %s\n", scd ? "" : "none"); list_for_each_entry (scd, &host->my_devices, siblings) {
SPRINTF(" [Channel: %02d, Id: %02d, Lun: %02d] ", scd->channel, scd->id, scd->lun);
SPRINTF("%s ", (scd->type < MAX_SCSI_DEVICE_CODE) ? scsi_device_types[(short) scd->type] : "Unknown device");
for (; scd; scd = scd->next) for (i = 0; (i < 8) && (scd->vendor[i] >= 0x20); i++)
if (scd->host->host_no == hostno) { SPRINTF("%c", scd->vendor[i]);
SPRINTF(" [Channel: %02d, Id: %02d, Lun: %02d] ", scd->channel, scd->id, scd->lun); SPRINTF(" ");
SPRINTF("%s ", (scd->type < MAX_SCSI_DEVICE_CODE) ? scsi_device_types[(short) scd->type] : "Unknown device");
for (i = 0; (i < 8) && (scd->vendor[i] >= 0x20); i++) for (i = 0; (i < 16) && (scd->model[i] >= 0x20); i++)
SPRINTF("%c", scd->vendor[i]); SPRINTF("%c", scd->model[i]);
SPRINTF(" "); SPRINTF("\n");
}
for (i = 0; (i < 16) && (scd->model[i] >= 0x20); i++)
SPRINTF("%c", scd->model[i]);
SPRINTF("\n");
}
SPRINTF("\n"); SPRINTF("\n");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment