diff options
46 files changed, 317 insertions, 338 deletions
diff --git a/drivers/block/cciss_scsi.c b/drivers/block/cciss_scsi.c index 8ad5d01e4d42..6951231d4ed5 100644 --- a/drivers/block/cciss_scsi.c +++ b/drivers/block/cciss_scsi.c @@ -712,7 +712,8 @@ cciss_scsi_detect(int ctlr) sh->hostdata[0] = (unsigned long) hba[ctlr]; sh->irq = hba[ctlr]->intr; sh->unique_id = sh->irq; - scsi_add_host(sh, &hba[ctlr]->pdev->dev); + scsi_add_host(sh, &hba[ctlr]->pdev->dev); /* XXX handle failure */ + scsi_scan_host(sh); return 1; } diff --git a/drivers/block/elevator.c b/drivers/block/elevator.c index a9bbb2f3d15a..85630fbb37ad 100644 --- a/drivers/block/elevator.c +++ b/drivers/block/elevator.c @@ -213,6 +213,18 @@ void elv_merge_requests(request_queue_t *q, struct request *rq, e->elevator_merge_req_fn(q, rq, next); } +void elv_requeue_request(request_queue_t *q, struct request *rq) +{ + /* + * if iosched has an explicit requeue hook, then use that. otherwise + * just put the request at the front of the queue + */ + if (q->elevator.elevator_requeue_req_fn) + q->elevator.elevator_requeue_req_fn(q, rq); + else + __elv_add_request(q, rq, 0, 0); +} + void __elv_add_request(request_queue_t *q, struct request *rq, int at_end, int plug) { @@ -416,6 +428,7 @@ EXPORT_SYMBOL(elevator_noop); EXPORT_SYMBOL(elv_add_request); EXPORT_SYMBOL(__elv_add_request); +EXPORT_SYMBOL(elv_requeue_request); EXPORT_SYMBOL(elv_next_request); EXPORT_SYMBOL(elv_remove_request); EXPORT_SYMBOL(elv_queue_empty); diff --git a/drivers/block/ll_rw_blk.c b/drivers/block/ll_rw_blk.c index 180ac3e95a66..f9678d95a043 100644 --- a/drivers/block/ll_rw_blk.c +++ b/drivers/block/ll_rw_blk.c @@ -1494,6 +1494,23 @@ struct request *blk_get_request(request_queue_t *q, int rw, int gfp_mask) return rq; } +/** + * blk_requeue_request - put a request back on queue + * @q: request queue where request should be inserted + * @rq: request to be inserted + * + * Description: + * Drivers often keep queueing requests until the hardware cannot accept + * more, when that condition happens we need to put the request back + * on the queue. Must be called with queue lock held. + */ +void blk_requeue_request(request_queue_t *q, struct request *rq) +{ + if (blk_rq_tagged(rq)) + blk_queue_end_tag(q, rq); + + elv_requeue_request(q, rq); +} /** * blk_insert_request - insert a special request in to a request queue @@ -2730,6 +2747,7 @@ EXPORT_SYMBOL(blk_hw_contig_segment); EXPORT_SYMBOL(blk_get_request); EXPORT_SYMBOL(blk_put_request); EXPORT_SYMBOL(blk_insert_request); +EXPORT_SYMBOL(blk_requeue_request); EXPORT_SYMBOL(blk_queue_prep_rq); EXPORT_SYMBOL(blk_queue_merge_bvec); diff --git a/drivers/scsi/53c700.c b/drivers/scsi/53c700.c index 3e70fb999f56..c2fce462e847 100644 --- a/drivers/scsi/53c700.c +++ b/drivers/scsi/53c700.c @@ -172,7 +172,7 @@ STATIC void NCR_700_chip_reset(struct Scsi_Host *host); STATIC int NCR_700_slave_configure(Scsi_Device *SDpnt); STATIC void NCR_700_slave_destroy(Scsi_Device *SDpnt); -static struct device_attribute **NCR_700_dev_attrs = NULL; +STATIC struct device_attribute *NCR_700_dev_attrs[]; static char *NCR_700_phase[] = { "", @@ -2027,25 +2027,12 @@ static struct device_attribute NCR_700_active_tags_attr = { .show = NCR_700_show_active_tags, }; -STATIC int __init -NCR_700_init(void) -{ - scsi_sysfs_modify_sdev_attribute(&NCR_700_dev_attrs, - &NCR_700_queue_depth_attr); - scsi_sysfs_modify_sdev_attribute(&NCR_700_dev_attrs, - &NCR_700_active_tags_attr); - return 0; -} - -/* NULL exit routine to keep modutils happy */ -STATIC void __exit -NCR_700_exit(void) -{ -} +STATIC struct device_attribute *NCR_700_dev_attrs[] = { + &NCR_700_queue_depth_attr, + &NCR_700_active_tags_attr, + NULL, +}; EXPORT_SYMBOL(NCR_700_detect); EXPORT_SYMBOL(NCR_700_release); EXPORT_SYMBOL(NCR_700_intr); - -module_init(NCR_700_init); -module_exit(NCR_700_exit); diff --git a/drivers/scsi/NCR_D700.c b/drivers/scsi/NCR_D700.c index f1eb7aaf22e4..7bff5570b6a0 100644 --- a/drivers/scsi/NCR_D700.c +++ b/drivers/scsi/NCR_D700.c @@ -218,7 +218,8 @@ NCR_D700_probe_one(struct NCR_D700_private *p, int siop, goto irq_failed; } - scsi_add_host(host, p->dev); + scsi_add_host(host, p->dev); /* XXX handle failure */ + scsi_scan_host(host); p->hosts[siop] = host; hostdata->dev = p->dev; @@ -387,7 +388,6 @@ static int __init NCR_D700_init(void) static void __exit NCR_D700_exit(void) { mca_unregister_driver(&NCR_D700_driver); - scsi_sysfs_release_attributes(&NCR_D700_driver_template); } module_init(NCR_D700_init); diff --git a/drivers/scsi/NCR_Q720.c b/drivers/scsi/NCR_Q720.c index c45c353cc9ad..b7d3b5264223 100644 --- a/drivers/scsi/NCR_Q720.c +++ b/drivers/scsi/NCR_Q720.c @@ -85,6 +85,7 @@ NCR_Q720_probe_one(struct NCR_Q720_private *p, int siop, __u8 scsr1 = readb(vaddr + NCR_Q720_SCSR_OFFSET + 1); __u8 differential = readb(vaddr + NCR_Q720_SCSR_OFFSET) & 0x20; __u8 version; + int error; scsi_id = scsr1 >> 4; /* enable burst length 16 (FIXME: should allow this) */ @@ -120,9 +121,12 @@ NCR_Q720_probe_one(struct NCR_Q720_private *p, int siop, scsr1 &= ~0x01; writeb(scsr1, vaddr + NCR_Q720_SCSR_OFFSET + 1); - scsi_add_host(p->hosts[siop], p->dev); - - return 0; + error = scsi_add_host(p->hosts[siop], p->dev); + if (error) + ncr53c8xx_release(p->hosts[siop]); + else + scsi_scan_host(p->hosts[siop]); + return error; fail: return -ENODEV; @@ -347,7 +351,6 @@ static void __exit NCR_Q720_exit(void) { mca_unregister_driver(&NCR_Q720_driver); - //scsi_sysfs_release_attributes(&NCR_Q720_driver_template); } module_init(NCR_Q720_init); diff --git a/drivers/scsi/aha152x.c b/drivers/scsi/aha152x.c index ee380d8b0ba6..5618e688d6c3 100644 --- a/drivers/scsi/aha152x.c +++ b/drivers/scsi/aha152x.c @@ -939,7 +939,8 @@ static irqreturn_t swintr(int irqno, void *dev_id, struct pt_regs *regs) struct Scsi_Host *shpnt = lookup_irq(irqno); if (!shpnt) { - printk(KERN_ERR "aha152x%d: catched software interrupt %d for unknown controller.\n", HOSTNO, irqno); + /* no point using HOSTNO here! */ + printk(KERN_ERR "aha152x: catched software interrupt %d for unknown controller.\n", irqno); return IRQ_NONE; } @@ -1047,6 +1048,10 @@ struct Scsi_Host *aha152x_probe_one(struct aha152x_setup *setup) printk(KERN_INFO "aha152x%d: trying software interrupt, ", shost->host_no); + + /* need to have host registered before triggering any interrupt */ + aha152x_host[registered_count] = shost; + mb(); SETPORT(DMACNTRL0, SWINT|INTEN); mdelay(1000); free_irq(shost->irq, shost); @@ -1062,7 +1067,7 @@ struct Scsi_Host *aha152x_probe_one(struct aha152x_setup *setup) printk(KERN_ERR "aha152x%d: IRQ %d possibly wrong. " "Please verify.\n", shost->host_no, shost->irq); - goto out_release_region; + goto out_unregister_host; } printk("ok.\n"); @@ -1075,12 +1080,12 @@ struct Scsi_Host *aha152x_probe_one(struct aha152x_setup *setup) "aha152x", shost) < 0) { printk(KERN_ERR "aha152x%d: failed to reassign interrupt.\n", shost->host_no); - goto out_release_region; + goto out_unregister_host; } - - aha152x_host[registered_count] = shost; return shost; /* the pcmcia stub needs the return value; */ +out_unregister_host: + aha152x_host[registered_count] = NULL; out_release_region: release_region(shost->io_port, IO_RANGE); out_unregister: diff --git a/drivers/scsi/aha1740.c b/drivers/scsi/aha1740.c index fe22bc364faf..9b1e7cace348 100644 --- a/drivers/scsi/aha1740.c +++ b/drivers/scsi/aha1740.c @@ -375,7 +375,7 @@ static int aha1740_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *)) #endif /* locate an available ecb */ - spin_lock_irqsave(&SCpnt->device->host->host_lock, flags); + spin_lock_irqsave(SCpnt->device->host->host_lock, flags); ecbno = host->last_ecb_used + 1; /* An optimization */ if (ecbno >= AHA1740_ECBS) ecbno = 0; @@ -394,7 +394,7 @@ static int aha1740_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *)) doubles as reserved flag */ host->last_ecb_used = ecbno; - spin_unlock_irqrestore(&SCpnt->device->host->host_lock, flags); + spin_unlock_irqrestore(SCpnt->device->host->host_lock, flags); #ifdef DEBUG printk("Sending command (%d %x)...", ecbno, done); @@ -491,7 +491,7 @@ static int aha1740_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *)) unsigned int base = SCpnt->device->host->io_port; DEB(printk("aha1740[%d] critical section\n",ecbno)); - spin_lock_irqsave(&SCpnt->device->host->host_lock, flags); + spin_lock_irqsave(SCpnt->device->host->host_lock, flags); for (loopcnt = 0; ; loopcnt++) { if (inb(G2STAT(base)) & G2STAT_MBXOUT) break; if (loopcnt == LOOPCNT_WARN) { @@ -511,7 +511,7 @@ static int aha1740_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *)) panic("aha1740.c: attn wait failed!\n"); } outb(ATTN_START | (target & 7), ATTN(base)); /* Start it up */ - spin_unlock_irqrestore(&SCpnt->device->host->host_lock, flags); + spin_unlock_irqrestore(SCpnt->device->host->host_lock, flags); DEB(printk("aha1740[%d] request queued.\n",ecbno)); } else printk(KERN_ALERT "aha1740_queuecommand: done can't be NULL\n"); @@ -594,7 +594,7 @@ static int aha1740_probe (struct device *dev) if (!request_region(slotbase, SLOTSIZE, "aha1740")) /* See if in use */ return -EBUSY; if (!aha1740_test_port(slotbase)) - goto err_release; + goto err_release_region; aha1740_getconfig(slotbase,&irq_level,&translation); if ((inb(G2STAT(slotbase)) & (G2STAT_MBXOUT|G2STAT_BUSY)) != G2STAT_MBXOUT) { @@ -609,7 +609,7 @@ static int aha1740_probe (struct device *dev) shpnt = scsi_host_alloc(&aha1740_template, sizeof(struct aha1740_hostdata)); if(shpnt == NULL) - goto err_release; + goto err_release_region; shpnt->base = 0; shpnt->io_port = slotbase; @@ -625,21 +625,27 @@ static int aha1740_probe (struct device *dev) if (!host->ecb_dma_addr) { printk (KERN_ERR "aha1740_probe: Couldn't map ECB, giving up\n"); scsi_unregister (shpnt); - goto err_release; + goto err_host_put; } DEB(printk("aha1740_probe: enable interrupt channel %d\n",irq_level)); if (request_irq(irq_level,aha1740_intr_handle,0,"aha1740",shpnt)) { printk(KERN_ERR "aha1740_probe: Unable to allocate IRQ %d.\n", irq_level); - goto err_release; + goto err_unmap; } eisa_set_drvdata (edev, shpnt); - scsi_add_host (shpnt, dev); + scsi_add_host (shpnt, dev); /* XXX handle failure */ + scsi_scan_host (shpnt); return 0; - err_release: + err_unmap: + dma_unmap_single (&edev->dev, host->ecb_dma_addr, + sizeof (host->ecb), DMA_BIDIRECTIONAL); + err_host_put: + scsi_host_put (shpnt); + err_release_region: release_region(slotbase, SLOTSIZE); return -ENODEV; diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.c b/drivers/scsi/aic7xxx/aic79xx_osm.c index c50c2bb46973..1b87b2aac104 100644 --- a/drivers/scsi/aic7xxx/aic79xx_osm.c +++ b/drivers/scsi/aic7xxx/aic79xx_osm.c @@ -2173,7 +2173,8 @@ ahd_linux_register_host(struct ahd_softc *ahd, Scsi_Host_Template *template) ahd_unlock(ahd, &s); #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) - scsi_add_host(host, &ahd->dev_softc->dev); + scsi_add_host(host, &ahd->dev_softc->dev); /* XXX handle failure */ + scsi_scan_host(host); #endif return (0); } diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.c b/drivers/scsi/aic7xxx/aic7xxx_osm.c index a2ec0a94f44c..8c1e4086a808 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_osm.c +++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c @@ -1811,7 +1811,8 @@ ahc_linux_register_host(struct ahc_softc *ahc, Scsi_Host_Template *template) ahc_unlock(ahc, &s); #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) - scsi_add_host(host, (ahc->dev_softc ? &ahc->dev_softc->dev : NULL)); + scsi_add_host(host, (ahc->dev_softc ? &ahc->dev_softc->dev : NULL)); /* XXX handle failure */ + scsi_scan_host(host); #endif return (0); } diff --git a/drivers/scsi/arm/acornscsi.c b/drivers/scsi/arm/acornscsi.c index 7ac9e317ec51..a0452a6c6122 100644 --- a/drivers/scsi/arm/acornscsi.c +++ b/drivers/scsi/arm/acornscsi.c @@ -3043,9 +3043,13 @@ acornscsi_probe(struct expansion_card *ec, const struct ecard_id *id) acornscsi_resetcard(ashost); ret = scsi_add_host(host, &ec->dev); - if (ret == 0) - goto out; + if (ret) + goto err_7; + + scsi_scan_host(host); + goto out; + err_7: free_irq(host->irq, ashost); err_6: release_region(host->io_port, 2048); diff --git a/drivers/scsi/arm/cumana_1.c b/drivers/scsi/arm/cumana_1.c index 35b1488ce2a6..aa75d505697f 100644 --- a/drivers/scsi/arm/cumana_1.c +++ b/drivers/scsi/arm/cumana_1.c @@ -297,9 +297,13 @@ cumanascsi1_probe(struct expansion_card *ec, const struct ecard_id *id) printk("\n"); ret = scsi_add_host(host, &ec->dev); - if (ret == 0) - goto out; + if (ret) + goto out_free_irq; + + scsi_scan_host(host); + goto out; + out_free_irq: free_irq(host->irq, host); out_release: release_region(host->io_port, host->n_io_port); diff --git a/drivers/scsi/arm/ecoscsi.c b/drivers/scsi/arm/ecoscsi.c index ec1571c94539..7f27e54258b8 100644 --- a/drivers/scsi/arm/ecoscsi.c +++ b/drivers/scsi/arm/ecoscsi.c @@ -205,7 +205,8 @@ static int __init ecoscsi_init(void) NCR5380_print_options(host); printk("\n"); - scsi_add_host(host, NULL); + scsi_add_host(host, NULL); /* XXX handle failure */ + scsi_scan_host(host); return 0; release_reg: diff --git a/drivers/scsi/arm/fas216.c b/drivers/scsi/arm/fas216.c index 11a733dea1c8..2648c6ee5b37 100644 --- a/drivers/scsi/arm/fas216.c +++ b/drivers/scsi/arm/fas216.c @@ -2861,6 +2861,8 @@ int fas216_add(struct Scsi_Host *host, struct device *dev) ret = scsi_add_host(host, dev); if (ret) fas216_writeb(info, REG_CMD, CMD_RESETCHIP); + else + scsi_scan_host(host); return ret; } diff --git a/drivers/scsi/arm/oak.c b/drivers/scsi/arm/oak.c index 34a54329d216..ccca39b6943d 100644 --- a/drivers/scsi/arm/oak.c +++ b/drivers/scsi/arm/oak.c @@ -158,9 +158,13 @@ oakscsi_probe(struct expansion_card *ec, const struct ecard_id *id) printk("\n"); ret = scsi_add_host(host, &ec->dev); - if (ret == 0) - goto out; + if (ret) + goto out_release; + + scsi_scan_host(host); + goto out; + out_release: release_region(host->io_port, host->n_io_port); unreg: scsi_host_put(host); diff --git a/drivers/scsi/dc395x.c b/drivers/scsi/dc395x.c index 65c9467477f9..ecf0333f92d4 100644 --- a/drivers/scsi/dc395x.c +++ b/drivers/scsi/dc395x.c @@ -6214,7 +6214,8 @@ int __devinit dc395x_init_one(struct pci_dev *pdev, pci_set_drvdata(pdev, scsi_host); /* get the scsi mid level to scan for new devices on the bus */ - scsi_add_host(scsi_host, &pdev->dev); + scsi_add_host(scsi_host, &pdev->dev); /* XXX handle failure */ + scsi_scan_host(scsi_host); return 0; } diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c index 755f7b837f04..f4f69bf1e148 100644 --- a/drivers/scsi/hosts.c +++ b/drivers/scsi/hosts.c @@ -81,19 +81,15 @@ int scsi_add_host(struct Scsi_Host *shost, struct device *dev) printk(KERN_INFO "scsi%d : %s\n", shost->host_no, sht->info ? sht->info(shost) : sht->name); - error = scsi_sysfs_add_host(shost, dev); - if (!shost->can_queue) { printk(KERN_ERR "%s: can_queue = 0 no longer supported\n", sht->name); error = -EINVAL; } - if (!error) { + error = scsi_sysfs_add_host(shost, dev); + if (!error) scsi_proc_host_add(shost); - scsi_scan_host(shost); - } - return error; } @@ -151,12 +147,6 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize) dump_stack(); } - /* if its not set in the template, use the default */ - if (!sht->shost_attrs) - sht->shost_attrs = scsi_sysfs_shost_attrs; - if (!sht->sdev_attrs) - sht->sdev_attrs = scsi_sysfs_sdev_attrs; - shost = kmalloc(sizeof(struct Scsi_Host) + privsize, gfp_mask); if (!shost) return NULL; @@ -283,8 +273,8 @@ struct Scsi_Host *scsi_host_lookup(unsigned short hostnum) **/ void scsi_host_get(struct Scsi_Host *shost) { - get_device(&shost->host_gendev); - class_device_get(&shost->class_dev); + get_device(&shost->shost_gendev); + class_device_get(&shost->shost_classdev); } /** @@ -293,6 +283,6 @@ void scsi_host_get(struct Scsi_Host *shost) **/ void scsi_host_put(struct Scsi_Host *shost) { - class_device_put(&shost->class_dev); - put_device(&shost->host_gendev); + class_device_put(&shost->shost_classdev); + put_device(&shost->shost_gendev); } diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c index cfd1e581072c..84238c4de22a 100644 --- a/drivers/scsi/ide-scsi.c +++ b/drivers/scsi/ide-scsi.c @@ -978,8 +978,10 @@ static int idescsi_attach(ide_drive_t *drive) idescsi_setup (drive, idescsi); drive->disk->fops = &idescsi_ops; err = scsi_add_host(host, &idescsi_primary); - if (!err) + if (!err) { + scsi_scan_host(host); return 0; + } /* fall through on error */ ide_unregister_subdriver(drive); } diff --git a/drivers/scsi/ips.h b/drivers/scsi/ips.h index 921d73f38f9d..0ad7adce9acf 100644 --- a/drivers/scsi/ips.h +++ b/drivers/scsi/ips.h @@ -111,7 +111,7 @@ #else #define IPS_REGISTER_HOSTS(SHT) (!ips_detect(SHT)) #define IPS_UNREGISTER_HOSTS(SHT) - #define IPS_ADD_HOST(shost,device) scsi_add_host(shost,device) + #define IPS_ADD_HOST(shost,device) do { scsi_add_host(shost,device); scsi_scan_host(shost); } while (0) #define IPS_REMOVE_HOST(shost) scsi_remove_host(shost) #define IPS_SCSI_SET_DEVICE(sh,ha) scsi_set_device(sh, &(ha)->pcidev->dev) #define IPS_PRINTK(level, pcidev, format, arg...) \ diff --git a/drivers/scsi/lasi700.c b/drivers/scsi/lasi700.c index b5c4b51b3cf3..25cff061f4a1 100644 --- a/drivers/scsi/lasi700.c +++ b/drivers/scsi/lasi700.c @@ -128,7 +128,8 @@ lasi700_driver_callback(struct parisc_device *dev) } dev_set_drvdata(&dev->dev, host); - scsi_add_host(host, &dev->dev); + scsi_add_host(host, &dev->dev); /* XXX handle failure */ + scsi_scan_host(host); return 0; @@ -165,7 +166,6 @@ static void __exit lasi700_exit(void) { unregister_parisc_driver(&lasi700_driver); - scsi_sysfs_release_attributes(&lasi700_template); } module_init(lasi700_init); diff --git a/drivers/scsi/nsp32.c b/drivers/scsi/nsp32.c index 963e409dcfd7..d9567d5b75f3 100644 --- a/drivers/scsi/nsp32.c +++ b/drivers/scsi/nsp32.c @@ -1820,7 +1820,8 @@ static int nsp32_detect(struct pci_dev *pdev) goto free_irq; } - scsi_add_host(host, &pdev->dev); + scsi_add_host(host, &pdev->dev); /* XXX handle failure */ + scsi_scan_host(host); pci_set_drvdata(pdev, host); return 0; diff --git a/drivers/scsi/pcmcia/aha152x_stub.c b/drivers/scsi/pcmcia/aha152x_stub.c index 41f420335072..af999e9509b6 100644 --- a/drivers/scsi/pcmcia/aha152x_stub.c +++ b/drivers/scsi/pcmcia/aha152x_stub.c @@ -278,7 +278,8 @@ static void aha152x_config_cs(dev_link_t *link) goto cs_failed; } - scsi_add_host(host, NULL); + scsi_add_host(host, NULL); /* XXX handle failure */ + scsi_scan_host(host); sprintf(info->node.dev_name, "scsi%d", host->host_no); link->dev = &info->node; diff --git a/drivers/scsi/pcmcia/fdomain_stub.c b/drivers/scsi/pcmcia/fdomain_stub.c index 7e12c1d37673..e91187dca450 100644 --- a/drivers/scsi/pcmcia/fdomain_stub.c +++ b/drivers/scsi/pcmcia/fdomain_stub.c @@ -254,7 +254,8 @@ static void fdomain_config(dev_link_t *link) goto cs_failed; } - scsi_add_host(host, NULL); + scsi_add_host(host, NULL); /* XXX handle failure */ + scsi_scan_host(host); sprintf(info->node.dev_name, "scsi%d", host->host_no); link->dev = &info->node; diff --git a/drivers/scsi/pcmcia/nsp_cs.c b/drivers/scsi/pcmcia/nsp_cs.c index 59291c8b32c1..5165af63b6b5 100644 --- a/drivers/scsi/pcmcia/nsp_cs.c +++ b/drivers/scsi/pcmcia/nsp_cs.c @@ -1773,7 +1773,8 @@ static void nsp_cs_config(dev_link_t *link) req.Base+req.Size-1); printk("\n"); - scsi_add_host(host, NULL); + scsi_add_host(host, NULL); /* XXX handle failure */ + scsi_scan_host(host); link->state &= ~DEV_CONFIG_PENDING; return; diff --git a/drivers/scsi/pcmcia/qlogic_stub.c b/drivers/scsi/pcmcia/qlogic_stub.c index debc8c985330..503a5fd05d96 100644 --- a/drivers/scsi/pcmcia/qlogic_stub.c +++ b/drivers/scsi/pcmcia/qlogic_stub.c @@ -270,7 +270,8 @@ static void qlogic_config(dev_link_t * link) link->dev = &info->node; info->host = host; - scsi_add_host(host, NULL); + scsi_add_host(host, NULL); /* XXX handle failure */ + scsi_scan_host(host); out: link->state &= ~DEV_CONFIG_PENDING; diff --git a/drivers/scsi/scsi.h b/drivers/scsi/scsi.h index 3ff36ab84744..5d2e6d8aec01 100644 --- a/drivers/scsi/scsi.h +++ b/drivers/scsi/scsi.h @@ -174,11 +174,6 @@ extern const char *scsi_extd_sense_format(unsigned char, unsigned char); #define SCSI_MLQUEUE_DEVICE_BUSY 0x1056 #define SCSI_MLQUEUE_EH_RETRY 0x1057 -extern int scsi_sysfs_modify_sdev_attribute(struct device_attribute ***dev_attrs, - struct device_attribute *attr); -extern int scsi_sysfs_modify_shost_attribute(struct class_device_attribute ***class_attrs, - struct class_device_attribute *attr); - /* * Legacy dma direction interfaces. * diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index 138e78f133b7..47125ef5d93e 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c @@ -687,7 +687,7 @@ static int resp_mode_sense(unsigned char * cmd, int target, pcontrol = (cmd[2] & 0xc0) >> 6; pcode = cmd[2] & 0x3f; msense_6 = (MODE_SENSE == cmd[0]); - alloc_len = msense_6 ? cmd[4] : ((cmd[7] << 8) | cmd[6]); + alloc_len = msense_6 ? cmd[4] : ((cmd[7] << 8) | cmd[8]); /* printk(KERN_INFO "msense: dbd=%d pcontrol=%d pcode=%d " "msense_6=%d alloc_len=%d\n", dbd, pcontrol, pcode, " "msense_6, alloc_len); */ @@ -1701,7 +1701,8 @@ static int sdebug_driver_probe(struct device * dev) printk(KERN_ERR "%s: scsi_add_host failed\n", __FUNCTION__); error = -ENODEV; scsi_host_put(hpnt); - } + } else + scsi_scan_host(hpnt); return error; diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 3997f09783e0..3a5d82add006 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -444,22 +444,8 @@ static void scsi_run_queue(struct request_queue *q) */ static void scsi_requeue_command(struct request_queue *q, struct scsi_cmnd *cmd) { - unsigned long flags; - - spin_lock_irqsave(q->queue_lock, flags); - cmd->request->special = cmd; - if (blk_rq_tagged(cmd->request)) - blk_queue_end_tag(q, cmd->request); - - /* - * set REQ_SPECIAL - we have a command - * clear REQ_DONTPREP - we assume the sg table has been - * nuked so we need to set it up again. - */ - cmd->request->flags |= REQ_SPECIAL; cmd->request->flags &= ~REQ_DONTPREP; - __elv_add_request(q, cmd->request, 0, 0); - spin_unlock_irqrestore(q->queue_lock, flags); + blk_insert_request(q, cmd->request, 1, cmd); scsi_run_queue(q); } @@ -1213,9 +1199,7 @@ static void scsi_request_fn(struct request_queue *q) * later time. */ spin_lock_irq(q->queue_lock); - if (blk_rq_tagged(req)) - blk_queue_end_tag(q, req); - __elv_add_request(q, req, 0, 0); + blk_requeue_request(q, req); sdev->device_busy--; if(sdev->device_busy == 0) blk_plug_device(q); @@ -1426,17 +1410,17 @@ __scsi_mode_sense(struct scsi_request *sreq, int dbd, int modepage, if(scsi_status_is_good(sreq->sr_result)) { data->header_length = header_length; if(use_10_for_ms) { - data->length = buffer[0]*256 + buffer[1]; + data->length = buffer[0]*256 + buffer[1] + 2; data->medium_type = buffer[2]; data->device_specific = buffer[3]; data->longlba = buffer[4] & 0x01; data->block_descriptor_length = buffer[6]*256 + buffer[7]; } else { - data->length = buffer[0]; + data->length = buffer[0] + 1; data->medium_type = buffer[1]; - data->device_specific = buffer[3]; - data->block_descriptor_length = buffer[4]; + data->device_specific = buffer[2]; + data->block_descriptor_length = buffer[3]; } } diff --git a/drivers/scsi/scsi_module.c b/drivers/scsi/scsi_module.c index 7803089da533..515a3e4b48fe 100644 --- a/drivers/scsi/scsi_module.c +++ b/drivers/scsi/scsi_module.c @@ -40,6 +40,7 @@ static int __init init_this_scsi_driver(void) error = scsi_add_host(shost, NULL); if (error) goto fail; + scsi_scan_host(shost); } return 0; fail: diff --git a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h index 6346005e64c7..f17bdd42afe6 100644 --- a/drivers/scsi/scsi_priv.h +++ b/drivers/scsi/scsi_priv.h @@ -102,7 +102,6 @@ extern void scsi_exit_procfs(void); #endif /* CONFIG_PROC_FS */ /* scsi_scan.c */ -extern void scsi_scan_host(struct Scsi_Host *); extern void scsi_forget_host(struct Scsi_Host *); extern void scsi_free_sdev(struct scsi_device *); extern void scsi_free_shost(struct Scsi_Host *); @@ -117,11 +116,6 @@ extern void scsi_sysfs_remove_host(struct Scsi_Host *); extern int scsi_sysfs_register(void); extern void scsi_sysfs_unregister(void); -/* definitions for the linker default sections covering the host - * class and device attributes */ -extern struct class_device_attribute *scsi_sysfs_shost_attrs[]; -extern struct device_attribute *scsi_sysfs_sdev_attrs[]; - extern struct class shost_class; extern struct bus_type scsi_bus_type; diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index 9dffa0c2caca..3b8309105021 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c @@ -464,8 +464,7 @@ static void scsi_set_name(struct scsi_device *sdev, char *inq_result) while (i >= 0 && type[i] == ' ') type[i--] = '\0'; - snprintf(sdev->sdev_driverfs_dev.name, DEVICE_NAME_SIZE, "SCSI %s", - type); + snprintf(sdev->sdev_gendev.name, DEVICE_NAME_SIZE, "SCSI %s", type); } /** diff --git a/drivers/scsi/scsi_syms.c b/drivers/scsi/scsi_syms.c index 62e413ef5949..2ce7cb6c25bf 100644 --- a/drivers/scsi/scsi_syms.c +++ b/drivers/scsi/scsi_syms.c @@ -34,6 +34,7 @@ EXPORT_SYMBOL(scsi_register_driver); EXPORT_SYMBOL(scsi_register_interface); EXPORT_SYMBOL(scsi_host_alloc); EXPORT_SYMBOL(scsi_add_host); +EXPORT_SYMBOL(scsi_scan_host); EXPORT_SYMBOL(scsi_remove_host); EXPORT_SYMBOL(scsi_host_get); EXPORT_SYMBOL(scsi_host_put); diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index 80be2659043d..3801b768c733 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c @@ -45,7 +45,7 @@ shost_rd_attr(cmd_per_lun, "%hd\n"); shost_rd_attr(sg_tablesize, "%hu\n"); shost_rd_attr(unchecked_isa_dma, "%d\n"); -struct class_device_attribute *scsi_sysfs_shost_attrs[] = { +static struct class_device_attribute *scsi_sysfs_shost_attrs[] = { &class_device_attr_unique_id, &class_device_attr_host_busy, &class_device_attr_cmd_per_lun, @@ -204,7 +204,7 @@ store_rescan_field (struct device *dev, const char *buf, size_t count) static DEVICE_ATTR(rescan, S_IWUSR, NULL, store_rescan_field) /* Default template for device attributes. May NOT be modified */ -struct device_attribute *scsi_sysfs_sdev_attrs[] = { +static struct device_attribute *scsi_sysfs_sdev_attrs[] = { &dev_attr_device_blocked, &dev_attr_queue_depth, &dev_attr_type, @@ -228,6 +228,42 @@ static void scsi_device_release(struct device *dev) scsi_free_sdev(sdev); } +static struct device_attribute *attr_overridden( + struct device_attribute **attrs, + struct device_attribute *attr) +{ + int i; + + if (!attrs) + return NULL; + for (i = 0; attrs[i]; i++) + if (!strcmp(attrs[i]->attr.name, attr->attr.name)) + return attrs[i]; + return NULL; +} + +static int attr_add(struct device *dev, struct device_attribute *attr) +{ + struct device_attribute *base_attr; + + /* + * Spare the caller from having to copy things it's not interested in. + */ + base_attr = attr_overridden(scsi_sysfs_sdev_attrs, attr); + if (base_attr) { + /* extend permissions */ + attr->attr.mode |= base_attr->attr.mode; + + /* override null show/store with default */ + if (!attr->show) + attr->show = base_attr->show; + if (!attr->store) + attr->store = base_attr->store; + } + + return device_create_file(dev, attr); +} + /** * scsi_device_register - register a scsi device with the scsi bus * @sdev: scsi_device to register @@ -239,20 +275,20 @@ int scsi_device_register(struct scsi_device *sdev) { int error = 0, i; - device_initialize(&sdev->sdev_driverfs_dev); - sprintf(sdev->sdev_driverfs_dev.bus_id,"%d:%d:%d:%d", + device_initialize(&sdev->sdev_gendev); + sprintf(sdev->sdev_gendev.bus_id,"%d:%d:%d:%d", sdev->host->host_no, sdev->channel, sdev->id, sdev->lun); - sdev->sdev_driverfs_dev.parent = &sdev->host->host_gendev; - sdev->sdev_driverfs_dev.bus = &scsi_bus_type; - sdev->sdev_driverfs_dev.release = scsi_device_release; + sdev->sdev_gendev.parent = &sdev->host->shost_gendev; + sdev->sdev_gendev.bus = &scsi_bus_type; + sdev->sdev_gendev.release = scsi_device_release; class_device_initialize(&sdev->sdev_classdev); - sdev->sdev_classdev.dev = &sdev->sdev_driverfs_dev; + sdev->sdev_classdev.dev = &sdev->sdev_gendev; sdev->sdev_classdev.class = &sdev_class; snprintf(sdev->sdev_classdev.class_id, BUS_ID_SIZE, "%d:%d:%d:%d", sdev->host->host_no, sdev->channel, sdev->id, sdev->lun); - error = device_add(&sdev->sdev_driverfs_dev); + error = device_add(&sdev->sdev_gendev); if (error) { printk(KERN_INFO "error 1\n"); return error; @@ -260,16 +296,28 @@ int scsi_device_register(struct scsi_device *sdev) error = class_device_add(&sdev->sdev_classdev); if (error) { printk(KERN_INFO "error 2\n"); - device_unregister(&sdev->sdev_driverfs_dev); + device_unregister(&sdev->sdev_gendev); return error; } - for (i = 0; !error && sdev->host->hostt->sdev_attrs[i] != NULL; i++) - error = device_create_file(&sdev->sdev_driverfs_dev, - sdev->host->hostt->sdev_attrs[i]); - - if (error) - scsi_device_unregister(sdev); + if (sdev->host->hostt->sdev_attrs) { + for (i = 0; sdev->host->hostt->sdev_attrs[i]; i++) { + error = attr_add(&sdev->sdev_gendev, + sdev->host->hostt->sdev_attrs[i]); + if (error) + scsi_device_unregister(sdev); + } + } + + for (i = 0; scsi_sysfs_sdev_attrs[i]; i++) { + if (!attr_overridden(sdev->host->hostt->sdev_attrs, + scsi_sysfs_sdev_attrs[i])) { + error = device_create_file(&sdev->sdev_gendev, + scsi_sysfs_sdev_attrs[i]); + if (error) + scsi_device_unregister(sdev); + } + } return error; } @@ -280,12 +328,8 @@ int scsi_device_register(struct scsi_device *sdev) **/ void scsi_device_unregister(struct scsi_device *sdev) { - int i; - - for (i = 0; sdev->host->hostt->sdev_attrs[i] != NULL; i++) - device_remove_file(&sdev->sdev_driverfs_dev, sdev->host->hostt->sdev_attrs[i]); class_device_unregister(&sdev->sdev_classdev); - device_unregister(&sdev->sdev_driverfs_dev); + device_unregister(&sdev->sdev_gendev); } int scsi_register_driver(struct device_driver *drv) @@ -315,20 +359,57 @@ static void scsi_host_release(struct device *dev) void scsi_sysfs_init_host(struct Scsi_Host *shost) { - device_initialize(&shost->host_gendev); - snprintf(shost->host_gendev.bus_id, BUS_ID_SIZE, "host%d", + device_initialize(&shost->shost_gendev); + snprintf(shost->shost_gendev.bus_id, BUS_ID_SIZE, "host%d", shost->host_no); - snprintf(shost->host_gendev.name, DEVICE_NAME_SIZE, "%s", + snprintf(shost->shost_gendev.name, DEVICE_NAME_SIZE, "%s", shost->hostt->proc_name); - shost->host_gendev.release = scsi_host_release; + shost->shost_gendev.release = scsi_host_release; - class_device_initialize(&shost->class_dev); - shost->class_dev.dev = &shost->host_gendev; - shost->class_dev.class = &shost_class; - snprintf(shost->class_dev.class_id, BUS_ID_SIZE, "host%d", + class_device_initialize(&shost->shost_classdev); + shost->shost_classdev.dev = &shost->shost_gendev; + shost->shost_classdev.class = &shost_class; + snprintf(shost->shost_classdev.class_id, BUS_ID_SIZE, "host%d", shost->host_no); } +static struct class_device_attribute *class_attr_overridden( + struct class_device_attribute **attrs, + struct class_device_attribute *attr) +{ + int i; + + if (!attrs) + return NULL; + for (i = 0; attrs[i]; i++) + if (!strcmp(attrs[i]->attr.name, attr->attr.name)) + return attrs[i]; + return NULL; +} + +static int class_attr_add(struct class_device *classdev, + struct class_device_attribute *attr) +{ + struct class_device_attribute *base_attr; + + /* + * Spare the caller from having to copy things it's not interested in. + */ + base_attr = class_attr_overridden(scsi_sysfs_shost_attrs, attr); + if (base_attr) { + /* extend permissions */ + attr->attr.mode |= base_attr->attr.mode; + + /* override null show/store with default */ + if (!attr->show) + attr->show = base_attr->show; + if (!attr->store) + attr->store = base_attr->store; + } + + return class_device_create_file(classdev, attr); +} + /** * scsi_sysfs_add_host - add scsi host to subsystem * @shost: scsi host struct to add to subsystem @@ -336,31 +417,44 @@ void scsi_sysfs_init_host(struct Scsi_Host *shost) **/ int scsi_sysfs_add_host(struct Scsi_Host *shost, struct device *dev) { - int i, error; + int error, i; - if (!shost->host_gendev.parent) - shost->host_gendev.parent = dev ? dev : &legacy_bus; + if (!shost->shost_gendev.parent) + shost->shost_gendev.parent = dev ? dev : &legacy_bus; - error = device_add(&shost->host_gendev); + error = device_add(&shost->shost_gendev); if (error) return error; - error = class_device_add(&shost->class_dev); + error = class_device_add(&shost->shost_classdev); if (error) goto clean_device; - for (i = 0; !error && shost->hostt->shost_attrs[i] != NULL; i++) - error = class_device_create_file(&shost->class_dev, - shost->hostt->shost_attrs[i]); - if (error) - goto clean_class; + if (shost->hostt->shost_attrs) { + for (i = 0; shost->hostt->shost_attrs[i]; i++) { + error = class_attr_add(&shost->shost_classdev, + shost->hostt->shost_attrs[i]); + if (error) + goto clean_class; + } + } + + for (i = 0; scsi_sysfs_shost_attrs[i]; i++) { + if (!class_attr_overridden(shost->hostt->shost_attrs, + scsi_sysfs_shost_attrs[i])) { + error = class_device_create_file(&shost->shost_classdev, + scsi_sysfs_shost_attrs[i]); + if (error) + goto clean_class; + } + } return error; clean_class: - class_device_del(&shost->class_dev); + class_device_del(&shost->shost_classdev); clean_device: - device_del(&shost->host_gendev); + device_del(&shost->shost_gendev); return error; } @@ -371,133 +465,6 @@ clean_device: **/ void scsi_sysfs_remove_host(struct Scsi_Host *shost) { - class_device_del(&shost->class_dev); - device_del(&shost->host_gendev); -} - -/** scsi_sysfs_modify_shost_attribute - modify or add a host class attribute - * - * @class_attrs:host class attribute list to be added to or modified - * @attr: individual attribute to change or added - * - * returns zero if successful or error if not - **/ -int scsi_sysfs_modify_shost_attribute( - struct class_device_attribute ***class_attrs, - struct class_device_attribute *attr) -{ - int modify = -1; - int num_attrs; - - if(*class_attrs == NULL) - *class_attrs = scsi_sysfs_shost_attrs; - - for(num_attrs=0; (*class_attrs)[num_attrs] != NULL; num_attrs++) - if(strcmp((*class_attrs)[num_attrs]->attr.name, - attr->attr.name) == 0) - modify = num_attrs; - - if(*class_attrs == scsi_sysfs_shost_attrs || modify < 0) { - /* note: need space for null at the end as well */ - struct class_device_attribute **tmp_attrs = - kmalloc(sizeof(*tmp_attrs) * - (num_attrs + (modify >= 0 ? 1 : 2)), - GFP_KERNEL); - if(tmp_attrs == NULL) - return -ENOMEM; - memcpy(tmp_attrs, *class_attrs, sizeof(*tmp_attrs) * - (num_attrs + 1)); - if(*class_attrs != scsi_sysfs_shost_attrs) - kfree(*class_attrs); - *class_attrs = tmp_attrs; - } - if(modify >= 0) { - /* spare the caller from having to copy things it's - * not interested in */ - struct class_device_attribute *old_attr = - (*class_attrs)[modify]; - /* extend permissions */ - attr->attr.mode |= old_attr->attr.mode; - - /* override null show/store with default */ - if(attr->show == NULL) - attr->show = old_attr->show; - if(attr->store == NULL) - attr->store = old_attr->store; - (*class_attrs)[modify] = attr; - } else { - (*class_attrs)[num_attrs++] = attr; - (*class_attrs)[num_attrs] = NULL; - } - - return 0; -} -EXPORT_SYMBOL(scsi_sysfs_modify_shost_attribute); - -/** scsi_sysfs_modify_sdev_attribute - modify or add a host device attribute - * - * @dev_attrs: pointer to the attribute list to be added to or modified - * @attr: individual attribute to change or added - * - * returns zero if successful or error if not - **/ -int scsi_sysfs_modify_sdev_attribute(struct device_attribute ***dev_attrs, - struct device_attribute *attr) -{ - int modify = -1; - int num_attrs; - - if(*dev_attrs == NULL) - *dev_attrs = scsi_sysfs_sdev_attrs; - - for(num_attrs=0; (*dev_attrs)[num_attrs] != NULL; num_attrs++) - if(strcmp((*dev_attrs)[num_attrs]->attr.name, - attr->attr.name) == 0) - modify = num_attrs; - - if(*dev_attrs == scsi_sysfs_sdev_attrs || modify < 0) { - /* note: need space for null at the end as well */ - struct device_attribute **tmp_attrs = - kmalloc(sizeof(*tmp_attrs) * - (num_attrs + (modify >= 0 ? 1 : 2)), - GFP_KERNEL); - if(tmp_attrs == NULL) - return -ENOMEM; - memcpy(tmp_attrs, *dev_attrs, sizeof(*tmp_attrs) * - (num_attrs + 1)); - if(*dev_attrs != scsi_sysfs_sdev_attrs) - kfree(*dev_attrs); - *dev_attrs = tmp_attrs; - } - if(modify >= 0) { - /* spare the caller from having to copy things it's - * not interested in */ - struct device_attribute *old_attr = - (*dev_attrs)[modify]; - /* extend permissions */ - attr->attr.mode |= old_attr->attr.mode; - - /* override null show/store with default */ - if(attr->show == NULL) - attr->show = old_attr->show; - if(attr->store == NULL) - attr->store = old_attr->store; - (*dev_attrs)[modify] = attr; - } else { - (*dev_attrs)[num_attrs++] = attr; - (*dev_attrs)[num_attrs] = NULL; - } - - return 0; -} -EXPORT_SYMBOL(scsi_sysfs_modify_sdev_attribute); - -void scsi_sysfs_release_attributes(struct scsi_host_template *hostt) -{ - if(hostt->sdev_attrs != scsi_sysfs_sdev_attrs) - kfree(hostt->sdev_attrs); - - if(hostt->shost_attrs != scsi_sysfs_shost_attrs) - kfree(hostt->shost_attrs); + class_device_del(&shost->shost_classdev); + device_del(&shost->shost_gendev); } -EXPORT_SYMBOL(scsi_sysfs_release_attributes); diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index dead50aa989e..441ca6e58cfc 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -606,35 +606,8 @@ not_present: static void sd_rescan(struct device *dev) { - struct scsi_device *sdp = to_scsi_device(dev); struct scsi_disk *sdkp = dev_get_drvdata(dev); - struct gendisk *gd; - struct scsi_request *SRpnt; - unsigned char *buffer; - - if (!sdkp || sdp->online == FALSE || !sdkp->media_present) - return; - - gd = sdkp->disk; - - SCSI_LOG_HLQUEUE(3, printk("sd_rescan: disk=%s\n", gd->disk_name)); - - SRpnt = scsi_allocate_request(sdp); - if (!SRpnt) { - printk(KERN_WARNING "(sd_rescan:) Request allocation " - "failure.\n"); - return; - } - - if (sdkp->device->host->unchecked_isa_dma) - buffer = kmalloc(512, GFP_DMA); - else - buffer = kmalloc(512, GFP_KERNEL); - - sd_read_capacity(sdkp, gd->disk_name, SRpnt, buffer); - set_capacity(gd, sdkp->capacity); - scsi_release_request(SRpnt); - kfree(buffer); + sd_revalidate_disk(sdkp->disk); } static struct block_device_operations sd_fops = { @@ -1318,7 +1291,7 @@ static int sd_probe(struct device *dev) sd_revalidate_disk(gd); - gd->driverfs_dev = &sdp->sdev_driverfs_dev; + gd->driverfs_dev = &sdp->sdev_gendev; gd->flags = GENHD_FL_DRIVERFS; if (sdp->removable) gd->flags |= GENHD_FL_REMOVABLE; diff --git a/drivers/scsi/sim710.c b/drivers/scsi/sim710.c index d5b8cb39b485..5132357c8fd8 100644 --- a/drivers/scsi/sim710.c +++ b/drivers/scsi/sim710.c @@ -138,7 +138,8 @@ sim710_probe_common(struct device *dev, unsigned long base_addr, goto out_unregister; } - scsi_add_host(host, dev); + scsi_add_host(host, dev); /* XXX handle failure */ + scsi_scan_host(host); hostdata->dev = dev; return 0; diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index e38e8d1d2231..7c24b78e45e6 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c @@ -533,7 +533,7 @@ static int sr_probe(struct device *dev) snprintf(disk->devfs_name, sizeof(disk->devfs_name), "%s/cd", sdev->devfs_name); - disk->driverfs_dev = &sdev->sdev_driverfs_dev; + disk->driverfs_dev = &sdev->sdev_gendev; register_cdrom(&cd->cdi); set_capacity(disk, cd->capacity); disk->private_data = &cd->driver; diff --git a/drivers/scsi/sym53c8xx_2/sym_glue.c b/drivers/scsi/sym53c8xx_2/sym_glue.c index be1548c00e3d..b0266f645172 100644 --- a/drivers/scsi/sym53c8xx_2/sym_glue.c +++ b/drivers/scsi/sym53c8xx_2/sym_glue.c @@ -1110,6 +1110,7 @@ static int sym_eh_handler(int op, char *opname, Scsi_Cmnd *cmd) int sts = -1; struct sym_eh_wait eh, *ep = &eh; char devname[20]; + unsigned long flags; sprintf(devname, "%s:%d:%d", sym_name(np), cmd->device->id, cmd->device->lun); @@ -1201,7 +1202,11 @@ finish: ep->timer.data = (u_long)cmd; ep->timed_out = 1; /* Be pessimistic for once :) */ add_timer(&ep->timer); + local_save_flags(flags); + spin_unlock_irq(cmd->device->host->host_lock); down(&ep->sem); + local_irq_restore(flags); + spin_lock(cmd->device->host->host_lock); if (ep->timed_out) sts = -2; } diff --git a/drivers/scsi/zalon.c b/drivers/scsi/zalon.c index bed64aaec0bc..05700528818b 100644 --- a/drivers/scsi/zalon.c +++ b/drivers/scsi/zalon.c @@ -85,7 +85,7 @@ zalon_scsi_callback(struct parisc_device *dev) { struct gsc_irq gsc_irq; u32 zalon_vers; - int irq; + int irq, error = -ENODEV; unsigned long zalon = dev->hpa; unsigned long io_port = zalon + GSC_SCSI_ZALON_OFFSET; static int unit = 0; @@ -147,11 +147,18 @@ zalon_scsi_callback(struct parisc_device *dev) dev_set_drvdata(&dev->dev, host); - scsi_add_host(host, &dev->dev); + error = scsi_add_host(host, &dev->dev); + if (error) + goto fail_free_irq; + scsi_scan_host(host); return 0; + + fail_free_irq: + free_irq(irq, host); fail: - return -ENODEV; + ncr53c8xx_release(host); + return error; } static struct parisc_device_id zalon_tbl[] = { diff --git a/drivers/usb/image/hpusbscsi.c b/drivers/usb/image/hpusbscsi.c index cc1768849fcc..bc323a4c74bf 100644 --- a/drivers/usb/image/hpusbscsi.c +++ b/drivers/usb/image/hpusbscsi.c @@ -109,7 +109,8 @@ hpusbscsi_usb_probe(struct usb_interface *intf, goto out_unlink_controlurb; new->host->hostdata[0] = (unsigned long)new; - scsi_add_host(new->host, &intf->dev); + scsi_add_host(new->host, &intf->dev); /* XXX handle failure */ + scsi_scan_host(new->host); new->sense_command[0] = REQUEST_SENSE; new->sense_command[4] = HPUSBSCSI_SENSE_LENGTH; diff --git a/drivers/usb/image/microtek.c b/drivers/usb/image/microtek.c index dcef1e90929d..e5f1a12dc2bb 100644 --- a/drivers/usb/image/microtek.c +++ b/drivers/usb/image/microtek.c @@ -817,7 +817,8 @@ static int mts_usb_probe(struct usb_interface *intf, goto out_free_urb; new_desc->host->hostdata[0] = (unsigned long)new_desc; - scsi_add_host(new_desc->host, NULL); + scsi_add_host(new_desc->host, NULL); /* XXX handle failure */ + scsi_scan_host(new_desc->host); usb_set_intfdata(intf, new_desc); return 0; diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c index ef495072850f..ee67b5340adc 100644 --- a/drivers/usb/storage/usb.c +++ b/drivers/usb/storage/usb.c @@ -958,6 +958,8 @@ static int storage_probe(struct usb_interface *intf, goto BadDevice; } + scsi_scan_host(us->host); + printk(KERN_DEBUG "WARNING: USB Mass Storage data integrity not assured\n"); printk(KERN_DEBUG diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 2e7f92aa1dc2..4f65bab2f201 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -491,6 +491,7 @@ extern void __blk_attempt_remerge(request_queue_t *, struct request *); extern struct request *blk_get_request(request_queue_t *, int, int); extern void blk_put_request(struct request *); extern void blk_insert_request(request_queue_t *, struct request *, int, void *); +extern void blk_requeue_request(request_queue_t *, struct request *); extern void blk_plug_device(request_queue_t *); extern int blk_remove_plug(request_queue_t *); extern void blk_recount_segments(request_queue_t *, struct bio *); diff --git a/include/linux/elevator.h b/include/linux/elevator.h index b0e70562be94..3eeb5a2e4591 100644 --- a/include/linux/elevator.h +++ b/include/linux/elevator.h @@ -13,6 +13,7 @@ typedef struct request *(elevator_next_req_fn) (request_queue_t *); typedef void (elevator_add_req_fn) (request_queue_t *, struct request *, struct list_head *); typedef int (elevator_queue_empty_fn) (request_queue_t *); typedef void (elevator_remove_req_fn) (request_queue_t *, struct request *); +typedef void (elevator_requeue_req_fn) (request_queue_t *, struct request *); typedef struct request *(elevator_request_list_fn) (request_queue_t *, struct request *); typedef struct list_head *(elevator_get_sort_head_fn) (request_queue_t *, struct request *); typedef void (elevator_completed_req_fn) (request_queue_t *, struct request *); @@ -33,6 +34,7 @@ struct elevator_s elevator_next_req_fn *elevator_next_req_fn; elevator_add_req_fn *elevator_add_req_fn; elevator_remove_req_fn *elevator_remove_req_fn; + elevator_requeue_req_fn *elevator_requeue_req_fn; elevator_queue_empty_fn *elevator_queue_empty_fn; elevator_completed_req_fn *elevator_completed_req_fn; @@ -64,6 +66,7 @@ extern void elv_merge_requests(request_queue_t *, struct request *, struct request *); extern void elv_merged_request(request_queue_t *, struct request *); extern void elv_remove_request(request_queue_t *, struct request *); +extern void elv_requeue_request(request_queue_t *, struct request *); extern int elv_queue_empty(request_queue_t *); extern struct request *elv_next_request(struct request_queue *q); extern struct request *elv_former_request(request_queue_t *, struct request *); diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h index c49c124fde74..de5ff9fd6c4a 100644 --- a/include/scsi/scsi_device.h +++ b/include/scsi/scsi_device.h @@ -11,8 +11,6 @@ struct scsi_mode_data; struct scsi_device { - struct class_device sdev_classdev; - struct list_head siblings; /* list of all devices on this host */ struct list_head same_target_siblings; /* just the devices sharing same target id */ struct Scsi_Host *host; @@ -86,10 +84,11 @@ struct scsi_device { unsigned int max_device_blocked; /* what device_blocked counts down from */ #define SCSI_DEFAULT_DEVICE_BLOCKED 3 - struct device sdev_driverfs_dev; + struct device sdev_gendev; + struct class_device sdev_classdev; }; #define to_scsi_device(d) \ - container_of(d, struct scsi_device, sdev_driverfs_dev) + container_of(d, struct scsi_device, sdev_gendev) extern struct scsi_device *scsi_add_device(struct Scsi_Host *, uint, uint, uint); diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h index d92dc75d131d..3ef701078fef 100644 --- a/include/scsi/scsi_host.h +++ b/include/scsi/scsi_host.h @@ -329,12 +329,12 @@ struct scsi_host_template { #define SCSI_DEFAULT_HOST_BLOCKED 7 /* - * Pointer to the sysfs class properties for this host + * Pointer to the sysfs class properties for this host, NULL terminated. */ struct class_device_attribute **shost_attrs; /* - * Pointer to the SCSI device properties for this host + * Pointer to the SCSI device properties for this host, NULL terminated. */ struct device_attribute **sdev_attrs; @@ -442,12 +442,6 @@ struct Scsi_Host { */ unsigned int max_host_blocked; - /* - * Support for sysfs - */ - struct device host_gendev; - struct class_device class_dev; - /* legacy crap */ unsigned long base; unsigned long io_port; @@ -455,6 +449,9 @@ struct Scsi_Host { unsigned char dma_channel; unsigned int irq; + /* ldm bits */ + struct device shost_gendev; + struct class_device shost_classdev; /* * List of hosts per template. @@ -474,12 +471,13 @@ struct Scsi_Host { __attribute__ ((aligned (sizeof(unsigned long)))); }; #define dev_to_shost(d) \ - container_of(d, struct Scsi_Host, host_gendev) + container_of(d, struct Scsi_Host, shost_gendev) #define class_to_shost(d) \ - container_of(d, struct Scsi_Host, class_dev) + container_of(d, struct Scsi_Host, shost_classdev) extern struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *, int); extern int scsi_add_host(struct Scsi_Host *, struct device *); +extern void scsi_scan_host(struct Scsi_Host *); extern int scsi_remove_host(struct Scsi_Host *); extern void scsi_host_get(struct Scsi_Host *); extern void scsi_host_put(struct Scsi_Host *t); @@ -495,16 +493,14 @@ static inline void scsi_assign_lock(struct Scsi_Host *shost, spinlock_t *lock) static inline void scsi_set_device(struct Scsi_Host *shost, struct device *dev) { - shost->host_gendev.parent = dev; + shost->shost_gendev.parent = dev; } static inline struct device *scsi_get_device(struct Scsi_Host *shost) { - return shost->host_gendev.parent; + return shost->shost_gendev.parent; } -extern void scsi_sysfs_release_attributes(struct scsi_host_template *); - extern void scsi_unblock_requests(struct Scsi_Host *); extern void scsi_block_requests(struct Scsi_Host *); diff --git a/include/scsi/scsi_request.h b/include/scsi/scsi_request.h index 90dcdaafe946..d591d365c983 100644 --- a/include/scsi/scsi_request.h +++ b/include/scsi/scsi_request.h @@ -56,7 +56,7 @@ extern void scsi_do_req(struct scsi_request *, const void *cmnd, int timeout, int retries); struct scsi_mode_data { - __u16 length; + __u32 length; __u16 block_descriptor_length; __u8 medium_type; __u8 device_specific; |
