diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/scsi/BusLogic.c | 12 | ||||
-rw-r--r-- | drivers/scsi/Makefile | 2 | ||||
-rw-r--r-- | drivers/scsi/NCR53c406a.c | 5 | ||||
-rw-r--r-- | drivers/scsi/aha1740.c | 10 | ||||
-rw-r--r-- | drivers/scsi/aic94xx/aic94xx_init.c | 9 | ||||
-rw-r--r-- | drivers/scsi/aic94xx/aic94xx_scb.c | 120 | ||||
-rw-r--r-- | drivers/scsi/fd_mcs.c | 2 | ||||
-rw-r--r-- | drivers/scsi/hosts.c | 4 | ||||
-rw-r--r-- | drivers/scsi/ips.c | 28 | ||||
-rw-r--r-- | drivers/scsi/ips.h | 9 | ||||
-rw-r--r-- | drivers/scsi/libsas/sas_init.c | 4 | ||||
-rw-r--r-- | drivers/scsi/libsas/sas_scsi_host.c | 90 | ||||
-rw-r--r-- | drivers/scsi/ncr53c8xx.c | 19 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_os.c | 12 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_sup.c | 8 | ||||
-rw-r--r-- | drivers/scsi/scsi.c | 2 | ||||
-rw-r--r-- | drivers/scsi/scsi_error.c | 33 | ||||
-rw-r--r-- | drivers/scsi/scsi_lib.c | 313 | ||||
-rw-r--r-- | drivers/scsi/scsi_priv.h | 3 | ||||
-rw-r--r-- | drivers/scsi/scsi_scan.c | 203 | ||||
-rw-r--r-- | drivers/scsi/scsi_wait_scan.c | 31 | ||||
-rw-r--r-- | drivers/scsi/sd.c | 29 | ||||
-rw-r--r-- | drivers/scsi/st.c | 16 | ||||
-rw-r--r-- | drivers/scsi/t128.h | 39 |
24 files changed, 732 insertions, 271 deletions
diff --git a/drivers/scsi/BusLogic.c b/drivers/scsi/BusLogic.c index cdd033724786..3075204915c8 100644 --- a/drivers/scsi/BusLogic.c +++ b/drivers/scsi/BusLogic.c | |||
@@ -2186,21 +2186,21 @@ static int __init BusLogic_init(void) | |||
2186 | 2186 | ||
2187 | if (BusLogic_ProbeOptions.NoProbe) | 2187 | if (BusLogic_ProbeOptions.NoProbe) |
2188 | return -ENODEV; | 2188 | return -ENODEV; |
2189 | BusLogic_ProbeInfoList = (struct BusLogic_ProbeInfo *) | 2189 | BusLogic_ProbeInfoList = |
2190 | kmalloc(BusLogic_MaxHostAdapters * sizeof(struct BusLogic_ProbeInfo), GFP_ATOMIC); | 2190 | kzalloc(BusLogic_MaxHostAdapters * sizeof(struct BusLogic_ProbeInfo), GFP_KERNEL); |
2191 | if (BusLogic_ProbeInfoList == NULL) { | 2191 | if (BusLogic_ProbeInfoList == NULL) { |
2192 | BusLogic_Error("BusLogic: Unable to allocate Probe Info List\n", NULL); | 2192 | BusLogic_Error("BusLogic: Unable to allocate Probe Info List\n", NULL); |
2193 | return -ENOMEM; | 2193 | return -ENOMEM; |
2194 | } | 2194 | } |
2195 | memset(BusLogic_ProbeInfoList, 0, BusLogic_MaxHostAdapters * sizeof(struct BusLogic_ProbeInfo)); | 2195 | |
2196 | PrototypeHostAdapter = (struct BusLogic_HostAdapter *) | 2196 | PrototypeHostAdapter = |
2197 | kmalloc(sizeof(struct BusLogic_HostAdapter), GFP_ATOMIC); | 2197 | kzalloc(sizeof(struct BusLogic_HostAdapter), GFP_KERNEL); |
2198 | if (PrototypeHostAdapter == NULL) { | 2198 | if (PrototypeHostAdapter == NULL) { |
2199 | kfree(BusLogic_ProbeInfoList); | 2199 | kfree(BusLogic_ProbeInfoList); |
2200 | BusLogic_Error("BusLogic: Unable to allocate Prototype " "Host Adapter\n", NULL); | 2200 | BusLogic_Error("BusLogic: Unable to allocate Prototype " "Host Adapter\n", NULL); |
2201 | return -ENOMEM; | 2201 | return -ENOMEM; |
2202 | } | 2202 | } |
2203 | memset(PrototypeHostAdapter, 0, sizeof(struct BusLogic_HostAdapter)); | 2203 | |
2204 | #ifdef MODULE | 2204 | #ifdef MODULE |
2205 | if (BusLogic != NULL) | 2205 | if (BusLogic != NULL) |
2206 | BusLogic_Setup(BusLogic); | 2206 | BusLogic_Setup(BusLogic); |
diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile index bcca39c3bcbf..a0a77fde3708 100644 --- a/drivers/scsi/Makefile +++ b/drivers/scsi/Makefile | |||
@@ -141,6 +141,8 @@ obj-$(CONFIG_CHR_DEV_SCH) += ch.o | |||
141 | # This goes last, so that "real" scsi devices probe earlier | 141 | # This goes last, so that "real" scsi devices probe earlier |
142 | obj-$(CONFIG_SCSI_DEBUG) += scsi_debug.o | 142 | obj-$(CONFIG_SCSI_DEBUG) += scsi_debug.o |
143 | 143 | ||
144 | obj-$(CONFIG_SCSI) += scsi_wait_scan.o | ||
145 | |||
144 | scsi_mod-y += scsi.o hosts.o scsi_ioctl.o constants.o \ | 146 | scsi_mod-y += scsi.o hosts.o scsi_ioctl.o constants.o \ |
145 | scsicam.o scsi_error.o scsi_lib.o \ | 147 | scsicam.o scsi_error.o scsi_lib.o \ |
146 | scsi_scan.o scsi_sysfs.o \ | 148 | scsi_scan.o scsi_sysfs.o \ |
diff --git a/drivers/scsi/NCR53c406a.c b/drivers/scsi/NCR53c406a.c index d4613815f685..8578555d58fd 100644 --- a/drivers/scsi/NCR53c406a.c +++ b/drivers/scsi/NCR53c406a.c | |||
@@ -220,9 +220,11 @@ static void *addresses[] = { | |||
220 | static unsigned short ports[] = { 0x230, 0x330, 0x280, 0x290, 0x330, 0x340, 0x300, 0x310, 0x348, 0x350 }; | 220 | static unsigned short ports[] = { 0x230, 0x330, 0x280, 0x290, 0x330, 0x340, 0x300, 0x310, 0x348, 0x350 }; |
221 | #define PORT_COUNT ARRAY_SIZE(ports) | 221 | #define PORT_COUNT ARRAY_SIZE(ports) |
222 | 222 | ||
223 | #ifndef MODULE | ||
223 | /* possible interrupt channels */ | 224 | /* possible interrupt channels */ |
224 | static unsigned short intrs[] = { 10, 11, 12, 15 }; | 225 | static unsigned short intrs[] = { 10, 11, 12, 15 }; |
225 | #define INTR_COUNT ARRAY_SIZE(intrs) | 226 | #define INTR_COUNT ARRAY_SIZE(intrs) |
227 | #endif /* !MODULE */ | ||
226 | 228 | ||
227 | /* signatures for NCR 53c406a based controllers */ | 229 | /* signatures for NCR 53c406a based controllers */ |
228 | #if USE_BIOS | 230 | #if USE_BIOS |
@@ -605,6 +607,7 @@ static int NCR53c406a_release(struct Scsi_Host *shost) | |||
605 | return 0; | 607 | return 0; |
606 | } | 608 | } |
607 | 609 | ||
610 | #ifndef MODULE | ||
608 | /* called from init/main.c */ | 611 | /* called from init/main.c */ |
609 | static int __init NCR53c406a_setup(char *str) | 612 | static int __init NCR53c406a_setup(char *str) |
610 | { | 613 | { |
@@ -661,6 +664,8 @@ static int __init NCR53c406a_setup(char *str) | |||
661 | 664 | ||
662 | __setup("ncr53c406a=", NCR53c406a_setup); | 665 | __setup("ncr53c406a=", NCR53c406a_setup); |
663 | 666 | ||
667 | #endif /* !MODULE */ | ||
668 | |||
664 | static const char *NCR53c406a_info(struct Scsi_Host *SChost) | 669 | static const char *NCR53c406a_info(struct Scsi_Host *SChost) |
665 | { | 670 | { |
666 | DEB(printk("NCR53c406a_info called\n")); | 671 | DEB(printk("NCR53c406a_info called\n")); |
diff --git a/drivers/scsi/aha1740.c b/drivers/scsi/aha1740.c index c3c38a7e8d32..d7af9c63a04d 100644 --- a/drivers/scsi/aha1740.c +++ b/drivers/scsi/aha1740.c | |||
@@ -586,7 +586,7 @@ static struct scsi_host_template aha1740_template = { | |||
586 | 586 | ||
587 | static int aha1740_probe (struct device *dev) | 587 | static int aha1740_probe (struct device *dev) |
588 | { | 588 | { |
589 | int slotbase; | 589 | int slotbase, rc; |
590 | unsigned int irq_level, irq_type, translation; | 590 | unsigned int irq_level, irq_type, translation; |
591 | struct Scsi_Host *shpnt; | 591 | struct Scsi_Host *shpnt; |
592 | struct aha1740_hostdata *host; | 592 | struct aha1740_hostdata *host; |
@@ -641,10 +641,16 @@ static int aha1740_probe (struct device *dev) | |||
641 | } | 641 | } |
642 | 642 | ||
643 | eisa_set_drvdata (edev, shpnt); | 643 | eisa_set_drvdata (edev, shpnt); |
644 | scsi_add_host (shpnt, dev); /* XXX handle failure */ | 644 | |
645 | rc = scsi_add_host (shpnt, dev); | ||
646 | if (rc) | ||
647 | goto err_irq; | ||
648 | |||
645 | scsi_scan_host (shpnt); | 649 | scsi_scan_host (shpnt); |
646 | return 0; | 650 | return 0; |
647 | 651 | ||
652 | err_irq: | ||
653 | free_irq(irq_level, shpnt); | ||
648 | err_unmap: | 654 | err_unmap: |
649 | dma_unmap_single (&edev->dev, host->ecb_dma_addr, | 655 | dma_unmap_single (&edev->dev, host->ecb_dma_addr, |
650 | sizeof (host->ecb), DMA_BIDIRECTIONAL); | 656 | sizeof (host->ecb), DMA_BIDIRECTIONAL); |
diff --git a/drivers/scsi/aic94xx/aic94xx_init.c b/drivers/scsi/aic94xx/aic94xx_init.c index 57c5ba4043f2..42302ef05ee5 100644 --- a/drivers/scsi/aic94xx/aic94xx_init.c +++ b/drivers/scsi/aic94xx/aic94xx_init.c | |||
@@ -724,6 +724,15 @@ static void asd_free_queues(struct asd_ha_struct *asd_ha) | |||
724 | 724 | ||
725 | list_for_each_safe(pos, n, &pending) { | 725 | list_for_each_safe(pos, n, &pending) { |
726 | struct asd_ascb *ascb = list_entry(pos, struct asd_ascb, list); | 726 | struct asd_ascb *ascb = list_entry(pos, struct asd_ascb, list); |
727 | /* | ||
728 | * Delete unexpired ascb timers. This may happen if we issue | ||
729 | * a CONTROL PHY scb to an adapter and rmmod before the scb | ||
730 | * times out. Apparently we don't wait for the CONTROL PHY | ||
731 | * to complete, so it doesn't matter if we kill the timer. | ||
732 | */ | ||
733 | del_timer_sync(&ascb->timer); | ||
734 | WARN_ON(ascb->scb->header.opcode != CONTROL_PHY); | ||
735 | |||
727 | list_del_init(pos); | 736 | list_del_init(pos); |
728 | ASD_DPRINTK("freeing from pending\n"); | 737 | ASD_DPRINTK("freeing from pending\n"); |
729 | asd_ascb_free(ascb); | 738 | asd_ascb_free(ascb); |
diff --git a/drivers/scsi/aic94xx/aic94xx_scb.c b/drivers/scsi/aic94xx/aic94xx_scb.c index b15caf1c8fa2..14d5d8c2ee13 100644 --- a/drivers/scsi/aic94xx/aic94xx_scb.c +++ b/drivers/scsi/aic94xx/aic94xx_scb.c | |||
@@ -25,6 +25,7 @@ | |||
25 | */ | 25 | */ |
26 | 26 | ||
27 | #include <linux/pci.h> | 27 | #include <linux/pci.h> |
28 | #include <scsi/scsi_host.h> | ||
28 | 29 | ||
29 | #include "aic94xx.h" | 30 | #include "aic94xx.h" |
30 | #include "aic94xx_reg.h" | 31 | #include "aic94xx_reg.h" |
@@ -412,6 +413,39 @@ void asd_invalidate_edb(struct asd_ascb *ascb, int edb_id) | |||
412 | } | 413 | } |
413 | } | 414 | } |
414 | 415 | ||
416 | /* hard reset a phy later */ | ||
417 | static void do_phy_reset_later(void *data) | ||
418 | { | ||
419 | struct sas_phy *sas_phy = data; | ||
420 | int error; | ||
421 | |||
422 | ASD_DPRINTK("%s: About to hard reset phy %d\n", __FUNCTION__, | ||
423 | sas_phy->identify.phy_identifier); | ||
424 | /* Reset device port */ | ||
425 | error = sas_phy_reset(sas_phy, 1); | ||
426 | if (error) | ||
427 | ASD_DPRINTK("%s: Hard reset of phy %d failed (%d).\n", | ||
428 | __FUNCTION__, sas_phy->identify.phy_identifier, error); | ||
429 | } | ||
430 | |||
431 | static void phy_reset_later(struct sas_phy *sas_phy, struct Scsi_Host *shost) | ||
432 | { | ||
433 | INIT_WORK(&sas_phy->reset_work, do_phy_reset_later, sas_phy); | ||
434 | queue_work(shost->work_q, &sas_phy->reset_work); | ||
435 | } | ||
436 | |||
437 | /* start up the ABORT TASK tmf... */ | ||
438 | static void task_kill_later(struct asd_ascb *ascb) | ||
439 | { | ||
440 | struct asd_ha_struct *asd_ha = ascb->ha; | ||
441 | struct sas_ha_struct *sas_ha = &asd_ha->sas_ha; | ||
442 | struct Scsi_Host *shost = sas_ha->core.shost; | ||
443 | struct sas_task *task = ascb->uldd_task; | ||
444 | |||
445 | INIT_WORK(&task->abort_work, (void (*)(void *))sas_task_abort, task); | ||
446 | queue_work(shost->work_q, &task->abort_work); | ||
447 | } | ||
448 | |||
415 | static void escb_tasklet_complete(struct asd_ascb *ascb, | 449 | static void escb_tasklet_complete(struct asd_ascb *ascb, |
416 | struct done_list_struct *dl) | 450 | struct done_list_struct *dl) |
417 | { | 451 | { |
@@ -439,6 +473,74 @@ static void escb_tasklet_complete(struct asd_ascb *ascb, | |||
439 | ascb->scb->header.opcode); | 473 | ascb->scb->header.opcode); |
440 | } | 474 | } |
441 | 475 | ||
476 | /* Catch these before we mask off the sb_opcode bits */ | ||
477 | switch (sb_opcode) { | ||
478 | case REQ_TASK_ABORT: { | ||
479 | struct asd_ascb *a, *b; | ||
480 | u16 tc_abort; | ||
481 | |||
482 | tc_abort = *((u16*)(&dl->status_block[1])); | ||
483 | tc_abort = le16_to_cpu(tc_abort); | ||
484 | |||
485 | ASD_DPRINTK("%s: REQ_TASK_ABORT, reason=0x%X\n", | ||
486 | __FUNCTION__, dl->status_block[3]); | ||
487 | |||
488 | /* Find the pending task and abort it. */ | ||
489 | list_for_each_entry_safe(a, b, &asd_ha->seq.pend_q, list) | ||
490 | if (a->tc_index == tc_abort) { | ||
491 | task_kill_later(a); | ||
492 | break; | ||
493 | } | ||
494 | goto out; | ||
495 | } | ||
496 | case REQ_DEVICE_RESET: { | ||
497 | struct Scsi_Host *shost = sas_ha->core.shost; | ||
498 | struct sas_phy *dev_phy; | ||
499 | struct asd_ascb *a; | ||
500 | u16 conn_handle; | ||
501 | |||
502 | conn_handle = *((u16*)(&dl->status_block[1])); | ||
503 | conn_handle = le16_to_cpu(conn_handle); | ||
504 | |||
505 | ASD_DPRINTK("%s: REQ_DEVICE_RESET, reason=0x%X\n", __FUNCTION__, | ||
506 | dl->status_block[3]); | ||
507 | |||
508 | /* Kill all pending tasks and reset the device */ | ||
509 | dev_phy = NULL; | ||
510 | list_for_each_entry(a, &asd_ha->seq.pend_q, list) { | ||
511 | struct sas_task *task; | ||
512 | struct domain_device *dev; | ||
513 | u16 x; | ||
514 | |||
515 | task = a->uldd_task; | ||
516 | if (!task) | ||
517 | continue; | ||
518 | dev = task->dev; | ||
519 | |||
520 | x = (unsigned long)dev->lldd_dev; | ||
521 | if (x == conn_handle) { | ||
522 | dev_phy = dev->port->phy; | ||
523 | task_kill_later(a); | ||
524 | } | ||
525 | } | ||
526 | |||
527 | /* Reset device port */ | ||
528 | if (!dev_phy) { | ||
529 | ASD_DPRINTK("%s: No pending commands; can't reset.\n", | ||
530 | __FUNCTION__); | ||
531 | goto out; | ||
532 | } | ||
533 | phy_reset_later(dev_phy, shost); | ||
534 | goto out; | ||
535 | } | ||
536 | case SIGNAL_NCQ_ERROR: | ||
537 | ASD_DPRINTK("%s: SIGNAL_NCQ_ERROR\n", __FUNCTION__); | ||
538 | goto out; | ||
539 | case CLEAR_NCQ_ERROR: | ||
540 | ASD_DPRINTK("%s: CLEAR_NCQ_ERROR\n", __FUNCTION__); | ||
541 | goto out; | ||
542 | } | ||
543 | |||
442 | sb_opcode &= ~DL_PHY_MASK; | 544 | sb_opcode &= ~DL_PHY_MASK; |
443 | 545 | ||
444 | switch (sb_opcode) { | 546 | switch (sb_opcode) { |
@@ -469,22 +571,6 @@ static void escb_tasklet_complete(struct asd_ascb *ascb, | |||
469 | asd_deform_port(asd_ha, phy); | 571 | asd_deform_port(asd_ha, phy); |
470 | sas_ha->notify_port_event(sas_phy, PORTE_TIMER_EVENT); | 572 | sas_ha->notify_port_event(sas_phy, PORTE_TIMER_EVENT); |
471 | break; | 573 | break; |
472 | case REQ_TASK_ABORT: | ||
473 | ASD_DPRINTK("%s: phy%d: REQ_TASK_ABORT\n", __FUNCTION__, | ||
474 | phy_id); | ||
475 | break; | ||
476 | case REQ_DEVICE_RESET: | ||
477 | ASD_DPRINTK("%s: phy%d: REQ_DEVICE_RESET\n", __FUNCTION__, | ||
478 | phy_id); | ||
479 | break; | ||
480 | case SIGNAL_NCQ_ERROR: | ||
481 | ASD_DPRINTK("%s: phy%d: SIGNAL_NCQ_ERROR\n", __FUNCTION__, | ||
482 | phy_id); | ||
483 | break; | ||
484 | case CLEAR_NCQ_ERROR: | ||
485 | ASD_DPRINTK("%s: phy%d: CLEAR_NCQ_ERROR\n", __FUNCTION__, | ||
486 | phy_id); | ||
487 | break; | ||
488 | default: | 574 | default: |
489 | ASD_DPRINTK("%s: phy%d: unknown event:0x%x\n", __FUNCTION__, | 575 | ASD_DPRINTK("%s: phy%d: unknown event:0x%x\n", __FUNCTION__, |
490 | phy_id, sb_opcode); | 576 | phy_id, sb_opcode); |
@@ -504,7 +590,7 @@ static void escb_tasklet_complete(struct asd_ascb *ascb, | |||
504 | 590 | ||
505 | break; | 591 | break; |
506 | } | 592 | } |
507 | 593 | out: | |
508 | asd_invalidate_edb(ascb, edb); | 594 | asd_invalidate_edb(ascb, edb); |
509 | } | 595 | } |
510 | 596 | ||
diff --git a/drivers/scsi/fd_mcs.c b/drivers/scsi/fd_mcs.c index ef8285c326e4..668569e8856b 100644 --- a/drivers/scsi/fd_mcs.c +++ b/drivers/scsi/fd_mcs.c | |||
@@ -294,6 +294,7 @@ static struct Scsi_Host *hosts[FD_MAX_HOSTS + 1] = { NULL }; | |||
294 | static int user_fifo_count = 0; | 294 | static int user_fifo_count = 0; |
295 | static int user_fifo_size = 0; | 295 | static int user_fifo_size = 0; |
296 | 296 | ||
297 | #ifndef MODULE | ||
297 | static int __init fd_mcs_setup(char *str) | 298 | static int __init fd_mcs_setup(char *str) |
298 | { | 299 | { |
299 | static int done_setup = 0; | 300 | static int done_setup = 0; |
@@ -311,6 +312,7 @@ static int __init fd_mcs_setup(char *str) | |||
311 | } | 312 | } |
312 | 313 | ||
313 | __setup("fd_mcs=", fd_mcs_setup); | 314 | __setup("fd_mcs=", fd_mcs_setup); |
315 | #endif /* !MODULE */ | ||
314 | 316 | ||
315 | static void print_banner(struct Scsi_Host *shpnt) | 317 | static void print_banner(struct Scsi_Host *shpnt) |
316 | { | 318 | { |
diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c index 68ef1636678d..2ffdc9e0532d 100644 --- a/drivers/scsi/hosts.c +++ b/drivers/scsi/hosts.c | |||
@@ -301,8 +301,8 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize) | |||
301 | if (!shost) | 301 | if (!shost) |
302 | return NULL; | 302 | return NULL; |
303 | 303 | ||
304 | spin_lock_init(&shost->default_lock); | 304 | shost->host_lock = &shost->default_lock; |
305 | scsi_assign_lock(shost, &shost->default_lock); | 305 | spin_lock_init(shost->host_lock); |
306 | shost->shost_state = SHOST_CREATED; | 306 | shost->shost_state = SHOST_CREATED; |
307 | INIT_LIST_HEAD(&shost->__devices); | 307 | INIT_LIST_HEAD(&shost->__devices); |
308 | INIT_LIST_HEAD(&shost->__targets); | 308 | INIT_LIST_HEAD(&shost->__targets); |
diff --git a/drivers/scsi/ips.c b/drivers/scsi/ips.c index f06a06ae6092..8b704f73055a 100644 --- a/drivers/scsi/ips.c +++ b/drivers/scsi/ips.c | |||
@@ -5001,7 +5001,7 @@ ips_init_copperhead(ips_ha_t * ha) | |||
5001 | break; | 5001 | break; |
5002 | 5002 | ||
5003 | /* Delay for 1 Second */ | 5003 | /* Delay for 1 Second */ |
5004 | msleep(IPS_ONE_SEC); | 5004 | MDELAY(IPS_ONE_SEC); |
5005 | } | 5005 | } |
5006 | 5006 | ||
5007 | if (j >= 45) | 5007 | if (j >= 45) |
@@ -5027,7 +5027,7 @@ ips_init_copperhead(ips_ha_t * ha) | |||
5027 | break; | 5027 | break; |
5028 | 5028 | ||
5029 | /* Delay for 1 Second */ | 5029 | /* Delay for 1 Second */ |
5030 | msleep(IPS_ONE_SEC); | 5030 | MDELAY(IPS_ONE_SEC); |
5031 | } | 5031 | } |
5032 | 5032 | ||
5033 | if (j >= 240) | 5033 | if (j >= 240) |
@@ -5045,7 +5045,7 @@ ips_init_copperhead(ips_ha_t * ha) | |||
5045 | break; | 5045 | break; |
5046 | 5046 | ||
5047 | /* Delay for 1 Second */ | 5047 | /* Delay for 1 Second */ |
5048 | msleep(IPS_ONE_SEC); | 5048 | MDELAY(IPS_ONE_SEC); |
5049 | } | 5049 | } |
5050 | 5050 | ||
5051 | if (i >= 240) | 5051 | if (i >= 240) |
@@ -5095,7 +5095,7 @@ ips_init_copperhead_memio(ips_ha_t * ha) | |||
5095 | break; | 5095 | break; |
5096 | 5096 | ||
5097 | /* Delay for 1 Second */ | 5097 | /* Delay for 1 Second */ |
5098 | msleep(IPS_ONE_SEC); | 5098 | MDELAY(IPS_ONE_SEC); |
5099 | } | 5099 | } |
5100 | 5100 | ||
5101 | if (j >= 45) | 5101 | if (j >= 45) |
@@ -5121,7 +5121,7 @@ ips_init_copperhead_memio(ips_ha_t * ha) | |||
5121 | break; | 5121 | break; |
5122 | 5122 | ||
5123 | /* Delay for 1 Second */ | 5123 | /* Delay for 1 Second */ |
5124 | msleep(IPS_ONE_SEC); | 5124 | MDELAY(IPS_ONE_SEC); |
5125 | } | 5125 | } |
5126 | 5126 | ||
5127 | if (j >= 240) | 5127 | if (j >= 240) |
@@ -5139,7 +5139,7 @@ ips_init_copperhead_memio(ips_ha_t * ha) | |||
5139 | break; | 5139 | break; |
5140 | 5140 | ||
5141 | /* Delay for 1 Second */ | 5141 | /* Delay for 1 Second */ |
5142 | msleep(IPS_ONE_SEC); | 5142 | MDELAY(IPS_ONE_SEC); |
5143 | } | 5143 | } |
5144 | 5144 | ||
5145 | if (i >= 240) | 5145 | if (i >= 240) |
@@ -5191,7 +5191,7 @@ ips_init_morpheus(ips_ha_t * ha) | |||
5191 | break; | 5191 | break; |
5192 | 5192 | ||
5193 | /* Delay for 1 Second */ | 5193 | /* Delay for 1 Second */ |
5194 | msleep(IPS_ONE_SEC); | 5194 | MDELAY(IPS_ONE_SEC); |
5195 | } | 5195 | } |
5196 | 5196 | ||
5197 | if (i >= 45) { | 5197 | if (i >= 45) { |
@@ -5217,7 +5217,7 @@ ips_init_morpheus(ips_ha_t * ha) | |||
5217 | if (Post != 0x4F00) | 5217 | if (Post != 0x4F00) |
5218 | break; | 5218 | break; |
5219 | /* Delay for 1 Second */ | 5219 | /* Delay for 1 Second */ |
5220 | msleep(IPS_ONE_SEC); | 5220 | MDELAY(IPS_ONE_SEC); |
5221 | } | 5221 | } |
5222 | 5222 | ||
5223 | if (i >= 120) { | 5223 | if (i >= 120) { |
@@ -5247,7 +5247,7 @@ ips_init_morpheus(ips_ha_t * ha) | |||
5247 | break; | 5247 | break; |
5248 | 5248 | ||
5249 | /* Delay for 1 Second */ | 5249 | /* Delay for 1 Second */ |
5250 | msleep(IPS_ONE_SEC); | 5250 | MDELAY(IPS_ONE_SEC); |
5251 | } | 5251 | } |
5252 | 5252 | ||
5253 | if (i >= 240) { | 5253 | if (i >= 240) { |
@@ -5307,12 +5307,12 @@ ips_reset_copperhead(ips_ha_t * ha) | |||
5307 | outb(IPS_BIT_RST, ha->io_addr + IPS_REG_SCPR); | 5307 | outb(IPS_BIT_RST, ha->io_addr + IPS_REG_SCPR); |
5308 | 5308 | ||
5309 | /* Delay for 1 Second */ | 5309 | /* Delay for 1 Second */ |
5310 | msleep(IPS_ONE_SEC); | 5310 | MDELAY(IPS_ONE_SEC); |
5311 | 5311 | ||
5312 | outb(0, ha->io_addr + IPS_REG_SCPR); | 5312 | outb(0, ha->io_addr + IPS_REG_SCPR); |
5313 | 5313 | ||
5314 | /* Delay for 1 Second */ | 5314 | /* Delay for 1 Second */ |
5315 | msleep(IPS_ONE_SEC); | 5315 | MDELAY(IPS_ONE_SEC); |
5316 | 5316 | ||
5317 | if ((*ha->func.init) (ha)) | 5317 | if ((*ha->func.init) (ha)) |
5318 | break; | 5318 | break; |
@@ -5352,12 +5352,12 @@ ips_reset_copperhead_memio(ips_ha_t * ha) | |||
5352 | writeb(IPS_BIT_RST, ha->mem_ptr + IPS_REG_SCPR); | 5352 | writeb(IPS_BIT_RST, ha->mem_ptr + IPS_REG_SCPR); |
5353 | 5353 | ||
5354 | /* Delay for 1 Second */ | 5354 | /* Delay for 1 Second */ |
5355 | msleep(IPS_ONE_SEC); | 5355 | MDELAY(IPS_ONE_SEC); |
5356 | 5356 | ||
5357 | writeb(0, ha->mem_ptr + IPS_REG_SCPR); | 5357 | writeb(0, ha->mem_ptr + IPS_REG_SCPR); |
5358 | 5358 | ||
5359 | /* Delay for 1 Second */ | 5359 | /* Delay for 1 Second */ |
5360 | msleep(IPS_ONE_SEC); | 5360 | MDELAY(IPS_ONE_SEC); |
5361 | 5361 | ||
5362 | if ((*ha->func.init) (ha)) | 5362 | if ((*ha->func.init) (ha)) |
5363 | break; | 5363 | break; |
@@ -5398,7 +5398,7 @@ ips_reset_morpheus(ips_ha_t * ha) | |||
5398 | writel(0x80000000, ha->mem_ptr + IPS_REG_I960_IDR); | 5398 | writel(0x80000000, ha->mem_ptr + IPS_REG_I960_IDR); |
5399 | 5399 | ||
5400 | /* Delay for 5 Seconds */ | 5400 | /* Delay for 5 Seconds */ |
5401 | msleep(5 * IPS_ONE_SEC); | 5401 | MDELAY(5 * IPS_ONE_SEC); |
5402 | 5402 | ||
5403 | /* Do a PCI config read to wait for adapter */ | 5403 | /* Do a PCI config read to wait for adapter */ |
5404 | pci_read_config_byte(ha->pcidev, 4, &junk); | 5404 | pci_read_config_byte(ha->pcidev, 4, &junk); |
diff --git a/drivers/scsi/ips.h b/drivers/scsi/ips.h index 34680f3dd452..b726dcc424b1 100644 --- a/drivers/scsi/ips.h +++ b/drivers/scsi/ips.h | |||
@@ -51,6 +51,7 @@ | |||
51 | #define _IPS_H_ | 51 | #define _IPS_H_ |
52 | 52 | ||
53 | #include <linux/version.h> | 53 | #include <linux/version.h> |
54 | #include <linux/nmi.h> | ||
54 | #include <asm/uaccess.h> | 55 | #include <asm/uaccess.h> |
55 | #include <asm/io.h> | 56 | #include <asm/io.h> |
56 | 57 | ||
@@ -116,9 +117,11 @@ | |||
116 | dev_printk(level , &((pcidev)->dev) , format , ## arg) | 117 | dev_printk(level , &((pcidev)->dev) , format , ## arg) |
117 | #endif | 118 | #endif |
118 | 119 | ||
119 | #ifndef MDELAY | 120 | #define MDELAY(n) \ |
120 | #define MDELAY mdelay | 121 | do { \ |
121 | #endif | 122 | mdelay(n); \ |
123 | touch_nmi_watchdog(); \ | ||
124 | } while (0) | ||
122 | 125 | ||
123 | #ifndef min | 126 | #ifndef min |
124 | #define min(x,y) ((x) < (y) ? x : y) | 127 | #define min(x,y) ((x) < (y) ? x : y) |
diff --git a/drivers/scsi/libsas/sas_init.c b/drivers/scsi/libsas/sas_init.c index c836a237fb79..0fb347b4b1a2 100644 --- a/drivers/scsi/libsas/sas_init.c +++ b/drivers/scsi/libsas/sas_init.c | |||
@@ -112,6 +112,8 @@ int sas_register_ha(struct sas_ha_struct *sas_ha) | |||
112 | } | 112 | } |
113 | } | 113 | } |
114 | 114 | ||
115 | INIT_LIST_HEAD(&sas_ha->eh_done_q); | ||
116 | |||
115 | return 0; | 117 | return 0; |
116 | 118 | ||
117 | Undo_ports: | 119 | Undo_ports: |
@@ -142,7 +144,7 @@ static int sas_get_linkerrors(struct sas_phy *phy) | |||
142 | return sas_smp_get_phy_events(phy); | 144 | return sas_smp_get_phy_events(phy); |
143 | } | 145 | } |
144 | 146 | ||
145 | static int sas_phy_reset(struct sas_phy *phy, int hard_reset) | 147 | int sas_phy_reset(struct sas_phy *phy, int hard_reset) |
146 | { | 148 | { |
147 | int ret; | 149 | int ret; |
148 | enum phy_func reset_type; | 150 | enum phy_func reset_type; |
diff --git a/drivers/scsi/libsas/sas_scsi_host.c b/drivers/scsi/libsas/sas_scsi_host.c index e46e79355b77..e064aac06b90 100644 --- a/drivers/scsi/libsas/sas_scsi_host.c +++ b/drivers/scsi/libsas/sas_scsi_host.c | |||
@@ -29,9 +29,11 @@ | |||
29 | #include <scsi/scsi_device.h> | 29 | #include <scsi/scsi_device.h> |
30 | #include <scsi/scsi_tcq.h> | 30 | #include <scsi/scsi_tcq.h> |
31 | #include <scsi/scsi.h> | 31 | #include <scsi/scsi.h> |
32 | #include <scsi/scsi_eh.h> | ||
32 | #include <scsi/scsi_transport.h> | 33 | #include <scsi/scsi_transport.h> |
33 | #include <scsi/scsi_transport_sas.h> | 34 | #include <scsi/scsi_transport_sas.h> |
34 | #include "../scsi_sas_internal.h" | 35 | #include "../scsi_sas_internal.h" |
36 | #include "../scsi_transport_api.h" | ||
35 | 37 | ||
36 | #include <linux/err.h> | 38 | #include <linux/err.h> |
37 | #include <linux/blkdev.h> | 39 | #include <linux/blkdev.h> |
@@ -46,6 +48,7 @@ static void sas_scsi_task_done(struct sas_task *task) | |||
46 | { | 48 | { |
47 | struct task_status_struct *ts = &task->task_status; | 49 | struct task_status_struct *ts = &task->task_status; |
48 | struct scsi_cmnd *sc = task->uldd_task; | 50 | struct scsi_cmnd *sc = task->uldd_task; |
51 | struct sas_ha_struct *sas_ha = SHOST_TO_SAS_HA(sc->device->host); | ||
49 | unsigned ts_flags = task->task_state_flags; | 52 | unsigned ts_flags = task->task_state_flags; |
50 | int hs = 0, stat = 0; | 53 | int hs = 0, stat = 0; |
51 | 54 | ||
@@ -116,7 +119,7 @@ static void sas_scsi_task_done(struct sas_task *task) | |||
116 | sas_free_task(task); | 119 | sas_free_task(task); |
117 | /* This is very ugly but this is how SCSI Core works. */ | 120 | /* This is very ugly but this is how SCSI Core works. */ |
118 | if (ts_flags & SAS_TASK_STATE_ABORTED) | 121 | if (ts_flags & SAS_TASK_STATE_ABORTED) |
119 | scsi_finish_command(sc); | 122 | scsi_eh_finish_cmd(sc, &sas_ha->eh_done_q); |
120 | else | 123 | else |
121 | sc->scsi_done(sc); | 124 | sc->scsi_done(sc); |
122 | } | 125 | } |
@@ -307,6 +310,15 @@ static enum task_disposition sas_scsi_find_task(struct sas_task *task) | |||
307 | spin_unlock_irqrestore(&core->task_queue_lock, flags); | 310 | spin_unlock_irqrestore(&core->task_queue_lock, flags); |
308 | } | 311 | } |
309 | 312 | ||
313 | spin_lock_irqsave(&task->task_state_lock, flags); | ||
314 | if (task->task_state_flags & SAS_TASK_INITIATOR_ABORTED) { | ||
315 | spin_unlock_irqrestore(&task->task_state_lock, flags); | ||
316 | SAS_DPRINTK("%s: task 0x%p already aborted\n", | ||
317 | __FUNCTION__, task); | ||
318 | return TASK_IS_ABORTED; | ||
319 | } | ||
320 | spin_unlock_irqrestore(&task->task_state_lock, flags); | ||
321 | |||
310 | for (i = 0; i < 5; i++) { | 322 | for (i = 0; i < 5; i++) { |
311 | SAS_DPRINTK("%s: aborting task 0x%p\n", __FUNCTION__, task); | 323 | SAS_DPRINTK("%s: aborting task 0x%p\n", __FUNCTION__, task); |
312 | res = si->dft->lldd_abort_task(task); | 324 | res = si->dft->lldd_abort_task(task); |
@@ -409,13 +421,16 @@ Again: | |||
409 | SAS_DPRINTK("going over list...\n"); | 421 | SAS_DPRINTK("going over list...\n"); |
410 | list_for_each_entry_safe(cmd, n, &error_q, eh_entry) { | 422 | list_for_each_entry_safe(cmd, n, &error_q, eh_entry) { |
411 | struct sas_task *task = TO_SAS_TASK(cmd); | 423 | struct sas_task *task = TO_SAS_TASK(cmd); |
424 | list_del_init(&cmd->eh_entry); | ||
412 | 425 | ||
426 | if (!task) { | ||
427 | SAS_DPRINTK("%s: taskless cmd?!\n", __FUNCTION__); | ||
428 | continue; | ||
429 | } | ||
413 | SAS_DPRINTK("trying to find task 0x%p\n", task); | 430 | SAS_DPRINTK("trying to find task 0x%p\n", task); |
414 | list_del_init(&cmd->eh_entry); | ||
415 | res = sas_scsi_find_task(task); | 431 | res = sas_scsi_find_task(task); |
416 | 432 | ||
417 | cmd->eh_eflags = 0; | 433 | cmd->eh_eflags = 0; |
418 | shost->host_failed--; | ||
419 | 434 | ||
420 | switch (res) { | 435 | switch (res) { |
421 | case TASK_IS_DONE: | 436 | case TASK_IS_DONE: |
@@ -491,6 +506,7 @@ Again: | |||
491 | } | 506 | } |
492 | } | 507 | } |
493 | out: | 508 | out: |
509 | scsi_eh_flush_done_q(&ha->eh_done_q); | ||
494 | SAS_DPRINTK("--- Exit %s\n", __FUNCTION__); | 510 | SAS_DPRINTK("--- Exit %s\n", __FUNCTION__); |
495 | return; | 511 | return; |
496 | clear_q: | 512 | clear_q: |
@@ -508,12 +524,18 @@ enum scsi_eh_timer_return sas_scsi_timed_out(struct scsi_cmnd *cmd) | |||
508 | unsigned long flags; | 524 | unsigned long flags; |
509 | 525 | ||
510 | if (!task) { | 526 | if (!task) { |
511 | SAS_DPRINTK("command 0x%p, task 0x%p, timed out: EH_HANDLED\n", | 527 | SAS_DPRINTK("command 0x%p, task 0x%p, gone: EH_HANDLED\n", |
512 | cmd, task); | 528 | cmd, task); |
513 | return EH_HANDLED; | 529 | return EH_HANDLED; |
514 | } | 530 | } |
515 | 531 | ||
516 | spin_lock_irqsave(&task->task_state_lock, flags); | 532 | spin_lock_irqsave(&task->task_state_lock, flags); |
533 | if (task->task_state_flags & SAS_TASK_INITIATOR_ABORTED) { | ||
534 | spin_unlock_irqrestore(&task->task_state_lock, flags); | ||
535 | SAS_DPRINTK("command 0x%p, task 0x%p, aborted by initiator: " | ||
536 | "EH_NOT_HANDLED\n", cmd, task); | ||
537 | return EH_NOT_HANDLED; | ||
538 | } | ||
517 | if (task->task_state_flags & SAS_TASK_STATE_DONE) { | 539 | if (task->task_state_flags & SAS_TASK_STATE_DONE) { |
518 | spin_unlock_irqrestore(&task->task_state_lock, flags); | 540 | spin_unlock_irqrestore(&task->task_state_lock, flags); |
519 | SAS_DPRINTK("command 0x%p, task 0x%p, timed out: EH_HANDLED\n", | 541 | SAS_DPRINTK("command 0x%p, task 0x%p, timed out: EH_HANDLED\n", |
@@ -777,6 +799,64 @@ void sas_shutdown_queue(struct sas_ha_struct *sas_ha) | |||
777 | spin_unlock_irqrestore(&core->task_queue_lock, flags); | 799 | spin_unlock_irqrestore(&core->task_queue_lock, flags); |
778 | } | 800 | } |
779 | 801 | ||
802 | static int do_sas_task_abort(struct sas_task *task) | ||
803 | { | ||
804 | struct scsi_cmnd *sc = task->uldd_task; | ||
805 | struct sas_internal *si = | ||
806 | to_sas_internal(task->dev->port->ha->core.shost->transportt); | ||
807 | unsigned long flags; | ||
808 | int res; | ||
809 | |||
810 | spin_lock_irqsave(&task->task_state_lock, flags); | ||
811 | if (task->task_state_flags & SAS_TASK_STATE_ABORTED) { | ||
812 | spin_unlock_irqrestore(&task->task_state_lock, flags); | ||
813 | SAS_DPRINTK("%s: Task %p already aborted.\n", __FUNCTION__, | ||
814 | task); | ||
815 | return 0; | ||
816 | } | ||
817 | |||
818 | task->task_state_flags |= SAS_TASK_INITIATOR_ABORTED; | ||
819 | if (!(task->task_state_flags & SAS_TASK_STATE_DONE)) | ||
820 | task->task_state_flags |= SAS_TASK_STATE_ABORTED; | ||
821 | spin_unlock_irqrestore(&task->task_state_lock, flags); | ||
822 | |||
823 | if (!si->dft->lldd_abort_task) | ||
824 | return -ENODEV; | ||
825 | |||
826 | res = si->dft->lldd_abort_task(task); | ||
827 | if ((task->task_state_flags & SAS_TASK_STATE_DONE) || | ||
828 | (res == TMF_RESP_FUNC_COMPLETE)) | ||
829 | { | ||
830 | /* SMP commands don't have scsi_cmds(?) */ | ||
831 | if (!sc) { | ||
832 | task->task_done(task); | ||
833 | return 0; | ||
834 | } | ||
835 | scsi_req_abort_cmd(sc); | ||
836 | scsi_schedule_eh(sc->device->host); | ||
837 | return 0; | ||
838 | } | ||
839 | |||
840 | spin_lock_irqsave(&task->task_state_lock, flags); | ||
841 | task->task_state_flags &= ~SAS_TASK_INITIATOR_ABORTED; | ||
842 | if (!(task->task_state_flags & SAS_TASK_STATE_DONE)) | ||
843 | task->task_state_flags &= ~SAS_TASK_STATE_ABORTED; | ||
844 | spin_unlock_irqrestore(&task->task_state_lock, flags); | ||
845 | |||
846 | return -EAGAIN; | ||
847 | } | ||
848 | |||
849 | void sas_task_abort(struct sas_task *task) | ||
850 | { | ||
851 | int i; | ||
852 | |||
853 | for (i = 0; i < 5; i++) | ||
854 | if (!do_sas_task_abort(task)) | ||
855 | return; | ||
856 | |||
857 | SAS_DPRINTK("%s: Could not kill task!\n", __FUNCTION__); | ||
858 | } | ||
859 | |||
780 | EXPORT_SYMBOL_GPL(sas_queuecommand); | 860 | EXPORT_SYMBOL_GPL(sas_queuecommand); |
781 | EXPORT_SYMBOL_GPL(sas_target_alloc); | 861 | EXPORT_SYMBOL_GPL(sas_target_alloc); |
782 | EXPORT_SYMBOL_GPL(sas_slave_configure); | 862 | EXPORT_SYMBOL_GPL(sas_slave_configure); |
@@ -784,3 +864,5 @@ EXPORT_SYMBOL_GPL(sas_slave_destroy); | |||
784 | EXPORT_SYMBOL_GPL(sas_change_queue_depth); | 864 | EXPORT_SYMBOL_GPL(sas_change_queue_depth); |
785 | EXPORT_SYMBOL_GPL(sas_change_queue_type); | 865 | EXPORT_SYMBOL_GPL(sas_change_queue_type); |
786 | EXPORT_SYMBOL_GPL(sas_bios_param); | 866 | EXPORT_SYMBOL_GPL(sas_bios_param); |
867 | EXPORT_SYMBOL_GPL(sas_task_abort); | ||
868 | EXPORT_SYMBOL_GPL(sas_phy_reset); | ||
diff --git a/drivers/scsi/ncr53c8xx.c b/drivers/scsi/ncr53c8xx.c index 6cc2bc2f62be..5a88fa0b2fc3 100644 --- a/drivers/scsi/ncr53c8xx.c +++ b/drivers/scsi/ncr53c8xx.c | |||
@@ -589,10 +589,12 @@ static int __map_scsi_sg_data(struct device *dev, struct scsi_cmnd *cmd) | |||
589 | static struct ncr_driver_setup | 589 | static struct ncr_driver_setup |
590 | driver_setup = SCSI_NCR_DRIVER_SETUP; | 590 | driver_setup = SCSI_NCR_DRIVER_SETUP; |
591 | 591 | ||
592 | #ifndef MODULE | ||
592 | #ifdef SCSI_NCR_BOOT_COMMAND_LINE_SUPPORT | 593 | #ifdef SCSI_NCR_BOOT_COMMAND_LINE_SUPPORT |
593 | static struct ncr_driver_setup | 594 | static struct ncr_driver_setup |
594 | driver_safe_setup __initdata = SCSI_NCR_DRIVER_SAFE_SETUP; | 595 | driver_safe_setup __initdata = SCSI_NCR_DRIVER_SAFE_SETUP; |
595 | #endif | 596 | #endif |
597 | #endif /* !MODULE */ | ||
596 | 598 | ||
597 | #define initverbose (driver_setup.verbose) | 599 | #define initverbose (driver_setup.verbose) |
598 | #define bootverbose (np->verbose) | 600 | #define bootverbose (np->verbose) |
@@ -641,6 +643,13 @@ static struct ncr_driver_setup | |||
641 | #define OPT_IARB 26 | 643 | #define OPT_IARB 26 |
642 | #endif | 644 | #endif |
643 | 645 | ||
646 | #ifdef MODULE | ||
647 | #define ARG_SEP ' ' | ||
648 | #else | ||
649 | #define ARG_SEP ',' | ||
650 | #endif | ||
651 | |||
652 | #ifndef MODULE | ||
644 | static char setup_token[] __initdata = | 653 | static char setup_token[] __initdata = |
645 | "tags:" "mpar:" | 654 | "tags:" "mpar:" |
646 | "spar:" "disc:" | 655 | "spar:" "disc:" |
@@ -660,12 +669,6 @@ static char setup_token[] __initdata = | |||
660 | #endif | 669 | #endif |
661 | ; /* DONNOT REMOVE THIS ';' */ | 670 | ; /* DONNOT REMOVE THIS ';' */ |
662 | 671 | ||
663 | #ifdef MODULE | ||
664 | #define ARG_SEP ' ' | ||
665 | #else | ||
666 | #define ARG_SEP ',' | ||
667 | #endif | ||
668 | |||
669 | static int __init get_setup_token(char *p) | 672 | static int __init get_setup_token(char *p) |
670 | { | 673 | { |
671 | char *cur = setup_token; | 674 | char *cur = setup_token; |
@@ -682,7 +685,6 @@ static int __init get_setup_token(char *p) | |||
682 | return 0; | 685 | return 0; |
683 | } | 686 | } |
684 | 687 | ||
685 | |||
686 | static int __init sym53c8xx__setup(char *str) | 688 | static int __init sym53c8xx__setup(char *str) |
687 | { | 689 | { |
688 | #ifdef SCSI_NCR_BOOT_COMMAND_LINE_SUPPORT | 690 | #ifdef SCSI_NCR_BOOT_COMMAND_LINE_SUPPORT |
@@ -804,6 +806,7 @@ static int __init sym53c8xx__setup(char *str) | |||
804 | #endif /* SCSI_NCR_BOOT_COMMAND_LINE_SUPPORT */ | 806 | #endif /* SCSI_NCR_BOOT_COMMAND_LINE_SUPPORT */ |
805 | return 1; | 807 | return 1; |
806 | } | 808 | } |
809 | #endif /* !MODULE */ | ||
807 | 810 | ||
808 | /*=================================================================== | 811 | /*=================================================================== |
809 | ** | 812 | ** |
@@ -8321,12 +8324,12 @@ char *ncr53c8xx; /* command line passed by insmod */ | |||
8321 | module_param(ncr53c8xx, charp, 0); | 8324 | module_param(ncr53c8xx, charp, 0); |
8322 | #endif | 8325 | #endif |
8323 | 8326 | ||
8327 | #ifndef MODULE | ||
8324 | static int __init ncr53c8xx_setup(char *str) | 8328 | static int __init ncr53c8xx_setup(char *str) |
8325 | { | 8329 | { |
8326 | return sym53c8xx__setup(str); | 8330 | return sym53c8xx__setup(str); |
8327 | } | 8331 | } |
8328 | 8332 | ||
8329 | #ifndef MODULE | ||
8330 | __setup("ncr53c8xx=", ncr53c8xx_setup); | 8333 | __setup("ncr53c8xx=", ncr53c8xx_setup); |
8331 | #endif | 8334 | #endif |
8332 | 8335 | ||
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 208607be78c7..3eb4cd2cbc78 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c | |||
@@ -287,7 +287,7 @@ qla24xx_pci_info_str(struct scsi_qla_host *ha, char *str) | |||
287 | return str; | 287 | return str; |
288 | } | 288 | } |
289 | 289 | ||
290 | char * | 290 | static char * |
291 | qla2x00_fw_version_str(struct scsi_qla_host *ha, char *str) | 291 | qla2x00_fw_version_str(struct scsi_qla_host *ha, char *str) |
292 | { | 292 | { |
293 | char un_str[10]; | 293 | char un_str[10]; |
@@ -325,7 +325,7 @@ qla2x00_fw_version_str(struct scsi_qla_host *ha, char *str) | |||
325 | return (str); | 325 | return (str); |
326 | } | 326 | } |
327 | 327 | ||
328 | char * | 328 | static char * |
329 | qla24xx_fw_version_str(struct scsi_qla_host *ha, char *str) | 329 | qla24xx_fw_version_str(struct scsi_qla_host *ha, char *str) |
330 | { | 330 | { |
331 | sprintf(str, "%d.%02d.%02d ", ha->fw_major_version, | 331 | sprintf(str, "%d.%02d.%02d ", ha->fw_major_version, |
@@ -634,7 +634,7 @@ qla2x00_block_error_handler(struct scsi_cmnd *cmnd) | |||
634 | * Note: | 634 | * Note: |
635 | * Only return FAILED if command not returned by firmware. | 635 | * Only return FAILED if command not returned by firmware. |
636 | **************************************************************************/ | 636 | **************************************************************************/ |
637 | int | 637 | static int |
638 | qla2xxx_eh_abort(struct scsi_cmnd *cmd) | 638 | qla2xxx_eh_abort(struct scsi_cmnd *cmd) |
639 | { | 639 | { |
640 | scsi_qla_host_t *ha = to_qla_host(cmd->device->host); | 640 | scsi_qla_host_t *ha = to_qla_host(cmd->device->host); |
@@ -771,7 +771,7 @@ qla2x00_eh_wait_for_pending_target_commands(scsi_qla_host_t *ha, unsigned int t) | |||
771 | * SUCCESS/FAILURE (defined as macro in scsi.h). | 771 | * SUCCESS/FAILURE (defined as macro in scsi.h). |
772 | * | 772 | * |
773 | **************************************************************************/ | 773 | **************************************************************************/ |
774 | int | 774 | static int |
775 | qla2xxx_eh_device_reset(struct scsi_cmnd *cmd) | 775 | qla2xxx_eh_device_reset(struct scsi_cmnd *cmd) |
776 | { | 776 | { |
777 | scsi_qla_host_t *ha = to_qla_host(cmd->device->host); | 777 | scsi_qla_host_t *ha = to_qla_host(cmd->device->host); |
@@ -902,7 +902,7 @@ qla2x00_eh_wait_for_pending_commands(scsi_qla_host_t *ha) | |||
902 | * SUCCESS/FAILURE (defined as macro in scsi.h). | 902 | * SUCCESS/FAILURE (defined as macro in scsi.h). |
903 | * | 903 | * |
904 | **************************************************************************/ | 904 | **************************************************************************/ |
905 | int | 905 | static int |
906 | qla2xxx_eh_bus_reset(struct scsi_cmnd *cmd) | 906 | qla2xxx_eh_bus_reset(struct scsi_cmnd *cmd) |
907 | { | 907 | { |
908 | scsi_qla_host_t *ha = to_qla_host(cmd->device->host); | 908 | scsi_qla_host_t *ha = to_qla_host(cmd->device->host); |
@@ -963,7 +963,7 @@ eh_bus_reset_done: | |||
963 | * | 963 | * |
964 | * Note: | 964 | * Note: |
965 | **************************************************************************/ | 965 | **************************************************************************/ |
966 | int | 966 | static int |
967 | qla2xxx_eh_host_reset(struct scsi_cmnd *cmd) | 967 | qla2xxx_eh_host_reset(struct scsi_cmnd *cmd) |
968 | { | 968 | { |
969 | scsi_qla_host_t *ha = to_qla_host(cmd->device->host); | 969 | scsi_qla_host_t *ha = to_qla_host(cmd->device->host); |
diff --git a/drivers/scsi/qla2xxx/qla_sup.c b/drivers/scsi/qla2xxx/qla_sup.c index c71dbd5bd543..15390ad87456 100644 --- a/drivers/scsi/qla2xxx/qla_sup.c +++ b/drivers/scsi/qla2xxx/qla_sup.c | |||
@@ -449,7 +449,7 @@ nvram_data_to_access_addr(uint32_t naddr) | |||
449 | return FARX_ACCESS_NVRAM_DATA | naddr; | 449 | return FARX_ACCESS_NVRAM_DATA | naddr; |
450 | } | 450 | } |
451 | 451 | ||
452 | uint32_t | 452 | static uint32_t |
453 | qla24xx_read_flash_dword(scsi_qla_host_t *ha, uint32_t addr) | 453 | qla24xx_read_flash_dword(scsi_qla_host_t *ha, uint32_t addr) |
454 | { | 454 | { |
455 | int rval; | 455 | int rval; |
@@ -490,7 +490,7 @@ qla24xx_read_flash_data(scsi_qla_host_t *ha, uint32_t *dwptr, uint32_t faddr, | |||
490 | return dwptr; | 490 | return dwptr; |
491 | } | 491 | } |
492 | 492 | ||
493 | int | 493 | static int |
494 | qla24xx_write_flash_dword(scsi_qla_host_t *ha, uint32_t addr, uint32_t data) | 494 | qla24xx_write_flash_dword(scsi_qla_host_t *ha, uint32_t addr, uint32_t data) |
495 | { | 495 | { |
496 | int rval; | 496 | int rval; |
@@ -512,7 +512,7 @@ qla24xx_write_flash_dword(scsi_qla_host_t *ha, uint32_t addr, uint32_t data) | |||
512 | return rval; | 512 | return rval; |
513 | } | 513 | } |
514 | 514 | ||
515 | void | 515 | static void |
516 | qla24xx_get_flash_manufacturer(scsi_qla_host_t *ha, uint8_t *man_id, | 516 | qla24xx_get_flash_manufacturer(scsi_qla_host_t *ha, uint8_t *man_id, |
517 | uint8_t *flash_id) | 517 | uint8_t *flash_id) |
518 | { | 518 | { |
@@ -537,7 +537,7 @@ qla24xx_get_flash_manufacturer(scsi_qla_host_t *ha, uint8_t *man_id, | |||
537 | } | 537 | } |
538 | } | 538 | } |
539 | 539 | ||
540 | int | 540 | static int |
541 | qla24xx_write_flash_data(scsi_qla_host_t *ha, uint32_t *dwptr, uint32_t faddr, | 541 | qla24xx_write_flash_data(scsi_qla_host_t *ha, uint32_t *dwptr, uint32_t faddr, |
542 | uint32_t dwords) | 542 | uint32_t dwords) |
543 | { | 543 | { |
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index c59f31533ab4..780d6dc92b42 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c | |||
@@ -871,9 +871,9 @@ EXPORT_SYMBOL(scsi_device_get); | |||
871 | */ | 871 | */ |
872 | void scsi_device_put(struct scsi_device *sdev) | 872 | void scsi_device_put(struct scsi_device *sdev) |
873 | { | 873 | { |
874 | #ifdef CONFIG_MODULE_UNLOAD | ||
874 | struct module *module = sdev->host->hostt->module; | 875 | struct module *module = sdev->host->hostt->module; |
875 | 876 | ||
876 | #ifdef CONFIG_MODULE_UNLOAD | ||
877 | /* The module refcount will be zero if scsi_device_get() | 877 | /* The module refcount will be zero if scsi_device_get() |
878 | * was called from a module removal routine */ | 878 | * was called from a module removal routine */ |
879 | if (module && module_refcount(module) != 0) | 879 | if (module && module_refcount(module) != 0) |
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index aff1b0cfd4b2..2ecb6ff42444 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c | |||
@@ -453,9 +453,18 @@ static void scsi_eh_done(struct scsi_cmnd *scmd) | |||
453 | } | 453 | } |
454 | 454 | ||
455 | /** | 455 | /** |
456 | * scsi_send_eh_cmnd - send a cmd to a device as part of error recovery. | 456 | * scsi_send_eh_cmnd - submit a scsi command as part of error recory |
457 | * @scmd: SCSI Cmd to send. | 457 | * @scmd: SCSI command structure to hijack |
458 | * @timeout: Timeout for cmd. | 458 | * @cmnd: CDB to send |
459 | * @cmnd_size: size in bytes of @cmnd | ||
460 | * @timeout: timeout for this request | ||
461 | * @copy_sense: request sense data if set to 1 | ||
462 | * | ||
463 | * This function is used to send a scsi command down to a target device | ||
464 | * as part of the error recovery process. If @copy_sense is 0 the command | ||
465 | * sent must be one that does not transfer any data. If @copy_sense is 1 | ||
466 | * the command must be REQUEST_SENSE and this functions copies out the | ||
467 | * sense buffer it got into @scmd->sense_buffer. | ||
459 | * | 468 | * |
460 | * Return value: | 469 | * Return value: |
461 | * SUCCESS or FAILED or NEEDS_RETRY | 470 | * SUCCESS or FAILED or NEEDS_RETRY |
@@ -469,6 +478,7 @@ static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, unsigned char *cmnd, | |||
469 | DECLARE_COMPLETION_ONSTACK(done); | 478 | DECLARE_COMPLETION_ONSTACK(done); |
470 | unsigned long timeleft; | 479 | unsigned long timeleft; |
471 | unsigned long flags; | 480 | unsigned long flags; |
481 | struct scatterlist sgl; | ||
472 | unsigned char old_cmnd[MAX_COMMAND_SIZE]; | 482 | unsigned char old_cmnd[MAX_COMMAND_SIZE]; |
473 | enum dma_data_direction old_data_direction; | 483 | enum dma_data_direction old_data_direction; |
474 | unsigned short old_use_sg; | 484 | unsigned short old_use_sg; |
@@ -500,19 +510,24 @@ static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, unsigned char *cmnd, | |||
500 | if (shost->hostt->unchecked_isa_dma) | 510 | if (shost->hostt->unchecked_isa_dma) |
501 | gfp_mask |= __GFP_DMA; | 511 | gfp_mask |= __GFP_DMA; |
502 | 512 | ||
503 | scmd->sc_data_direction = DMA_FROM_DEVICE; | 513 | sgl.page = alloc_page(gfp_mask); |
504 | scmd->request_bufflen = 252; | 514 | if (!sgl.page) |
505 | scmd->request_buffer = kzalloc(scmd->request_bufflen, gfp_mask); | ||
506 | if (!scmd->request_buffer) | ||
507 | return FAILED; | 515 | return FAILED; |
516 | sgl.offset = 0; | ||
517 | sgl.length = 252; | ||
518 | |||
519 | scmd->sc_data_direction = DMA_FROM_DEVICE; | ||
520 | scmd->request_bufflen = sgl.length; | ||
521 | scmd->request_buffer = &sgl; | ||
522 | scmd->use_sg = 1; | ||
508 | } else { | 523 | } else { |
509 | scmd->request_buffer = NULL; | 524 | scmd->request_buffer = NULL; |
510 | scmd->request_bufflen = 0; | 525 | scmd->request_bufflen = 0; |
511 | scmd->sc_data_direction = DMA_NONE; | 526 | scmd->sc_data_direction = DMA_NONE; |
527 | scmd->use_sg = 0; | ||
512 | } | 528 | } |
513 | 529 | ||
514 | scmd->underflow = 0; | 530 | scmd->underflow = 0; |
515 | scmd->use_sg = 0; | ||
516 | scmd->cmd_len = COMMAND_SIZE(scmd->cmnd[0]); | 531 | scmd->cmd_len = COMMAND_SIZE(scmd->cmnd[0]); |
517 | 532 | ||
518 | if (sdev->scsi_level <= SCSI_2) | 533 | if (sdev->scsi_level <= SCSI_2) |
@@ -583,7 +598,7 @@ static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, unsigned char *cmnd, | |||
583 | memcpy(scmd->sense_buffer, scmd->request_buffer, | 598 | memcpy(scmd->sense_buffer, scmd->request_buffer, |
584 | sizeof(scmd->sense_buffer)); | 599 | sizeof(scmd->sense_buffer)); |
585 | } | 600 | } |
586 | kfree(scmd->request_buffer); | 601 | __free_page(sgl.page); |
587 | } | 602 | } |
588 | 603 | ||
589 | 604 | ||
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 3ac4890ce086..2f12f9f12fcb 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c | |||
@@ -996,25 +996,14 @@ static int scsi_init_io(struct scsi_cmnd *cmd) | |||
996 | int count; | 996 | int count; |
997 | 997 | ||
998 | /* | 998 | /* |
999 | * if this is a rq->data based REQ_BLOCK_PC, setup for a non-sg xfer | 999 | * We used to not use scatter-gather for single segment request, |
1000 | */ | ||
1001 | if (blk_pc_request(req) && !req->bio) { | ||
1002 | cmd->request_bufflen = req->data_len; | ||
1003 | cmd->request_buffer = req->data; | ||
1004 | req->buffer = req->data; | ||
1005 | cmd->use_sg = 0; | ||
1006 | return 0; | ||
1007 | } | ||
1008 | |||
1009 | /* | ||
1010 | * we used to not use scatter-gather for single segment request, | ||
1011 | * but now we do (it makes highmem I/O easier to support without | 1000 | * but now we do (it makes highmem I/O easier to support without |
1012 | * kmapping pages) | 1001 | * kmapping pages) |
1013 | */ | 1002 | */ |
1014 | cmd->use_sg = req->nr_phys_segments; | 1003 | cmd->use_sg = req->nr_phys_segments; |
1015 | 1004 | ||
1016 | /* | 1005 | /* |
1017 | * if sg table allocation fails, requeue request later. | 1006 | * If sg table allocation fails, requeue request later. |
1018 | */ | 1007 | */ |
1019 | sgpnt = scsi_alloc_sgtable(cmd, GFP_ATOMIC); | 1008 | sgpnt = scsi_alloc_sgtable(cmd, GFP_ATOMIC); |
1020 | if (unlikely(!sgpnt)) { | 1009 | if (unlikely(!sgpnt)) { |
@@ -1022,24 +1011,21 @@ static int scsi_init_io(struct scsi_cmnd *cmd) | |||
1022 | return BLKPREP_DEFER; | 1011 | return BLKPREP_DEFER; |
1023 | } | 1012 | } |
1024 | 1013 | ||
1014 | req->buffer = NULL; | ||
1025 | cmd->request_buffer = (char *) sgpnt; | 1015 | cmd->request_buffer = (char *) sgpnt; |
1026 | cmd->request_bufflen = req->nr_sectors << 9; | ||
1027 | if (blk_pc_request(req)) | 1016 | if (blk_pc_request(req)) |
1028 | cmd->request_bufflen = req->data_len; | 1017 | cmd->request_bufflen = req->data_len; |
1029 | req->buffer = NULL; | 1018 | else |
1019 | cmd->request_bufflen = req->nr_sectors << 9; | ||
1030 | 1020 | ||
1031 | /* | 1021 | /* |
1032 | * Next, walk the list, and fill in the addresses and sizes of | 1022 | * Next, walk the list, and fill in the addresses and sizes of |
1033 | * each segment. | 1023 | * each segment. |
1034 | */ | 1024 | */ |
1035 | count = blk_rq_map_sg(req->q, req, cmd->request_buffer); | 1025 | count = blk_rq_map_sg(req->q, req, cmd->request_buffer); |
1036 | |||
1037 | /* | ||
1038 | * mapped well, send it off | ||
1039 | */ | ||
1040 | if (likely(count <= cmd->use_sg)) { | 1026 | if (likely(count <= cmd->use_sg)) { |
1041 | cmd->use_sg = count; | 1027 | cmd->use_sg = count; |
1042 | return 0; | 1028 | return BLKPREP_OK; |
1043 | } | 1029 | } |
1044 | 1030 | ||
1045 | printk(KERN_ERR "Incorrect number of segments after building list\n"); | 1031 | printk(KERN_ERR "Incorrect number of segments after building list\n"); |
@@ -1069,6 +1055,27 @@ static int scsi_issue_flush_fn(request_queue_t *q, struct gendisk *disk, | |||
1069 | return -EOPNOTSUPP; | 1055 | return -EOPNOTSUPP; |
1070 | } | 1056 | } |
1071 | 1057 | ||
1058 | static struct scsi_cmnd *scsi_get_cmd_from_req(struct scsi_device *sdev, | ||
1059 | struct request *req) | ||
1060 | { | ||
1061 | struct scsi_cmnd *cmd; | ||
1062 | |||
1063 | if (!req->special) { | ||
1064 | cmd = scsi_get_command(sdev, GFP_ATOMIC); | ||
1065 | if (unlikely(!cmd)) | ||
1066 | return NULL; | ||
1067 | req->special = cmd; | ||
1068 | } else { | ||
1069 | cmd = req->special; | ||
1070 | } | ||
1071 | |||
1072 | /* pull a tag out of the request if we have one */ | ||
1073 | cmd->tag = req->tag; | ||
1074 | cmd->request = req; | ||
1075 | |||
1076 | return cmd; | ||
1077 | } | ||
1078 | |||
1072 | static void scsi_blk_pc_done(struct scsi_cmnd *cmd) | 1079 | static void scsi_blk_pc_done(struct scsi_cmnd *cmd) |
1073 | { | 1080 | { |
1074 | BUG_ON(!blk_pc_request(cmd->request)); | 1081 | BUG_ON(!blk_pc_request(cmd->request)); |
@@ -1081,9 +1088,37 @@ static void scsi_blk_pc_done(struct scsi_cmnd *cmd) | |||
1081 | scsi_io_completion(cmd, cmd->request_bufflen); | 1088 | scsi_io_completion(cmd, cmd->request_bufflen); |
1082 | } | 1089 | } |
1083 | 1090 | ||
1084 | static void scsi_setup_blk_pc_cmnd(struct scsi_cmnd *cmd) | 1091 | static int scsi_setup_blk_pc_cmnd(struct scsi_device *sdev, struct request *req) |
1085 | { | 1092 | { |
1086 | struct request *req = cmd->request; | 1093 | struct scsi_cmnd *cmd; |
1094 | |||
1095 | cmd = scsi_get_cmd_from_req(sdev, req); | ||
1096 | if (unlikely(!cmd)) | ||
1097 | return BLKPREP_DEFER; | ||
1098 | |||
1099 | /* | ||
1100 | * BLOCK_PC requests may transfer data, in which case they must | ||
1101 | * a bio attached to them. Or they might contain a SCSI command | ||
1102 | * that does not transfer data, in which case they may optionally | ||
1103 | * submit a request without an attached bio. | ||
1104 | */ | ||
1105 | if (req->bio) { | ||
1106 | int ret; | ||
1107 | |||
1108 | BUG_ON(!req->nr_phys_segments); | ||
1109 | |||
1110 | ret = scsi_init_io(cmd); | ||
1111 | if (unlikely(ret)) | ||
1112 | return ret; | ||
1113 | } else { | ||
1114 | BUG_ON(req->data_len); | ||
1115 | BUG_ON(req->data); | ||
1116 | |||
1117 | cmd->request_bufflen = 0; | ||
1118 | cmd->request_buffer = NULL; | ||
1119 | cmd->use_sg = 0; | ||
1120 | req->buffer = NULL; | ||
1121 | } | ||
1087 | 1122 | ||
1088 | BUILD_BUG_ON(sizeof(req->cmd) > sizeof(cmd->cmnd)); | 1123 | BUILD_BUG_ON(sizeof(req->cmd) > sizeof(cmd->cmnd)); |
1089 | memcpy(cmd->cmnd, req->cmd, sizeof(cmd->cmnd)); | 1124 | memcpy(cmd->cmnd, req->cmd, sizeof(cmd->cmnd)); |
@@ -1099,154 +1134,138 @@ static void scsi_setup_blk_pc_cmnd(struct scsi_cmnd *cmd) | |||
1099 | cmd->allowed = req->retries; | 1134 | cmd->allowed = req->retries; |
1100 | cmd->timeout_per_command = req->timeout; | 1135 | cmd->timeout_per_command = req->timeout; |
1101 | cmd->done = scsi_blk_pc_done; | 1136 | cmd->done = scsi_blk_pc_done; |
1137 | return BLKPREP_OK; | ||
1102 | } | 1138 | } |
1103 | 1139 | ||
1104 | static int scsi_prep_fn(struct request_queue *q, struct request *req) | 1140 | /* |
1141 | * Setup a REQ_TYPE_FS command. These are simple read/write request | ||
1142 | * from filesystems that still need to be translated to SCSI CDBs from | ||
1143 | * the ULD. | ||
1144 | */ | ||
1145 | static int scsi_setup_fs_cmnd(struct scsi_device *sdev, struct request *req) | ||
1105 | { | 1146 | { |
1106 | struct scsi_device *sdev = q->queuedata; | ||
1107 | struct scsi_cmnd *cmd; | 1147 | struct scsi_cmnd *cmd; |
1108 | int specials_only = 0; | 1148 | struct scsi_driver *drv; |
1149 | int ret; | ||
1109 | 1150 | ||
1110 | /* | 1151 | /* |
1111 | * Just check to see if the device is online. If it isn't, we | 1152 | * Filesystem requests must transfer data. |
1112 | * refuse to process any commands. The device must be brought | ||
1113 | * online before trying any recovery commands | ||
1114 | */ | 1153 | */ |
1115 | if (unlikely(!scsi_device_online(sdev))) { | 1154 | BUG_ON(!req->nr_phys_segments); |
1116 | sdev_printk(KERN_ERR, sdev, | 1155 | |
1117 | "rejecting I/O to offline device\n"); | 1156 | cmd = scsi_get_cmd_from_req(sdev, req); |
1118 | goto kill; | 1157 | if (unlikely(!cmd)) |
1119 | } | 1158 | return BLKPREP_DEFER; |
1120 | if (unlikely(sdev->sdev_state != SDEV_RUNNING)) { | 1159 | |
1121 | /* OK, we're not in a running state don't prep | 1160 | ret = scsi_init_io(cmd); |
1122 | * user commands */ | 1161 | if (unlikely(ret)) |
1123 | if (sdev->sdev_state == SDEV_DEL) { | 1162 | return ret; |
1124 | /* Device is fully deleted, no commands | 1163 | |
1125 | * at all allowed down */ | 1164 | /* |
1126 | sdev_printk(KERN_ERR, sdev, | 1165 | * Initialize the actual SCSI command for this request. |
1127 | "rejecting I/O to dead device\n"); | 1166 | */ |
1128 | goto kill; | 1167 | drv = *(struct scsi_driver **)req->rq_disk->private_data; |
1129 | } | 1168 | if (unlikely(!drv->init_command(cmd))) { |
1130 | /* OK, we only allow special commands (i.e. not | 1169 | scsi_release_buffers(cmd); |
1131 | * user initiated ones */ | 1170 | scsi_put_command(cmd); |
1132 | specials_only = sdev->sdev_state; | 1171 | return BLKPREP_KILL; |
1133 | } | 1172 | } |
1134 | 1173 | ||
1174 | return BLKPREP_OK; | ||
1175 | } | ||
1176 | |||
1177 | static int scsi_prep_fn(struct request_queue *q, struct request *req) | ||
1178 | { | ||
1179 | struct scsi_device *sdev = q->queuedata; | ||
1180 | int ret = BLKPREP_OK; | ||
1181 | |||
1135 | /* | 1182 | /* |
1136 | * Find the actual device driver associated with this command. | 1183 | * If the device is not in running state we will reject some |
1137 | * The SPECIAL requests are things like character device or | 1184 | * or all commands. |
1138 | * ioctls, which did not originate from ll_rw_blk. Note that | ||
1139 | * the special field is also used to indicate the cmd for | ||
1140 | * the remainder of a partially fulfilled request that can | ||
1141 | * come up when there is a medium error. We have to treat | ||
1142 | * these two cases differently. We differentiate by looking | ||
1143 | * at request->cmd, as this tells us the real story. | ||
1144 | */ | 1185 | */ |
1145 | if (blk_special_request(req) && req->special) | 1186 | if (unlikely(sdev->sdev_state != SDEV_RUNNING)) { |
1146 | cmd = req->special; | 1187 | switch (sdev->sdev_state) { |
1147 | else if (blk_pc_request(req) || blk_fs_request(req)) { | 1188 | case SDEV_OFFLINE: |
1148 | if (unlikely(specials_only) && !(req->cmd_flags & REQ_PREEMPT)){ | 1189 | /* |
1149 | if (specials_only == SDEV_QUIESCE || | 1190 | * If the device is offline we refuse to process any |
1150 | specials_only == SDEV_BLOCK) | 1191 | * commands. The device must be brought online |
1151 | goto defer; | 1192 | * before trying any recovery commands. |
1152 | 1193 | */ | |
1153 | sdev_printk(KERN_ERR, sdev, | 1194 | sdev_printk(KERN_ERR, sdev, |
1154 | "rejecting I/O to device being removed\n"); | 1195 | "rejecting I/O to offline device\n"); |
1155 | goto kill; | 1196 | ret = BLKPREP_KILL; |
1197 | break; | ||
1198 | case SDEV_DEL: | ||
1199 | /* | ||
1200 | * If the device is fully deleted, we refuse to | ||
1201 | * process any commands as well. | ||
1202 | */ | ||
1203 | sdev_printk(KERN_ERR, sdev, | ||
1204 | "rejecting I/O to dead device\n"); | ||
1205 | ret = BLKPREP_KILL; | ||
1206 | break; | ||
1207 | case SDEV_QUIESCE: | ||
1208 | case SDEV_BLOCK: | ||
1209 | /* | ||
1210 | * If the devices is blocked we defer normal commands. | ||
1211 | */ | ||
1212 | if (!(req->cmd_flags & REQ_PREEMPT)) | ||
1213 | ret = BLKPREP_DEFER; | ||
1214 | break; | ||
1215 | default: | ||
1216 | /* | ||
1217 | * For any other not fully online state we only allow | ||
1218 | * special commands. In particular any user initiated | ||
1219 | * command is not allowed. | ||
1220 | */ | ||
1221 | if (!(req->cmd_flags & REQ_PREEMPT)) | ||
1222 | ret = BLKPREP_KILL; | ||
1223 | break; | ||
1156 | } | 1224 | } |
1157 | 1225 | ||
1158 | /* | 1226 | if (ret != BLKPREP_OK) |
1159 | * Now try and find a command block that we can use. | 1227 | goto out; |
1160 | */ | ||
1161 | if (!req->special) { | ||
1162 | cmd = scsi_get_command(sdev, GFP_ATOMIC); | ||
1163 | if (unlikely(!cmd)) | ||
1164 | goto defer; | ||
1165 | } else | ||
1166 | cmd = req->special; | ||
1167 | |||
1168 | /* pull a tag out of the request if we have one */ | ||
1169 | cmd->tag = req->tag; | ||
1170 | } else { | ||
1171 | blk_dump_rq_flags(req, "SCSI bad req"); | ||
1172 | goto kill; | ||
1173 | } | 1228 | } |
1174 | |||
1175 | /* note the overloading of req->special. When the tag | ||
1176 | * is active it always means cmd. If the tag goes | ||
1177 | * back for re-queueing, it may be reset */ | ||
1178 | req->special = cmd; | ||
1179 | cmd->request = req; | ||
1180 | |||
1181 | /* | ||
1182 | * FIXME: drop the lock here because the functions below | ||
1183 | * expect to be called without the queue lock held. Also, | ||
1184 | * previously, we dequeued the request before dropping the | ||
1185 | * lock. We hope REQ_STARTED prevents anything untoward from | ||
1186 | * happening now. | ||
1187 | */ | ||
1188 | if (blk_fs_request(req) || blk_pc_request(req)) { | ||
1189 | int ret; | ||
1190 | 1229 | ||
1230 | switch (req->cmd_type) { | ||
1231 | case REQ_TYPE_BLOCK_PC: | ||
1232 | ret = scsi_setup_blk_pc_cmnd(sdev, req); | ||
1233 | break; | ||
1234 | case REQ_TYPE_FS: | ||
1235 | ret = scsi_setup_fs_cmnd(sdev, req); | ||
1236 | break; | ||
1237 | default: | ||
1191 | /* | 1238 | /* |
1192 | * This will do a couple of things: | 1239 | * All other command types are not supported. |
1193 | * 1) Fill in the actual SCSI command. | ||
1194 | * 2) Fill in any other upper-level specific fields | ||
1195 | * (timeout). | ||
1196 | * | 1240 | * |
1197 | * If this returns 0, it means that the request failed | 1241 | * Note that these days the SCSI subsystem does not use |
1198 | * (reading past end of disk, reading offline device, | 1242 | * REQ_TYPE_SPECIAL requests anymore. These are only used |
1199 | * etc). This won't actually talk to the device, but | 1243 | * (directly or via blk_insert_request) by non-SCSI drivers. |
1200 | * some kinds of consistency checking may cause the | ||
1201 | * request to be rejected immediately. | ||
1202 | */ | 1244 | */ |
1245 | blk_dump_rq_flags(req, "SCSI bad req"); | ||
1246 | ret = BLKPREP_KILL; | ||
1247 | break; | ||
1248 | } | ||
1203 | 1249 | ||
1204 | /* | 1250 | out: |
1205 | * This sets up the scatter-gather table (allocating if | 1251 | switch (ret) { |
1206 | * required). | 1252 | case BLKPREP_KILL: |
1207 | */ | 1253 | req->errors = DID_NO_CONNECT << 16; |
1208 | ret = scsi_init_io(cmd); | 1254 | break; |
1209 | switch(ret) { | 1255 | case BLKPREP_DEFER: |
1210 | /* For BLKPREP_KILL/DEFER the cmd was released */ | ||
1211 | case BLKPREP_KILL: | ||
1212 | goto kill; | ||
1213 | case BLKPREP_DEFER: | ||
1214 | goto defer; | ||
1215 | } | ||
1216 | |||
1217 | /* | 1256 | /* |
1218 | * Initialize the actual SCSI command for this request. | 1257 | * If we defer, the elv_next_request() returns NULL, but the |
1258 | * queue must be restarted, so we plug here if no returning | ||
1259 | * command will automatically do that. | ||
1219 | */ | 1260 | */ |
1220 | if (blk_pc_request(req)) { | 1261 | if (sdev->device_busy == 0) |
1221 | scsi_setup_blk_pc_cmnd(cmd); | 1262 | blk_plug_device(q); |
1222 | } else if (req->rq_disk) { | 1263 | break; |
1223 | struct scsi_driver *drv; | 1264 | default: |
1224 | 1265 | req->cmd_flags |= REQ_DONTPREP; | |
1225 | drv = *(struct scsi_driver **)req->rq_disk->private_data; | ||
1226 | if (unlikely(!drv->init_command(cmd))) { | ||
1227 | scsi_release_buffers(cmd); | ||
1228 | scsi_put_command(cmd); | ||
1229 | goto kill; | ||
1230 | } | ||
1231 | } | ||
1232 | } | 1266 | } |
1233 | 1267 | ||
1234 | /* | 1268 | return ret; |
1235 | * The request is now prepped, no need to come back here | ||
1236 | */ | ||
1237 | req->cmd_flags |= REQ_DONTPREP; | ||
1238 | return BLKPREP_OK; | ||
1239 | |||
1240 | defer: | ||
1241 | /* If we defer, the elv_next_request() returns NULL, but the | ||
1242 | * queue must be restarted, so we plug here if no returning | ||
1243 | * command will automatically do that. */ | ||
1244 | if (sdev->device_busy == 0) | ||
1245 | blk_plug_device(q); | ||
1246 | return BLKPREP_DEFER; | ||
1247 | kill: | ||
1248 | req->errors = DID_NO_CONNECT << 16; | ||
1249 | return BLKPREP_KILL; | ||
1250 | } | 1269 | } |
1251 | 1270 | ||
1252 | /* | 1271 | /* |
diff --git a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h index 5d023d44e5e7..f458c2f686d2 100644 --- a/drivers/scsi/scsi_priv.h +++ b/drivers/scsi/scsi_priv.h | |||
@@ -39,6 +39,9 @@ static inline void scsi_log_completion(struct scsi_cmnd *cmd, int disposition) | |||
39 | { }; | 39 | { }; |
40 | #endif | 40 | #endif |
41 | 41 | ||
42 | /* scsi_scan.c */ | ||
43 | int scsi_complete_async_scans(void); | ||
44 | |||
42 | /* scsi_devinfo.c */ | 45 | /* scsi_devinfo.c */ |
43 | extern int scsi_get_device_flags(struct scsi_device *sdev, | 46 | extern int scsi_get_device_flags(struct scsi_device *sdev, |
44 | const unsigned char *vendor, | 47 | const unsigned char *vendor, |
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index 94a274645f6f..aa1b1e0e9d22 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c | |||
@@ -29,7 +29,9 @@ | |||
29 | #include <linux/moduleparam.h> | 29 | #include <linux/moduleparam.h> |
30 | #include <linux/init.h> | 30 | #include <linux/init.h> |
31 | #include <linux/blkdev.h> | 31 | #include <linux/blkdev.h> |
32 | #include <asm/semaphore.h> | 32 | #include <linux/delay.h> |
33 | #include <linux/kthread.h> | ||
34 | #include <linux/spinlock.h> | ||
33 | 35 | ||
34 | #include <scsi/scsi.h> | 36 | #include <scsi/scsi.h> |
35 | #include <scsi/scsi_cmnd.h> | 37 | #include <scsi/scsi_cmnd.h> |
@@ -87,6 +89,11 @@ module_param_named(max_luns, max_scsi_luns, int, S_IRUGO|S_IWUSR); | |||
87 | MODULE_PARM_DESC(max_luns, | 89 | MODULE_PARM_DESC(max_luns, |
88 | "last scsi LUN (should be between 1 and 2^32-1)"); | 90 | "last scsi LUN (should be between 1 and 2^32-1)"); |
89 | 91 | ||
92 | static char scsi_scan_type[6] = "sync"; | ||
93 | |||
94 | module_param_string(scan, scsi_scan_type, sizeof(scsi_scan_type), S_IRUGO); | ||
95 | MODULE_PARM_DESC(scan, "sync, async or none"); | ||
96 | |||
90 | /* | 97 | /* |
91 | * max_scsi_report_luns: the maximum number of LUNS that will be | 98 | * max_scsi_report_luns: the maximum number of LUNS that will be |
92 | * returned from the REPORT LUNS command. 8 times this value must | 99 | * returned from the REPORT LUNS command. 8 times this value must |
@@ -108,6 +115,68 @@ MODULE_PARM_DESC(inq_timeout, | |||
108 | "Timeout (in seconds) waiting for devices to answer INQUIRY." | 115 | "Timeout (in seconds) waiting for devices to answer INQUIRY." |
109 | " Default is 5. Some non-compliant devices need more."); | 116 | " Default is 5. Some non-compliant devices need more."); |
110 | 117 | ||
118 | static DEFINE_SPINLOCK(async_scan_lock); | ||
119 | static LIST_HEAD(scanning_hosts); | ||
120 | |||
121 | struct async_scan_data { | ||
122 | struct list_head list; | ||
123 | struct Scsi_Host *shost; | ||
124 | struct completion prev_finished; | ||
125 | }; | ||
126 | |||
127 | /** | ||
128 | * scsi_complete_async_scans - Wait for asynchronous scans to complete | ||
129 | * | ||
130 | * Asynchronous scans add themselves to the scanning_hosts list. Once | ||
131 | * that list is empty, we know that the scans are complete. Rather than | ||
132 | * waking up periodically to check the state of the list, we pretend to be | ||
133 | * a scanning task by adding ourselves at the end of the list and going to | ||
134 | * sleep. When the task before us wakes us up, we take ourselves off the | ||
135 | * list and return. | ||
136 | */ | ||
137 | int scsi_complete_async_scans(void) | ||
138 | { | ||
139 | struct async_scan_data *data; | ||
140 | |||
141 | do { | ||
142 | if (list_empty(&scanning_hosts)) | ||
143 | return 0; | ||
144 | /* If we can't get memory immediately, that's OK. Just | ||
145 | * sleep a little. Even if we never get memory, the async | ||
146 | * scans will finish eventually. | ||
147 | */ | ||
148 | data = kmalloc(sizeof(*data), GFP_KERNEL); | ||
149 | if (!data) | ||
150 | msleep(1); | ||
151 | } while (!data); | ||
152 | |||
153 | data->shost = NULL; | ||
154 | init_completion(&data->prev_finished); | ||
155 | |||
156 | spin_lock(&async_scan_lock); | ||
157 | /* Check that there's still somebody else on the list */ | ||
158 | if (list_empty(&scanning_hosts)) | ||
159 | goto done; | ||
160 | list_add_tail(&data->list, &scanning_hosts); | ||
161 | spin_unlock(&async_scan_lock); | ||
162 | |||
163 | printk(KERN_INFO "scsi: waiting for bus probes to complete ...\n"); | ||
164 | wait_for_completion(&data->prev_finished); | ||
165 | |||
166 | spin_lock(&async_scan_lock); | ||
167 | list_del(&data->list); | ||
168 | done: | ||
169 | spin_unlock(&async_scan_lock); | ||
170 | |||
171 | kfree(data); | ||
172 | return 0; | ||
173 | } | ||
174 | |||
175 | #ifdef MODULE | ||
176 | /* Only exported for the benefit of scsi_wait_scan */ | ||
177 | EXPORT_SYMBOL_GPL(scsi_complete_async_scans); | ||
178 | #endif | ||
179 | |||
111 | /** | 180 | /** |
112 | * scsi_unlock_floptical - unlock device via a special MODE SENSE command | 181 | * scsi_unlock_floptical - unlock device via a special MODE SENSE command |
113 | * @sdev: scsi device to send command to | 182 | * @sdev: scsi device to send command to |
@@ -619,7 +688,7 @@ static int scsi_probe_lun(struct scsi_device *sdev, unsigned char *inq_result, | |||
619 | * SCSI_SCAN_LUN_PRESENT: a new scsi_device was allocated and initialized | 688 | * SCSI_SCAN_LUN_PRESENT: a new scsi_device was allocated and initialized |
620 | **/ | 689 | **/ |
621 | static int scsi_add_lun(struct scsi_device *sdev, unsigned char *inq_result, | 690 | static int scsi_add_lun(struct scsi_device *sdev, unsigned char *inq_result, |
622 | int *bflags) | 691 | int *bflags, int async) |
623 | { | 692 | { |
624 | /* | 693 | /* |
625 | * XXX do not save the inquiry, since it can change underneath us, | 694 | * XXX do not save the inquiry, since it can change underneath us, |
@@ -805,7 +874,7 @@ static int scsi_add_lun(struct scsi_device *sdev, unsigned char *inq_result, | |||
805 | * register it and tell the rest of the kernel | 874 | * register it and tell the rest of the kernel |
806 | * about it. | 875 | * about it. |
807 | */ | 876 | */ |
808 | if (scsi_sysfs_add_sdev(sdev) != 0) | 877 | if (!async && scsi_sysfs_add_sdev(sdev) != 0) |
809 | return SCSI_SCAN_NO_RESPONSE; | 878 | return SCSI_SCAN_NO_RESPONSE; |
810 | 879 | ||
811 | return SCSI_SCAN_LUN_PRESENT; | 880 | return SCSI_SCAN_LUN_PRESENT; |
@@ -974,7 +1043,7 @@ static int scsi_probe_and_add_lun(struct scsi_target *starget, | |||
974 | goto out_free_result; | 1043 | goto out_free_result; |
975 | } | 1044 | } |
976 | 1045 | ||
977 | res = scsi_add_lun(sdev, result, &bflags); | 1046 | res = scsi_add_lun(sdev, result, &bflags, shost->async_scan); |
978 | if (res == SCSI_SCAN_LUN_PRESENT) { | 1047 | if (res == SCSI_SCAN_LUN_PRESENT) { |
979 | if (bflags & BLIST_KEY) { | 1048 | if (bflags & BLIST_KEY) { |
980 | sdev->lockable = 0; | 1049 | sdev->lockable = 0; |
@@ -1474,6 +1543,9 @@ void scsi_scan_target(struct device *parent, unsigned int channel, | |||
1474 | { | 1543 | { |
1475 | struct Scsi_Host *shost = dev_to_shost(parent); | 1544 | struct Scsi_Host *shost = dev_to_shost(parent); |
1476 | 1545 | ||
1546 | if (!shost->async_scan) | ||
1547 | scsi_complete_async_scans(); | ||
1548 | |||
1477 | mutex_lock(&shost->scan_mutex); | 1549 | mutex_lock(&shost->scan_mutex); |
1478 | if (scsi_host_scan_allowed(shost)) | 1550 | if (scsi_host_scan_allowed(shost)) |
1479 | __scsi_scan_target(parent, channel, id, lun, rescan); | 1551 | __scsi_scan_target(parent, channel, id, lun, rescan); |
@@ -1519,6 +1591,9 @@ int scsi_scan_host_selected(struct Scsi_Host *shost, unsigned int channel, | |||
1519 | "%s: <%u:%u:%u>\n", | 1591 | "%s: <%u:%u:%u>\n", |
1520 | __FUNCTION__, channel, id, lun)); | 1592 | __FUNCTION__, channel, id, lun)); |
1521 | 1593 | ||
1594 | if (!shost->async_scan) | ||
1595 | scsi_complete_async_scans(); | ||
1596 | |||
1522 | if (((channel != SCAN_WILD_CARD) && (channel > shost->max_channel)) || | 1597 | if (((channel != SCAN_WILD_CARD) && (channel > shost->max_channel)) || |
1523 | ((id != SCAN_WILD_CARD) && (id >= shost->max_id)) || | 1598 | ((id != SCAN_WILD_CARD) && (id >= shost->max_id)) || |
1524 | ((lun != SCAN_WILD_CARD) && (lun > shost->max_lun))) | 1599 | ((lun != SCAN_WILD_CARD) && (lun > shost->max_lun))) |
@@ -1539,14 +1614,130 @@ int scsi_scan_host_selected(struct Scsi_Host *shost, unsigned int channel, | |||
1539 | return 0; | 1614 | return 0; |
1540 | } | 1615 | } |
1541 | 1616 | ||
1617 | static void scsi_sysfs_add_devices(struct Scsi_Host *shost) | ||
1618 | { | ||
1619 | struct scsi_device *sdev; | ||
1620 | shost_for_each_device(sdev, shost) { | ||
1621 | if (scsi_sysfs_add_sdev(sdev) != 0) | ||
1622 | scsi_destroy_sdev(sdev); | ||
1623 | } | ||
1624 | } | ||
1625 | |||
1626 | /** | ||
1627 | * scsi_prep_async_scan - prepare for an async scan | ||
1628 | * @shost: the host which will be scanned | ||
1629 | * Returns: a cookie to be passed to scsi_finish_async_scan() | ||
1630 | * | ||
1631 | * Tells the midlayer this host is going to do an asynchronous scan. | ||
1632 | * It reserves the host's position in the scanning list and ensures | ||
1633 | * that other asynchronous scans started after this one won't affect the | ||
1634 | * ordering of the discovered devices. | ||
1635 | */ | ||
1636 | struct async_scan_data *scsi_prep_async_scan(struct Scsi_Host *shost) | ||
1637 | { | ||
1638 | struct async_scan_data *data; | ||
1639 | |||
1640 | if (strncmp(scsi_scan_type, "sync", 4) == 0) | ||
1641 | return NULL; | ||
1642 | |||
1643 | if (shost->async_scan) { | ||
1644 | printk("%s called twice for host %d", __FUNCTION__, | ||
1645 | shost->host_no); | ||
1646 | dump_stack(); | ||
1647 | return NULL; | ||
1648 | } | ||
1649 | |||
1650 | data = kmalloc(sizeof(*data), GFP_KERNEL); | ||
1651 | if (!data) | ||
1652 | goto err; | ||
1653 | data->shost = scsi_host_get(shost); | ||
1654 | if (!data->shost) | ||
1655 | goto err; | ||
1656 | init_completion(&data->prev_finished); | ||
1657 | |||
1658 | spin_lock(&async_scan_lock); | ||
1659 | shost->async_scan = 1; | ||
1660 | if (list_empty(&scanning_hosts)) | ||
1661 | complete(&data->prev_finished); | ||
1662 | list_add_tail(&data->list, &scanning_hosts); | ||
1663 | spin_unlock(&async_scan_lock); | ||
1664 | |||
1665 | return data; | ||
1666 | |||
1667 | err: | ||
1668 | kfree(data); | ||
1669 | return NULL; | ||
1670 | } | ||
1671 | |||
1672 | /** | ||
1673 | * scsi_finish_async_scan - asynchronous scan has finished | ||
1674 | * @data: cookie returned from earlier call to scsi_prep_async_scan() | ||
1675 | * | ||
1676 | * All the devices currently attached to this host have been found. | ||
1677 | * This function announces all the devices it has found to the rest | ||
1678 | * of the system. | ||
1679 | */ | ||
1680 | void scsi_finish_async_scan(struct async_scan_data *data) | ||
1681 | { | ||
1682 | struct Scsi_Host *shost; | ||
1683 | |||
1684 | if (!data) | ||
1685 | return; | ||
1686 | |||
1687 | shost = data->shost; | ||
1688 | if (!shost->async_scan) { | ||
1689 | printk("%s called twice for host %d", __FUNCTION__, | ||
1690 | shost->host_no); | ||
1691 | dump_stack(); | ||
1692 | return; | ||
1693 | } | ||
1694 | |||
1695 | wait_for_completion(&data->prev_finished); | ||
1696 | |||
1697 | scsi_sysfs_add_devices(shost); | ||
1698 | |||
1699 | spin_lock(&async_scan_lock); | ||
1700 | shost->async_scan = 0; | ||
1701 | list_del(&data->list); | ||
1702 | if (!list_empty(&scanning_hosts)) { | ||
1703 | struct async_scan_data *next = list_entry(scanning_hosts.next, | ||
1704 | struct async_scan_data, list); | ||
1705 | complete(&next->prev_finished); | ||
1706 | } | ||
1707 | spin_unlock(&async_scan_lock); | ||
1708 | |||
1709 | scsi_host_put(shost); | ||
1710 | kfree(data); | ||
1711 | } | ||
1712 | |||
1713 | static int do_scan_async(void *_data) | ||
1714 | { | ||
1715 | struct async_scan_data *data = _data; | ||
1716 | scsi_scan_host_selected(data->shost, SCAN_WILD_CARD, SCAN_WILD_CARD, | ||
1717 | SCAN_WILD_CARD, 0); | ||
1718 | |||
1719 | scsi_finish_async_scan(data); | ||
1720 | return 0; | ||
1721 | } | ||
1722 | |||
1542 | /** | 1723 | /** |
1543 | * scsi_scan_host - scan the given adapter | 1724 | * scsi_scan_host - scan the given adapter |
1544 | * @shost: adapter to scan | 1725 | * @shost: adapter to scan |
1545 | **/ | 1726 | **/ |
1546 | void scsi_scan_host(struct Scsi_Host *shost) | 1727 | void scsi_scan_host(struct Scsi_Host *shost) |
1547 | { | 1728 | { |
1548 | scsi_scan_host_selected(shost, SCAN_WILD_CARD, SCAN_WILD_CARD, | 1729 | struct async_scan_data *data; |
1549 | SCAN_WILD_CARD, 0); | 1730 | |
1731 | if (strncmp(scsi_scan_type, "none", 4) == 0) | ||
1732 | return; | ||
1733 | |||
1734 | data = scsi_prep_async_scan(shost); | ||
1735 | if (!data) { | ||
1736 | scsi_scan_host_selected(shost, SCAN_WILD_CARD, SCAN_WILD_CARD, | ||
1737 | SCAN_WILD_CARD, 0); | ||
1738 | return; | ||
1739 | } | ||
1740 | kthread_run(do_scan_async, data, "scsi_scan_%d", shost->host_no); | ||
1550 | } | 1741 | } |
1551 | EXPORT_SYMBOL(scsi_scan_host); | 1742 | EXPORT_SYMBOL(scsi_scan_host); |
1552 | 1743 | ||
diff --git a/drivers/scsi/scsi_wait_scan.c b/drivers/scsi/scsi_wait_scan.c new file mode 100644 index 000000000000..8a636103083d --- /dev/null +++ b/drivers/scsi/scsi_wait_scan.c | |||
@@ -0,0 +1,31 @@ | |||
1 | /* | ||
2 | * scsi_wait_scan.c | ||
3 | * | ||
4 | * Copyright (C) 2006 James Bottomley <James.Bottomley@SteelEye.com> | ||
5 | * | ||
6 | * This is a simple module to wait until all the async scans are | ||
7 | * complete. The idea is to use it in initrd/initramfs scripts. You | ||
8 | * modprobe it after all the modprobes of the root SCSI drivers and it | ||
9 | * will wait until they have all finished scanning their busses before | ||
10 | * allowing the boot to proceed | ||
11 | */ | ||
12 | |||
13 | #include <linux/module.h> | ||
14 | #include "scsi_priv.h" | ||
15 | |||
16 | static int __init wait_scan_init(void) | ||
17 | { | ||
18 | scsi_complete_async_scans(); | ||
19 | return 0; | ||
20 | } | ||
21 | |||
22 | static void __exit wait_scan_exit(void) | ||
23 | { | ||
24 | } | ||
25 | |||
26 | MODULE_DESCRIPTION("SCSI wait for scans"); | ||
27 | MODULE_AUTHOR("James Bottomley"); | ||
28 | MODULE_LICENSE("GPL"); | ||
29 | |||
30 | late_initcall(wait_scan_init); | ||
31 | module_exit(wait_scan_exit); | ||
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 84ff203ffedd..f6a452846fab 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c | |||
@@ -1051,6 +1051,14 @@ sd_spinup_disk(struct scsi_disk *sdkp, char *diskname) | |||
1051 | &sshdr, SD_TIMEOUT, | 1051 | &sshdr, SD_TIMEOUT, |
1052 | SD_MAX_RETRIES); | 1052 | SD_MAX_RETRIES); |
1053 | 1053 | ||
1054 | /* | ||
1055 | * If the drive has indicated to us that it | ||
1056 | * doesn't have any media in it, don't bother | ||
1057 | * with any more polling. | ||
1058 | */ | ||
1059 | if (media_not_present(sdkp, &sshdr)) | ||
1060 | return; | ||
1061 | |||
1054 | if (the_result) | 1062 | if (the_result) |
1055 | sense_valid = scsi_sense_valid(&sshdr); | 1063 | sense_valid = scsi_sense_valid(&sshdr); |
1056 | retries++; | 1064 | retries++; |
@@ -1059,14 +1067,6 @@ sd_spinup_disk(struct scsi_disk *sdkp, char *diskname) | |||
1059 | ((driver_byte(the_result) & DRIVER_SENSE) && | 1067 | ((driver_byte(the_result) & DRIVER_SENSE) && |
1060 | sense_valid && sshdr.sense_key == UNIT_ATTENTION))); | 1068 | sense_valid && sshdr.sense_key == UNIT_ATTENTION))); |
1061 | 1069 | ||
1062 | /* | ||
1063 | * If the drive has indicated to us that it doesn't have | ||
1064 | * any media in it, don't bother with any of the rest of | ||
1065 | * this crap. | ||
1066 | */ | ||
1067 | if (media_not_present(sdkp, &sshdr)) | ||
1068 | return; | ||
1069 | |||
1070 | if ((driver_byte(the_result) & DRIVER_SENSE) == 0) { | 1070 | if ((driver_byte(the_result) & DRIVER_SENSE) == 0) { |
1071 | /* no sense, TUR either succeeded or failed | 1071 | /* no sense, TUR either succeeded or failed |
1072 | * with a status error */ | 1072 | * with a status error */ |
@@ -1467,7 +1467,6 @@ sd_read_cache_type(struct scsi_disk *sdkp, char *diskname, | |||
1467 | res = sd_do_mode_sense(sdp, dbd, modepage, buffer, len, &data, &sshdr); | 1467 | res = sd_do_mode_sense(sdp, dbd, modepage, buffer, len, &data, &sshdr); |
1468 | 1468 | ||
1469 | if (scsi_status_is_good(res)) { | 1469 | if (scsi_status_is_good(res)) { |
1470 | int ct = 0; | ||
1471 | int offset = data.header_length + data.block_descriptor_length; | 1470 | int offset = data.header_length + data.block_descriptor_length; |
1472 | 1471 | ||
1473 | if (offset >= SD_BUF_SIZE - 2) { | 1472 | if (offset >= SD_BUF_SIZE - 2) { |
@@ -1496,11 +1495,13 @@ sd_read_cache_type(struct scsi_disk *sdkp, char *diskname, | |||
1496 | sdkp->DPOFUA = 0; | 1495 | sdkp->DPOFUA = 0; |
1497 | } | 1496 | } |
1498 | 1497 | ||
1499 | ct = sdkp->RCD + 2*sdkp->WCE; | 1498 | printk(KERN_NOTICE "SCSI device %s: " |
1500 | 1499 | "write cache: %s, read cache: %s, %s\n", | |
1501 | printk(KERN_NOTICE "SCSI device %s: drive cache: %s%s\n", | 1500 | diskname, |
1502 | diskname, sd_cache_types[ct], | 1501 | sdkp->WCE ? "enabled" : "disabled", |
1503 | sdkp->DPOFUA ? " w/ FUA" : ""); | 1502 | sdkp->RCD ? "disabled" : "enabled", |
1503 | sdkp->DPOFUA ? "supports DPO and FUA" | ||
1504 | : "doesn't support DPO or FUA"); | ||
1504 | 1505 | ||
1505 | return; | 1506 | return; |
1506 | } | 1507 | } |
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index e1a52c525ed4..587274dd7059 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c | |||
@@ -9,7 +9,7 @@ | |||
9 | Steve Hirsch, Andreas Koppenh"ofer, Michael Leodolter, Eyal Lebedinsky, | 9 | Steve Hirsch, Andreas Koppenh"ofer, Michael Leodolter, Eyal Lebedinsky, |
10 | Michael Schaefer, J"org Weule, and Eric Youngdale. | 10 | Michael Schaefer, J"org Weule, and Eric Youngdale. |
11 | 11 | ||
12 | Copyright 1992 - 2005 Kai Makisara | 12 | Copyright 1992 - 2006 Kai Makisara |
13 | email Kai.Makisara@kolumbus.fi | 13 | email Kai.Makisara@kolumbus.fi |
14 | 14 | ||
15 | Some small formal changes - aeb, 950809 | 15 | Some small formal changes - aeb, 950809 |
@@ -17,7 +17,7 @@ | |||
17 | Last modified: 18-JAN-1998 Richard Gooch <rgooch@atnf.csiro.au> Devfs support | 17 | Last modified: 18-JAN-1998 Richard Gooch <rgooch@atnf.csiro.au> Devfs support |
18 | */ | 18 | */ |
19 | 19 | ||
20 | static const char *verstr = "20050830"; | 20 | static const char *verstr = "20061107"; |
21 | 21 | ||
22 | #include <linux/module.h> | 22 | #include <linux/module.h> |
23 | 23 | ||
@@ -999,7 +999,7 @@ static int check_tape(struct scsi_tape *STp, struct file *filp) | |||
999 | STp->min_block = ((STp->buffer)->b_data[4] << 8) | | 999 | STp->min_block = ((STp->buffer)->b_data[4] << 8) | |
1000 | (STp->buffer)->b_data[5]; | 1000 | (STp->buffer)->b_data[5]; |
1001 | if ( DEB( debugging || ) !STp->inited) | 1001 | if ( DEB( debugging || ) !STp->inited) |
1002 | printk(KERN_WARNING | 1002 | printk(KERN_INFO |
1003 | "%s: Block limits %d - %d bytes.\n", name, | 1003 | "%s: Block limits %d - %d bytes.\n", name, |
1004 | STp->min_block, STp->max_block); | 1004 | STp->min_block, STp->max_block); |
1005 | } else { | 1005 | } else { |
@@ -1224,7 +1224,7 @@ static int st_flush(struct file *filp, fl_owner_t id) | |||
1224 | } | 1224 | } |
1225 | 1225 | ||
1226 | DEBC( if (STp->nbr_requests) | 1226 | DEBC( if (STp->nbr_requests) |
1227 | printk(KERN_WARNING "%s: Number of r/w requests %d, dio used in %d, pages %d (%d).\n", | 1227 | printk(KERN_DEBUG "%s: Number of r/w requests %d, dio used in %d, pages %d (%d).\n", |
1228 | name, STp->nbr_requests, STp->nbr_dio, STp->nbr_pages, STp->nbr_combinable)); | 1228 | name, STp->nbr_requests, STp->nbr_dio, STp->nbr_pages, STp->nbr_combinable)); |
1229 | 1229 | ||
1230 | if (STps->rw == ST_WRITING && !STp->pos_unknown) { | 1230 | if (STps->rw == ST_WRITING && !STp->pos_unknown) { |
@@ -4056,11 +4056,11 @@ static int st_probe(struct device *dev) | |||
4056 | goto out_free_tape; | 4056 | goto out_free_tape; |
4057 | } | 4057 | } |
4058 | 4058 | ||
4059 | sdev_printk(KERN_WARNING, SDp, | 4059 | sdev_printk(KERN_NOTICE, SDp, |
4060 | "Attached scsi tape %s\n", tape_name(tpnt)); | 4060 | "Attached scsi tape %s\n", tape_name(tpnt)); |
4061 | printk(KERN_WARNING "%s: try direct i/o: %s (alignment %d B)\n", | 4061 | sdev_printk(KERN_INFO, SDp, "%s: try direct i/o: %s (alignment %d B)\n", |
4062 | tape_name(tpnt), tpnt->try_dio ? "yes" : "no", | 4062 | tape_name(tpnt), tpnt->try_dio ? "yes" : "no", |
4063 | queue_dma_alignment(SDp->request_queue) + 1); | 4063 | queue_dma_alignment(SDp->request_queue) + 1); |
4064 | 4064 | ||
4065 | return 0; | 4065 | return 0; |
4066 | 4066 | ||
diff --git a/drivers/scsi/t128.h b/drivers/scsi/t128.h index 646e840266e2..76a069b7ac0b 100644 --- a/drivers/scsi/t128.h +++ b/drivers/scsi/t128.h | |||
@@ -8,20 +8,20 @@ | |||
8 | * drew@colorado.edu | 8 | * drew@colorado.edu |
9 | * +1 (303) 440-4894 | 9 | * +1 (303) 440-4894 |
10 | * | 10 | * |
11 | * DISTRIBUTION RELEASE 3. | 11 | * DISTRIBUTION RELEASE 3. |
12 | * | 12 | * |
13 | * For more information, please consult | 13 | * For more information, please consult |
14 | * | 14 | * |
15 | * Trantor Systems, Ltd. | 15 | * Trantor Systems, Ltd. |
16 | * T128/T128F/T228 SCSI Host Adapter | 16 | * T128/T128F/T228 SCSI Host Adapter |
17 | * Hardware Specifications | 17 | * Hardware Specifications |
18 | * | 18 | * |
19 | * Trantor Systems, Ltd. | 19 | * Trantor Systems, Ltd. |
20 | * 5415 Randall Place | 20 | * 5415 Randall Place |
21 | * Fremont, CA 94538 | 21 | * Fremont, CA 94538 |
22 | * 1+ (415) 770-1400, FAX 1+ (415) 770-9910 | 22 | * 1+ (415) 770-1400, FAX 1+ (415) 770-9910 |
23 | * | 23 | * |
24 | * and | 24 | * and |
25 | * | 25 | * |
26 | * NCR 5380 Family | 26 | * NCR 5380 Family |
27 | * SCSI Protocol Controller | 27 | * SCSI Protocol Controller |
@@ -48,15 +48,15 @@ | |||
48 | #define TDEBUG_TRANSFER 0x2 | 48 | #define TDEBUG_TRANSFER 0x2 |
49 | 49 | ||
50 | /* | 50 | /* |
51 | * The trantor boards are memory mapped. They use an NCR5380 or | 51 | * The trantor boards are memory mapped. They use an NCR5380 or |
52 | * equivalent (my sample board had part second sourced from ZILOG). | 52 | * equivalent (my sample board had part second sourced from ZILOG). |
53 | * NCR's recommended "Pseudo-DMA" architecture is used, where | 53 | * NCR's recommended "Pseudo-DMA" architecture is used, where |
54 | * a PAL drives the DMA signals on the 5380 allowing fast, blind | 54 | * a PAL drives the DMA signals on the 5380 allowing fast, blind |
55 | * transfers with proper handshaking. | 55 | * transfers with proper handshaking. |
56 | */ | 56 | */ |
57 | 57 | ||
58 | /* | 58 | /* |
59 | * Note : a boot switch is provided for the purpose of informing the | 59 | * Note : a boot switch is provided for the purpose of informing the |
60 | * firmware to boot or not boot from attached SCSI devices. So, I imagine | 60 | * firmware to boot or not boot from attached SCSI devices. So, I imagine |
61 | * there are fewer people who've yanked the ROM like they do on the Seagate | 61 | * there are fewer people who've yanked the ROM like they do on the Seagate |
62 | * to make bootup faster, and I'll probably use this for autodetection. | 62 | * to make bootup faster, and I'll probably use this for autodetection. |
@@ -92,19 +92,20 @@ | |||
92 | #define T_DATA_REG_OFFSET 0x1e00 /* rw 512 bytes long */ | 92 | #define T_DATA_REG_OFFSET 0x1e00 /* rw 512 bytes long */ |
93 | 93 | ||
94 | #ifndef ASM | 94 | #ifndef ASM |
95 | static int t128_abort(Scsi_Cmnd *); | 95 | static int t128_abort(struct scsi_cmnd *); |
96 | static int t128_biosparam(struct scsi_device *, struct block_device *, | 96 | static int t128_biosparam(struct scsi_device *, struct block_device *, |
97 | sector_t, int*); | 97 | sector_t, int*); |
98 | static int t128_detect(struct scsi_host_template *); | 98 | static int t128_detect(struct scsi_host_template *); |
99 | static int t128_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); | 99 | static int t128_queue_command(struct scsi_cmnd *, |
100 | static int t128_bus_reset(Scsi_Cmnd *); | 100 | void (*done)(struct scsi_cmnd *)); |
101 | static int t128_bus_reset(struct scsi_cmnd *); | ||
101 | 102 | ||
102 | #ifndef CMD_PER_LUN | 103 | #ifndef CMD_PER_LUN |
103 | #define CMD_PER_LUN 2 | 104 | #define CMD_PER_LUN 2 |
104 | #endif | 105 | #endif |
105 | 106 | ||
106 | #ifndef CAN_QUEUE | 107 | #ifndef CAN_QUEUE |
107 | #define CAN_QUEUE 32 | 108 | #define CAN_QUEUE 32 |
108 | #endif | 109 | #endif |
109 | 110 | ||
110 | #ifndef HOSTS_C | 111 | #ifndef HOSTS_C |
@@ -120,7 +121,7 @@ static int t128_bus_reset(Scsi_Cmnd *); | |||
120 | 121 | ||
121 | #define T128_address(reg) (base + T_5380_OFFSET + ((reg) * 0x20)) | 122 | #define T128_address(reg) (base + T_5380_OFFSET + ((reg) * 0x20)) |
122 | 123 | ||
123 | #if !(TDEBUG & TDEBUG_TRANSFER) | 124 | #if !(TDEBUG & TDEBUG_TRANSFER) |
124 | #define NCR5380_read(reg) readb(T128_address(reg)) | 125 | #define NCR5380_read(reg) readb(T128_address(reg)) |
125 | #define NCR5380_write(reg, value) writeb((value),(T128_address(reg))) | 126 | #define NCR5380_write(reg, value) writeb((value),(T128_address(reg))) |
126 | #else | 127 | #else |
@@ -129,7 +130,7 @@ static int t128_bus_reset(Scsi_Cmnd *); | |||
129 | , instance->hostno, (reg), T128_address(reg))), readb(T128_address(reg))) | 130 | , instance->hostno, (reg), T128_address(reg))), readb(T128_address(reg))) |
130 | 131 | ||
131 | #define NCR5380_write(reg, value) { \ | 132 | #define NCR5380_write(reg, value) { \ |
132 | printk("scsi%d : write %02x to register %d at address %08x\n", \ | 133 | printk("scsi%d : write %02x to register %d at address %08x\n", \ |
133 | instance->hostno, (value), (reg), T128_address(reg)); \ | 134 | instance->hostno, (value), (reg), T128_address(reg)); \ |
134 | writeb((value), (T128_address(reg))); \ | 135 | writeb((value), (T128_address(reg))); \ |
135 | } | 136 | } |
@@ -142,10 +143,10 @@ static int t128_bus_reset(Scsi_Cmnd *); | |||
142 | #define NCR5380_bus_reset t128_bus_reset | 143 | #define NCR5380_bus_reset t128_bus_reset |
143 | #define NCR5380_proc_info t128_proc_info | 144 | #define NCR5380_proc_info t128_proc_info |
144 | 145 | ||
145 | /* 15 14 12 10 7 5 3 | 146 | /* 15 14 12 10 7 5 3 |
146 | 1101 0100 1010 1000 */ | 147 | 1101 0100 1010 1000 */ |
147 | 148 | ||
148 | #define T128_IRQS 0xc4a8 | 149 | #define T128_IRQS 0xc4a8 |
149 | 150 | ||
150 | #endif /* else def HOSTS_C */ | 151 | #endif /* else def HOSTS_C */ |
151 | #endif /* ndef ASM */ | 152 | #endif /* ndef ASM */ |