Commit df0ae2497ddefd72a87f3a3b34ff32455d7d4ae0
1 parent
68b3aa7c98
Exists in
master
and in
4 other branches
[SCSI] allow sleeping in ->eh_host_reset_handler()
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Showing 38 changed files with 177 additions and 44 deletions Side-by-side Diff
- Documentation/scsi/scsi_mid_low_api.txt
- drivers/fc4/fc.c
- drivers/fc4/fc_syms.c
- drivers/fc4/fcp_impl.h
- drivers/message/fusion/mptscsih.c
- drivers/s390/scsi/zfcp_scsi.c
- drivers/scsi/3w-9xxx.c
- drivers/scsi/3w-xxxx.c
- drivers/scsi/53c700.c
- drivers/scsi/BusLogic.c
- drivers/scsi/NCR53c406a.c
- drivers/scsi/a2091.c
- drivers/scsi/a3000.c
- drivers/scsi/aacraid/linit.c
- drivers/scsi/aha1542.c
- drivers/scsi/aic7xxx_old.c
- drivers/scsi/arm/fas216.c
- drivers/scsi/dpt_i2o.c
- drivers/scsi/eata.c
- drivers/scsi/eata_pio.c
- drivers/scsi/gvp11.c
- drivers/scsi/ibmmca.c
- drivers/scsi/ide-scsi.c
- drivers/scsi/ipr.c
- drivers/scsi/ips.c
- drivers/scsi/mac53c94.c
- drivers/scsi/mesh.c
- drivers/scsi/mvme147.c
- drivers/scsi/nsp32.c
- drivers/scsi/pcmcia/sym53c500_cs.c
- drivers/scsi/qla1280.c
- drivers/scsi/qla2xxx/qla_os.c
- drivers/scsi/scsi_error.c
- drivers/scsi/sgiwd93.c
- drivers/scsi/sym53c416.c
- drivers/scsi/sym53c8xx_2/sym_glue.c
- drivers/scsi/u14-34f.c
- drivers/scsi/wd7000.c
Documentation/scsi/scsi_mid_low_api.txt
... | ... | @@ -990,8 +990,7 @@ |
990 | 990 | * |
991 | 991 | * Returns SUCCESS if command aborted else FAILED |
992 | 992 | * |
993 | - * Locks: struct Scsi_Host::host_lock held (with irqsave) on entry | |
994 | - * and assumed to be held on return. | |
993 | + * Locks: None held | |
995 | 994 | * |
996 | 995 | * Calling context: kernel thread |
997 | 996 | * |
drivers/fc4/fc.c
... | ... | @@ -1005,14 +1005,8 @@ |
1005 | 1005 | return SUCCESS; |
1006 | 1006 | } |
1007 | 1007 | |
1008 | -int fcp_scsi_bus_reset(Scsi_Cmnd *SCpnt) | |
1008 | +static int __fcp_scsi_host_reset(Scsi_Cmnd *SCpnt) | |
1009 | 1009 | { |
1010 | - printk ("FC: bus reset!\n"); | |
1011 | - return FAILED; | |
1012 | -} | |
1013 | - | |
1014 | -int fcp_scsi_host_reset(Scsi_Cmnd *SCpnt) | |
1015 | -{ | |
1016 | 1010 | fc_channel *fc = FC_SCMND(SCpnt); |
1017 | 1011 | fcp_cmnd *fcmd = FCP_CMND(SCpnt); |
1018 | 1012 | int i; |
... | ... | @@ -1030,6 +1024,17 @@ |
1030 | 1024 | fc->abort_count = 0; |
1031 | 1025 | if (fcp_initialize(fc, 1)) return SUCCESS; |
1032 | 1026 | else return FAILED; |
1027 | +} | |
1028 | + | |
1029 | +int fcp_scsi_host_reset(Scsi_Cmnd *SCpnt) | |
1030 | +{ | |
1031 | + int rc; | |
1032 | + | |
1033 | + spin_lock_irqsave(SCpnt->device->host->host_lock, flags); | |
1034 | + rc = __fcp_scsi_host_reset(SCpnt); | |
1035 | + spin_unlock_irqrestore(SCpnt->device->host->host_lock, flags); | |
1036 | + | |
1037 | + return rc; | |
1033 | 1038 | } |
1034 | 1039 | |
1035 | 1040 | static int fcp_els_queue_it(fc_channel *fc, fcp_cmnd *fcmd) |
drivers/fc4/fc_syms.c
drivers/fc4/fcp_impl.h
... | ... | @@ -158,7 +158,6 @@ |
158 | 158 | int fcp_scsi_queuecommand(Scsi_Cmnd *, void (* done)(Scsi_Cmnd *)); |
159 | 159 | int fcp_scsi_abort(Scsi_Cmnd *); |
160 | 160 | int fcp_scsi_dev_reset(Scsi_Cmnd *); |
161 | -int fcp_scsi_bus_reset(Scsi_Cmnd *); | |
162 | 161 | int fcp_scsi_host_reset(Scsi_Cmnd *); |
163 | 162 | |
164 | 163 | #endif /* !(_FCP_SCSI_H) */ |
drivers/message/fusion/mptscsih.c
... | ... | @@ -1899,7 +1899,6 @@ |
1899 | 1899 | { |
1900 | 1900 | MPT_SCSI_HOST * hd; |
1901 | 1901 | int status = SUCCESS; |
1902 | - spinlock_t *host_lock = SCpnt->device->host->host_lock; | |
1903 | 1902 | |
1904 | 1903 | /* If we can't locate the host to reset, then we failed. */ |
1905 | 1904 | if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){ |
... | ... | @@ -1915,7 +1914,6 @@ |
1915 | 1914 | /* If our attempts to reset the host failed, then return a failed |
1916 | 1915 | * status. The host will be taken off line by the SCSI mid-layer. |
1917 | 1916 | */ |
1918 | - spin_unlock_irq(host_lock); | |
1919 | 1917 | if (mpt_HardResetHandler(hd->ioc, CAN_SLEEP) < 0){ |
1920 | 1918 | status = FAILED; |
1921 | 1919 | } else { |
... | ... | @@ -1925,8 +1923,6 @@ |
1925 | 1923 | hd->tmPending = 0; |
1926 | 1924 | hd->tmState = TM_STATE_NONE; |
1927 | 1925 | } |
1928 | - spin_lock_irq(host_lock); | |
1929 | - | |
1930 | 1926 | |
1931 | 1927 | dtmprintk( ( KERN_WARNING MYNAM ": mptscsih_host_reset: " |
1932 | 1928 | "Status = %s\n", |
drivers/s390/scsi/zfcp_scsi.c
... | ... | @@ -755,8 +755,6 @@ |
755 | 755 | struct zfcp_unit *unit; |
756 | 756 | struct Scsi_Host *scsi_host = scpnt->device->host; |
757 | 757 | |
758 | - spin_unlock_irq(scsi_host->host_lock); | |
759 | - | |
760 | 758 | unit = (struct zfcp_unit *) scpnt->device->hostdata; |
761 | 759 | ZFCP_LOG_NORMAL("host reset because of problems with " |
762 | 760 | "unit 0x%016Lx\n", unit->fcp_lun); |
... | ... | @@ -764,7 +762,6 @@ |
764 | 762 | zfcp_erp_wait(unit->port->adapter); |
765 | 763 | retval = SUCCESS; |
766 | 764 | |
767 | - spin_lock_irq(scsi_host->host_lock); | |
768 | 765 | return retval; |
769 | 766 | } |
770 | 767 |
drivers/scsi/3w-9xxx.c
... | ... | @@ -1695,8 +1695,6 @@ |
1695 | 1695 | |
1696 | 1696 | tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata; |
1697 | 1697 | |
1698 | - spin_unlock_irq(tw_dev->host->host_lock); | |
1699 | - | |
1700 | 1698 | tw_dev->num_resets++; |
1701 | 1699 | |
1702 | 1700 | printk(KERN_WARNING "3w-9xxx: scsi%d: WARNING: (0x%02X:0x%04X): Unit #%d: Command (0x%x) timed out, resetting card.\n", tw_dev->host->host_no, TW_DRIVER, 0x2c, SCpnt->device->id, SCpnt->cmnd[0]); |
... | ... | @@ -1709,7 +1707,6 @@ |
1709 | 1707 | |
1710 | 1708 | retval = SUCCESS; |
1711 | 1709 | out: |
1712 | - spin_lock_irq(tw_dev->host->host_lock); | |
1713 | 1710 | return retval; |
1714 | 1711 | } /* End twa_scsi_eh_reset() */ |
1715 | 1712 |
drivers/scsi/3w-xxxx.c
... | ... | @@ -1430,8 +1430,6 @@ |
1430 | 1430 | |
1431 | 1431 | tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata; |
1432 | 1432 | |
1433 | - spin_unlock_irq(tw_dev->host->host_lock); | |
1434 | - | |
1435 | 1433 | tw_dev->num_resets++; |
1436 | 1434 | |
1437 | 1435 | printk(KERN_WARNING "3w-xxxx: scsi%d: WARNING: Unit #%d: Command (0x%x) timed out, resetting card.\n", tw_dev->host->host_no, SCpnt->device->id, SCpnt->cmnd[0]); |
... | ... | @@ -1444,7 +1442,6 @@ |
1444 | 1442 | |
1445 | 1443 | retval = SUCCESS; |
1446 | 1444 | out: |
1447 | - spin_lock_irq(tw_dev->host->host_lock); | |
1448 | 1445 | return retval; |
1449 | 1446 | } /* End tw_scsi_eh_reset() */ |
1450 | 1447 |
drivers/scsi/53c700.c
... | ... | @@ -1991,8 +1991,13 @@ |
1991 | 1991 | SCp->device->host->host_no, SCp->device->id, SCp->device->lun); |
1992 | 1992 | scsi_print_command(SCp); |
1993 | 1993 | |
1994 | + spin_lock_irq(SCp->device->host->host_lock); | |
1995 | + | |
1994 | 1996 | NCR_700_internal_bus_reset(SCp->device->host); |
1995 | 1997 | NCR_700_chip_reset(SCp->device->host); |
1998 | + | |
1999 | + spin_unlock_irq(SCp->device->host->host_lock); | |
2000 | + | |
1996 | 2001 | return SUCCESS; |
1997 | 2002 | } |
1998 | 2003 |
drivers/scsi/BusLogic.c
... | ... | @@ -2746,9 +2746,15 @@ |
2746 | 2746 | |
2747 | 2747 | unsigned int id = SCpnt->device->id; |
2748 | 2748 | struct BusLogic_TargetStatistics *stats = &HostAdapter->TargetStatistics[id]; |
2749 | + int rc; | |
2750 | + | |
2751 | + spin_lock_irq(SCpnt->device->host->host_lock); | |
2752 | + | |
2749 | 2753 | BusLogic_IncrementErrorCounter(&stats->HostAdapterResetsRequested); |
2750 | 2754 | |
2751 | - return BusLogic_ResetHostAdapter(HostAdapter, false); | |
2755 | + rc = BusLogic_ResetHostAdapter(HostAdapter, false); | |
2756 | + spin_unlock_irq(SCpnt->device->host->host_lock); | |
2757 | + return rc; | |
2752 | 2758 | } |
2753 | 2759 | |
2754 | 2760 | /* |
drivers/scsi/NCR53c406a.c
... | ... | @@ -725,6 +725,9 @@ |
725 | 725 | static int NCR53c406a_host_reset(Scsi_Cmnd * SCpnt) |
726 | 726 | { |
727 | 727 | DEB(printk("NCR53c406a_reset called\n")); |
728 | + | |
729 | + spin_lock_irq(SCpnt->device->host->host_lock); | |
730 | + | |
728 | 731 | outb(C4_IMG, CONFIG4); /* Select reg set 0 */ |
729 | 732 | outb(CHIP_RESET, CMD_REG); |
730 | 733 | outb(SCSI_NOP, CMD_REG); /* required after reset */ |
... | ... | @@ -732,6 +735,9 @@ |
732 | 735 | chip_init(); |
733 | 736 | |
734 | 737 | rtrc(2); |
738 | + | |
739 | + spin_unlock_irq(SCpnt->device->host->host_lock); | |
740 | + | |
735 | 741 | return SUCCESS; |
736 | 742 | } |
737 | 743 |
drivers/scsi/a2091.c
... | ... | @@ -222,6 +222,9 @@ |
222 | 222 | { |
223 | 223 | /* FIXME perform bus-specific reset */ |
224 | 224 | |
225 | + /* FIXME 2: kill this function, and let midlayer fall back | |
226 | + to the same action, calling wd33c93_host_reset() */ | |
227 | + | |
225 | 228 | spin_lock_irq(cmd->device->host->host_lock); |
226 | 229 | wd33c93_host_reset(cmd); |
227 | 230 | spin_unlock_irq(cmd->device->host->host_lock); |
drivers/scsi/a3000.c
... | ... | @@ -208,6 +208,9 @@ |
208 | 208 | static int a3000_bus_reset(Scsi_Cmnd *cmd) |
209 | 209 | { |
210 | 210 | /* FIXME perform bus-specific reset */ |
211 | + | |
212 | + /* FIXME 2: kill this entire function, which should | |
213 | + cause mid-layer to call wd33c93_host_reset anyway? */ | |
211 | 214 | |
212 | 215 | spin_lock_irq(cmd->device->host->host_lock); |
213 | 216 | wd33c93_host_reset(cmd); |
drivers/scsi/aacraid/linit.c
... | ... | @@ -384,10 +384,13 @@ |
384 | 384 | AAC_DRIVERNAME); |
385 | 385 | |
386 | 386 | |
387 | + spin_lock_irq(host->host_lock); | |
388 | + | |
387 | 389 | aac = (struct aac_dev *)host->hostdata; |
388 | 390 | if (aac_adapter_check_health(aac)) { |
389 | 391 | printk(KERN_ERR "%s: Host adapter appears dead\n", |
390 | 392 | AAC_DRIVERNAME); |
393 | + spin_unlock_irq(host->host_lock); | |
391 | 394 | return -ENODEV; |
392 | 395 | } |
393 | 396 | /* |
... | ... | @@ -418,6 +421,7 @@ |
418 | 421 | ssleep(1); |
419 | 422 | spin_lock_irq(host->host_lock); |
420 | 423 | } |
424 | + spin_unlock_irq(host->host_lock); | |
421 | 425 | printk(KERN_ERR "%s: SCSI bus appears hung\n", AAC_DRIVERNAME); |
422 | 426 | return -ETIMEDOUT; |
423 | 427 | } |
drivers/scsi/aha1542.c
... | ... | @@ -1530,7 +1530,6 @@ |
1530 | 1530 | * check for timeout, and if we are doing something like this |
1531 | 1531 | * we are pretty desperate anyways. |
1532 | 1532 | */ |
1533 | - spin_unlock_irq(SCpnt->device->host->host_lock); | |
1534 | 1533 | ssleep(4); |
1535 | 1534 | spin_lock_irq(SCpnt->device->host->host_lock); |
1536 | 1535 | |
1537 | 1536 | |
... | ... | @@ -1574,9 +1573,11 @@ |
1574 | 1573 | } |
1575 | 1574 | } |
1576 | 1575 | |
1576 | + spin_unlock_irq(SCpnt->device->host->host_lock); | |
1577 | 1577 | return SUCCESS; |
1578 | 1578 | |
1579 | 1579 | fail: |
1580 | + spin_unlock_irq(SCpnt->device->host->host_lock); | |
1580 | 1581 | return FAILED; |
1581 | 1582 | } |
1582 | 1583 |
drivers/scsi/aic7xxx_old.c
... | ... | @@ -10845,6 +10845,8 @@ |
10845 | 10845 | struct aic_dev_data *aic_dev; |
10846 | 10846 | |
10847 | 10847 | p = (struct aic7xxx_host *) cmd->device->host->hostdata; |
10848 | + spin_lock_irq(p->host->host_lock); | |
10849 | + | |
10848 | 10850 | aic_dev = AIC_DEV(cmd); |
10849 | 10851 | if(aic7xxx_position(cmd) < p->scb_data->numscbs) |
10850 | 10852 | { |
... | ... | @@ -10884,6 +10886,7 @@ |
10884 | 10886 | * longer have it. |
10885 | 10887 | */ |
10886 | 10888 | unpause_sequencer(p, FALSE); |
10889 | + spin_unlock_irq(p->host->host_lock); | |
10887 | 10890 | return SUCCESS; |
10888 | 10891 | } |
10889 | 10892 | |
... | ... | @@ -10907,7 +10910,6 @@ |
10907 | 10910 | unpause_sequencer(p, FALSE); |
10908 | 10911 | spin_unlock_irq(p->host->host_lock); |
10909 | 10912 | ssleep(2); |
10910 | - spin_lock_irq(p->host->host_lock); | |
10911 | 10913 | return SUCCESS; |
10912 | 10914 | } |
10913 | 10915 |
drivers/scsi/arm/fas216.c
... | ... | @@ -2659,6 +2659,8 @@ |
2659 | 2659 | { |
2660 | 2660 | FAS216_Info *info = (FAS216_Info *)SCpnt->device->host->hostdata; |
2661 | 2661 | |
2662 | + spin_lock_irq(info->host->host_lock); | |
2663 | + | |
2662 | 2664 | fas216_checkmagic(info); |
2663 | 2665 | |
2664 | 2666 | printk("scsi%d.%c: %s: resetting host\n", |
... | ... | @@ -2686,6 +2688,7 @@ |
2686 | 2688 | |
2687 | 2689 | fas216_init_chip(info); |
2688 | 2690 | |
2691 | + spin_unlock_irq(info->host->host_lock); | |
2689 | 2692 | return SUCCESS; |
2690 | 2693 | } |
2691 | 2694 |
drivers/scsi/dpt_i2o.c
... | ... | @@ -746,7 +746,7 @@ |
746 | 746 | } |
747 | 747 | |
748 | 748 | // This version of reset is called by the eh_error_handler |
749 | -static int adpt_reset(struct scsi_cmnd* cmd) | |
749 | +static int __adpt_reset(struct scsi_cmnd* cmd) | |
750 | 750 | { |
751 | 751 | adpt_hba* pHba; |
752 | 752 | int rcode; |
... | ... | @@ -760,6 +760,17 @@ |
760 | 760 | printk(KERN_WARNING"%s: HBA reset failed (%x)\n",pHba->name, rcode); |
761 | 761 | return FAILED; |
762 | 762 | } |
763 | +} | |
764 | + | |
765 | +static int adpt_reset(struct scsi_cmnd* cmd) | |
766 | +{ | |
767 | + int rc; | |
768 | + | |
769 | + spin_lock_irq(cmd->device->host->host_lock); | |
770 | + rc = __adpt_reset(cmd); | |
771 | + spin_unlock_irq(cmd->device->host->host_lock); | |
772 | + | |
773 | + return rc; | |
763 | 774 | } |
764 | 775 | |
765 | 776 | // This version of reset is called by the ioctls and indirectly from eh_error_handler via adpt_reset |
drivers/scsi/eata.c
... | ... | @@ -1948,16 +1948,20 @@ |
1948 | 1948 | ha->board_name, SCarg->device->channel, SCarg->device->id, |
1949 | 1949 | SCarg->device->lun, SCarg->pid); |
1950 | 1950 | |
1951 | + spin_lock_irq(shost->host_lock); | |
1952 | + | |
1951 | 1953 | if (SCarg->host_scribble == NULL) |
1952 | 1954 | printk("%s: reset, pid %ld inactive.\n", ha->board_name, SCarg->pid); |
1953 | 1955 | |
1954 | 1956 | if (ha->in_reset) { |
1955 | 1957 | printk("%s: reset, exit, already in reset.\n", ha->board_name); |
1958 | + spin_unlock_irq(shost->host_lock); | |
1956 | 1959 | return FAILED; |
1957 | 1960 | } |
1958 | 1961 | |
1959 | 1962 | if (wait_on_busy(shost->io_port, MAXLOOP)) { |
1960 | 1963 | printk("%s: reset, exit, timeout error.\n", ha->board_name); |
1964 | + spin_unlock_irq(shost->host_lock); | |
1961 | 1965 | return FAILED; |
1962 | 1966 | } |
1963 | 1967 | |
... | ... | @@ -2012,6 +2016,7 @@ |
2012 | 2016 | |
2013 | 2017 | if (do_dma(shost->io_port, 0, RESET_PIO)) { |
2014 | 2018 | printk("%s: reset, cannot reset, timeout error.\n", ha->board_name); |
2019 | + spin_unlock_irq(shost->host_lock); | |
2015 | 2020 | return FAILED; |
2016 | 2021 | } |
2017 | 2022 | |
2018 | 2023 | |
... | ... | @@ -2024,9 +2029,12 @@ |
2024 | 2029 | ha->in_reset = 1; |
2025 | 2030 | |
2026 | 2031 | spin_unlock_irq(shost->host_lock); |
2032 | + | |
2033 | + /* FIXME: use a sleep instead */ | |
2027 | 2034 | time = jiffies; |
2028 | 2035 | while ((jiffies - time) < (10 * HZ) && limit++ < 200000) |
2029 | 2036 | udelay(100L); |
2037 | + | |
2030 | 2038 | spin_lock_irq(shost->host_lock); |
2031 | 2039 | |
2032 | 2040 | printk("%s: reset, interrupts disabled, loops %d.\n", ha->board_name, limit); |
... | ... | @@ -2076,6 +2084,7 @@ |
2076 | 2084 | else |
2077 | 2085 | printk("%s: reset, exit.\n", ha->board_name); |
2078 | 2086 | |
2087 | + spin_unlock_irq(shost->host_lock); | |
2079 | 2088 | return SUCCESS; |
2080 | 2089 | } |
2081 | 2090 |
drivers/scsi/eata_pio.c
... | ... | @@ -486,8 +486,11 @@ |
486 | 486 | |
487 | 487 | DBG(DBG_ABNORM, printk(KERN_WARNING "eata_pio_reset called pid:%ld target:" " %x lun: %x reason %x\n", cmd->pid, cmd->device->id, cmd->device->lun, cmd->abort_reason)); |
488 | 488 | |
489 | + spin_lock_irq(host->host_lock); | |
490 | + | |
489 | 491 | if (HD(cmd)->state == RESET) { |
490 | 492 | printk(KERN_WARNING "eata_pio_reset: exit, already in reset.\n"); |
493 | + spin_unlock_irq(host->host_lock); | |
491 | 494 | return FAILED; |
492 | 495 | } |
493 | 496 | |
... | ... | @@ -535,6 +538,8 @@ |
535 | 538 | } |
536 | 539 | |
537 | 540 | HD(cmd)->state = 0; |
541 | + | |
542 | + spin_unlock_irq(host->host_lock); | |
538 | 543 | |
539 | 544 | if (success) { /* hmmm... */ |
540 | 545 | DBG(DBG_ABNORM, printk(KERN_WARNING "eata_pio_reset: exit, success.\n")); |
drivers/scsi/gvp11.c
... | ... | @@ -346,6 +346,10 @@ |
346 | 346 | { |
347 | 347 | /* FIXME perform bus-specific reset */ |
348 | 348 | |
349 | + /* FIXME 2: shouldn't we no-op this function (return | |
350 | + FAILED), and fall back to host reset function, | |
351 | + wd33c93_host_reset ? */ | |
352 | + | |
349 | 353 | spin_lock_irq(cmd->device->host->host_lock); |
350 | 354 | wd33c93_host_reset(cmd); |
351 | 355 | spin_unlock_irq(cmd->device->host->host_lock); |
drivers/scsi/ibmmca.c
... | ... | @@ -2237,7 +2237,7 @@ |
2237 | 2237 | return rc; |
2238 | 2238 | } |
2239 | 2239 | |
2240 | -static int ibmmca_host_reset(Scsi_Cmnd * cmd) | |
2240 | +static int __ibmmca_host_reset(Scsi_Cmnd * cmd) | |
2241 | 2241 | { |
2242 | 2242 | struct Scsi_Host *shpnt; |
2243 | 2243 | Scsi_Cmnd *cmd_aid; |
... | ... | @@ -2322,6 +2322,18 @@ |
2322 | 2322 | } |
2323 | 2323 | } |
2324 | 2324 | return SUCCESS; |
2325 | +} | |
2326 | + | |
2327 | +static int ibmmca_host_reset(Scsi_Cmnd * cmd) | |
2328 | +{ | |
2329 | + struct Scsi_Host *shpnt = cmd->device->host; | |
2330 | + int rc; | |
2331 | + | |
2332 | + spin_lock_irq(shpnt->host_lock); | |
2333 | + rc = __ibmmca_host_reset(cmd); | |
2334 | + spin_unlock_irq(shpnt->host_lock); | |
2335 | + | |
2336 | + return rc; | |
2325 | 2337 | } |
2326 | 2338 | |
2327 | 2339 | static int ibmmca_biosparam(struct scsi_device *sdev, struct block_device *bdev, sector_t capacity, int *info) |
drivers/scsi/ide-scsi.c
... | ... | @@ -46,6 +46,7 @@ |
46 | 46 | #include <linux/slab.h> |
47 | 47 | #include <linux/ide.h> |
48 | 48 | #include <linux/scatterlist.h> |
49 | +#include <linux/delay.h> | |
49 | 50 | |
50 | 51 | #include <asm/io.h> |
51 | 52 | #include <asm/bitops.h> |
52 | 53 | |
... | ... | @@ -1026,11 +1027,13 @@ |
1026 | 1027 | return FAILED; |
1027 | 1028 | } |
1028 | 1029 | |
1029 | - spin_lock_irq(&ide_lock); | |
1030 | + spin_lock_irq(cmd->device->host->host_lock); | |
1031 | + spin_lock(&ide_lock); | |
1030 | 1032 | |
1031 | 1033 | if (!scsi->pc || (req = scsi->pc->rq) != HWGROUP(drive)->rq || !HWGROUP(drive)->handler) { |
1032 | 1034 | printk (KERN_WARNING "ide-scsi: No active request in idescsi_eh_reset\n"); |
1033 | 1035 | spin_unlock(&ide_lock); |
1036 | + spin_unlock_irq(cmd->device->host->host_lock); | |
1034 | 1037 | return FAILED; |
1035 | 1038 | } |
1036 | 1039 | |
1037 | 1040 | |
1038 | 1041 | |
... | ... | @@ -1052,16 +1055,15 @@ |
1052 | 1055 | HWGROUP(drive)->rq = NULL; |
1053 | 1056 | HWGROUP(drive)->handler = NULL; |
1054 | 1057 | HWGROUP(drive)->busy = 1; /* will set this to zero when ide reset finished */ |
1055 | - spin_unlock_irq(&ide_lock); | |
1058 | + spin_unlock(&ide_lock); | |
1056 | 1059 | |
1057 | 1060 | ide_do_reset(drive); |
1058 | 1061 | |
1059 | 1062 | /* ide_do_reset starts a polling handler which restarts itself every 50ms until the reset finishes */ |
1060 | 1063 | |
1061 | 1064 | do { |
1062 | - set_current_state(TASK_UNINTERRUPTIBLE); | |
1063 | 1065 | spin_unlock_irq(cmd->device->host->host_lock); |
1064 | - schedule_timeout(HZ/20); | |
1066 | + msleep(50); | |
1065 | 1067 | spin_lock_irq(cmd->device->host->host_lock); |
1066 | 1068 | } while ( HWGROUP(drive)->handler ); |
1067 | 1069 | |
... | ... | @@ -1072,6 +1074,7 @@ |
1072 | 1074 | ret = FAILED; |
1073 | 1075 | } |
1074 | 1076 | |
1077 | + spin_unlock_irq(cmd->device->host->host_lock); | |
1075 | 1078 | return ret; |
1076 | 1079 | } |
1077 | 1080 |
drivers/scsi/ipr.c
... | ... | @@ -2885,7 +2885,7 @@ |
2885 | 2885 | * Return value: |
2886 | 2886 | * SUCCESS / FAILED |
2887 | 2887 | **/ |
2888 | -static int ipr_eh_host_reset(struct scsi_cmnd * scsi_cmd) | |
2888 | +static int __ipr_eh_host_reset(struct scsi_cmnd * scsi_cmd) | |
2889 | 2889 | { |
2890 | 2890 | struct ipr_ioa_cfg *ioa_cfg; |
2891 | 2891 | int rc; |
... | ... | @@ -2902,6 +2902,17 @@ |
2902 | 2902 | rc = ipr_reset_reload(ioa_cfg, IPR_SHUTDOWN_ABBREV); |
2903 | 2903 | |
2904 | 2904 | LEAVE; |
2905 | + return rc; | |
2906 | +} | |
2907 | + | |
2908 | +static int ipr_eh_host_reset(struct scsi_cmnd * cmd) | |
2909 | +{ | |
2910 | + int rc; | |
2911 | + | |
2912 | + spin_lock_irq(cmd->device->host->host_lock); | |
2913 | + rc = __ipr_eh_host_reset(cmd); | |
2914 | + spin_unlock_irq(cmd->device->host->host_lock); | |
2915 | + | |
2905 | 2916 | return rc; |
2906 | 2917 | } |
2907 | 2918 |
drivers/scsi/ips.c
... | ... | @@ -873,7 +873,7 @@ |
873 | 873 | /* */ |
874 | 874 | /****************************************************************************/ |
875 | 875 | static int |
876 | -ips_eh_reset(Scsi_Cmnd * SC) | |
876 | +__ips_eh_reset(Scsi_Cmnd * SC) | |
877 | 877 | { |
878 | 878 | int ret; |
879 | 879 | int i; |
... | ... | @@ -1058,6 +1058,18 @@ |
1058 | 1058 | return (SUCCESS); |
1059 | 1059 | #endif /* NO_IPS_RESET */ |
1060 | 1060 | |
1061 | +} | |
1062 | + | |
1063 | +static int | |
1064 | +ips_eh_reset(Scsi_Cmnd * SC) | |
1065 | +{ | |
1066 | + int rc; | |
1067 | + | |
1068 | + spin_lock_irq(SC->device->host->host_lock); | |
1069 | + rc = __ips_eh_reset(SC); | |
1070 | + spin_unlock_irq(SC->device->host->host_lock); | |
1071 | + | |
1072 | + return rc; | |
1061 | 1073 | } |
1062 | 1074 | |
1063 | 1075 | /****************************************************************************/ |
drivers/scsi/mac53c94.c
... | ... | @@ -103,7 +103,10 @@ |
103 | 103 | struct fsc_state *state = (struct fsc_state *) cmd->device->host->hostdata; |
104 | 104 | struct mac53c94_regs __iomem *regs = state->regs; |
105 | 105 | struct dbdma_regs __iomem *dma = state->dma; |
106 | + unsigned long flags; | |
106 | 107 | |
108 | + spin_lock_irqsave(cmd->device->host->host_lock, flags); | |
109 | + | |
107 | 110 | writel((RUN|PAUSE|FLUSH|WAKE) << 16, &dma->control); |
108 | 111 | writeb(CMD_SCSI_RESET, ®s->command); /* assert RST */ |
109 | 112 | udelay(100); /* leave it on for a while (>= 25us) */ |
... | ... | @@ -111,6 +114,8 @@ |
111 | 114 | udelay(20); |
112 | 115 | mac53c94_init(state); |
113 | 116 | writeb(CMD_NOP, ®s->command); |
117 | + | |
118 | + spin_unlock_irqrestore(cmd->device->host->host_lock, flags); | |
114 | 119 | return SUCCESS; |
115 | 120 | } |
116 | 121 |
drivers/scsi/mesh.c
... | ... | @@ -1715,9 +1715,12 @@ |
1715 | 1715 | struct mesh_state *ms = (struct mesh_state *) cmd->device->host->hostdata; |
1716 | 1716 | volatile struct mesh_regs __iomem *mr = ms->mesh; |
1717 | 1717 | volatile struct dbdma_regs __iomem *md = ms->dma; |
1718 | + unsigned long flags; | |
1718 | 1719 | |
1719 | 1720 | printk(KERN_DEBUG "mesh_host_reset\n"); |
1720 | 1721 | |
1722 | + spin_lock_irqsave(ms->host->host_lock, flags); | |
1723 | + | |
1721 | 1724 | /* Reset the controller & dbdma channel */ |
1722 | 1725 | out_le32(&md->control, (RUN|PAUSE|FLUSH|WAKE) << 16); /* stop dma */ |
1723 | 1726 | out_8(&mr->exception, 0xff); /* clear all exception bits */ |
... | ... | @@ -1739,6 +1742,7 @@ |
1739 | 1742 | /* Complete pending commands */ |
1740 | 1743 | handle_reset(ms); |
1741 | 1744 | |
1745 | + spin_unlock_irqrestore(ms->host->host_lock, flags); | |
1742 | 1746 | return SUCCESS; |
1743 | 1747 | } |
1744 | 1748 |
drivers/scsi/mvme147.c
... | ... | @@ -117,6 +117,9 @@ |
117 | 117 | { |
118 | 118 | /* FIXME perform bus-specific reset */ |
119 | 119 | |
120 | + /* FIXME 2: kill this function, and let midlayer fallback to | |
121 | + the same result, calling wd33c93_host_reset() */ | |
122 | + | |
120 | 123 | spin_lock_irq(cmd->device->host->host_lock); |
121 | 124 | wd33c93_host_reset(cmd); |
122 | 125 | spin_unlock_irq(cmd->device->host->host_lock); |
drivers/scsi/nsp32.c
... | ... | @@ -3051,11 +3051,14 @@ |
3051 | 3051 | nsp32_msg(KERN_INFO, "Host Reset"); |
3052 | 3052 | nsp32_dbg(NSP32_DEBUG_BUSRESET, "SCpnt=0x%x", SCpnt); |
3053 | 3053 | |
3054 | + spin_lock_irq(SCpnt->device->host->host_lock); | |
3055 | + | |
3054 | 3056 | nsp32hw_init(data); |
3055 | 3057 | nsp32_write2(base, IRQ_CONTROL, IRQ_CONTROL_ALL_IRQ_MASK); |
3056 | 3058 | nsp32_do_bus_reset(data); |
3057 | 3059 | nsp32_write2(base, IRQ_CONTROL, 0); |
3058 | 3060 | |
3061 | + spin_unlock_irq(SCpnt->device->host->host_lock); | |
3059 | 3062 | return SUCCESS; /* Host reset is succeeded at any time. */ |
3060 | 3063 | } |
3061 | 3064 |
drivers/scsi/pcmcia/sym53c500_cs.c
... | ... | @@ -627,7 +627,9 @@ |
627 | 627 | int port_base = SCpnt->device->host->io_port; |
628 | 628 | |
629 | 629 | DEB(printk("SYM53C500_host_reset called\n")); |
630 | + spin_lock_irq(SCpnt->device->host->host_lock); | |
630 | 631 | SYM53C500_int_host_reset(port_base); |
632 | + spin_unlock_irq(SCpnt->device->host->host_lock); | |
631 | 633 | |
632 | 634 | return SUCCESS; |
633 | 635 | } |
drivers/scsi/qla1280.c
... | ... | @@ -1146,7 +1146,13 @@ |
1146 | 1146 | static int |
1147 | 1147 | qla1280_eh_adapter_reset(struct scsi_cmnd *cmd) |
1148 | 1148 | { |
1149 | - return qla1280_error_action(cmd, ADAPTER_RESET); | |
1149 | + int rc; | |
1150 | + | |
1151 | + spin_lock_irq(cmd->device->host->host_lock); | |
1152 | + rc = qla1280_error_action(cmd, ADAPTER_RESET); | |
1153 | + spin_unlock_irq(cmd->device->host->host_lock); | |
1154 | + | |
1155 | + return rc; | |
1150 | 1156 | } |
1151 | 1157 | |
1152 | 1158 | static int |
drivers/scsi/qla2xxx/qla_os.c
... | ... | @@ -815,8 +815,6 @@ |
815 | 815 | qla_printk(KERN_INFO, ha, |
816 | 816 | "scsi(%ld:%d:%d): ADAPTER RESET ISSUED.\n", ha->host_no, id, lun); |
817 | 817 | |
818 | - spin_unlock_irq(ha->host->host_lock); | |
819 | - | |
820 | 818 | if (qla2x00_wait_for_hba_online(ha) != QLA_SUCCESS) |
821 | 819 | goto eh_host_reset_lock; |
822 | 820 | |
... | ... | @@ -845,8 +843,6 @@ |
845 | 843 | ret = SUCCESS; |
846 | 844 | |
847 | 845 | eh_host_reset_lock: |
848 | - spin_lock_irq(ha->host->host_lock); | |
849 | - | |
850 | 846 | qla_printk(KERN_INFO, ha, "%s: reset %s\n", __func__, |
851 | 847 | (ret == FAILED) ? "failed" : "succeded"); |
852 | 848 |
drivers/scsi/scsi_error.c
... | ... | @@ -1082,9 +1082,7 @@ |
1082 | 1082 | if (!scmd->device->host->hostt->eh_host_reset_handler) |
1083 | 1083 | return FAILED; |
1084 | 1084 | |
1085 | - spin_lock_irqsave(scmd->device->host->host_lock, flags); | |
1086 | 1085 | rtn = scmd->device->host->hostt->eh_host_reset_handler(scmd); |
1087 | - spin_unlock_irqrestore(scmd->device->host->host_lock, flags); | |
1088 | 1086 | |
1089 | 1087 | if (rtn == SUCCESS) { |
1090 | 1088 | if (!scmd->device->host->hostt->skip_settle_delay) |
drivers/scsi/sgiwd93.c
... | ... | @@ -311,6 +311,9 @@ |
311 | 311 | { |
312 | 312 | /* FIXME perform bus-specific reset */ |
313 | 313 | |
314 | + /* FIXME 2: kill this function, and let midlayer fallback | |
315 | + to the same result, calling wd33c93_host_reset() */ | |
316 | + | |
314 | 317 | spin_lock_irq(cmd->device->host->host_lock); |
315 | 318 | wd33c93_host_reset(cmd); |
316 | 319 | spin_unlock_irq(cmd->device->host->host_lock); |
drivers/scsi/sym53c416.c
... | ... | @@ -790,7 +790,10 @@ |
790 | 790 | int base; |
791 | 791 | int scsi_id = -1; |
792 | 792 | int i; |
793 | + unsigned long flags; | |
793 | 794 | |
795 | + spin_lock_irqsave(&sym53c416_lock, flags); | |
796 | + | |
794 | 797 | /* printk("sym53c416_reset\n"); */ |
795 | 798 | base = SCpnt->device->host->io_port; |
796 | 799 | /* search scsi_id - fixme, we shouldnt need to iterate for this! */ |
... | ... | @@ -801,6 +804,8 @@ |
801 | 804 | outb(NOOP | PIO_MODE, base + COMMAND_REG); |
802 | 805 | outb(RESET_SCSI_BUS, base + COMMAND_REG); |
803 | 806 | sym53c416_init(base, scsi_id); |
807 | + | |
808 | + spin_unlock_irqrestore(&sym53c416_lock, flags); | |
804 | 809 | return SUCCESS; |
805 | 810 | } |
806 | 811 |
drivers/scsi/sym53c8xx_2/sym_glue.c
... | ... | @@ -889,7 +889,13 @@ |
889 | 889 | |
890 | 890 | static int sym53c8xx_eh_host_reset_handler(struct scsi_cmnd *cmd) |
891 | 891 | { |
892 | - return sym_eh_handler(SYM_EH_HOST_RESET, "HOST RESET", cmd); | |
892 | + int rc; | |
893 | + | |
894 | + spin_lock_irq(cmd->device->host->host_lock); | |
895 | + rc = sym_eh_handler(SYM_EH_HOST_RESET, "HOST RESET", cmd); | |
896 | + spin_unlock_irq(cmd->device->host->host_lock); | |
897 | + | |
898 | + return rc; | |
893 | 899 | } |
894 | 900 | |
895 | 901 | /* |
drivers/scsi/u14-34f.c
... | ... | @@ -1417,16 +1417,20 @@ |
1417 | 1417 | printk("%s: reset, enter, target %d.%d:%d, pid %ld.\n", |
1418 | 1418 | BN(j), SCarg->device->channel, SCarg->device->id, SCarg->device->lun, SCarg->pid); |
1419 | 1419 | |
1420 | + spin_lock_irq(sh[j]->host_lock); | |
1421 | + | |
1420 | 1422 | if (SCarg->host_scribble == NULL) |
1421 | 1423 | printk("%s: reset, pid %ld inactive.\n", BN(j), SCarg->pid); |
1422 | 1424 | |
1423 | 1425 | if (HD(j)->in_reset) { |
1424 | 1426 | printk("%s: reset, exit, already in reset.\n", BN(j)); |
1427 | + spin_unlock_irq(sh[j]->host_lock); | |
1425 | 1428 | return FAILED; |
1426 | 1429 | } |
1427 | 1430 | |
1428 | 1431 | if (wait_on_busy(sh[j]->io_port, MAXLOOP)) { |
1429 | 1432 | printk("%s: reset, exit, timeout error.\n", BN(j)); |
1433 | + spin_unlock_irq(sh[j]->host_lock); | |
1430 | 1434 | return FAILED; |
1431 | 1435 | } |
1432 | 1436 | |
... | ... | @@ -1477,6 +1481,7 @@ |
1477 | 1481 | |
1478 | 1482 | if (wait_on_busy(sh[j]->io_port, MAXLOOP)) { |
1479 | 1483 | printk("%s: reset, cannot reset, timeout error.\n", BN(j)); |
1484 | + spin_unlock_irq(sh[j]->host_lock); | |
1480 | 1485 | return FAILED; |
1481 | 1486 | } |
1482 | 1487 | |
... | ... | @@ -1538,6 +1543,7 @@ |
1538 | 1543 | if (arg_done) printk("%s: reset, exit, pid %ld done.\n", BN(j), SCarg->pid); |
1539 | 1544 | else printk("%s: reset, exit.\n", BN(j)); |
1540 | 1545 | |
1546 | + spin_unlock_irq(sh[j]->host_lock); | |
1541 | 1547 | return SUCCESS; |
1542 | 1548 | } |
1543 | 1549 |
drivers/scsi/wd7000.c
... | ... | @@ -1586,9 +1586,16 @@ |
1586 | 1586 | { |
1587 | 1587 | Adapter *host = (Adapter *) SCpnt->device->host->hostdata; |
1588 | 1588 | |
1589 | - if (wd7000_adapter_reset(host) < 0) | |
1589 | + spin_unlock_irq(SCpnt->device->host->host_lock); | |
1590 | + | |
1591 | + if (wd7000_adapter_reset(host) < 0) { | |
1592 | + spin_unlock_irq(SCpnt->device->host->host_lock); | |
1590 | 1593 | return FAILED; |
1594 | + } | |
1595 | + | |
1591 | 1596 | wd7000_enable_intr(host); |
1597 | + | |
1598 | + spin_unlock_irq(SCpnt->device->host->host_lock); | |
1592 | 1599 | return SUCCESS; |
1593 | 1600 | } |
1594 | 1601 |