From 54d8fe4425c9d3fdf8473c1833c6807b61c6e70e Mon Sep 17 00:00:00 2001 From: Finn Thain Date: Sun, 3 Jan 2016 16:05:06 +1100 Subject: ncr5380: Remove NCR5380_local_declare and NCR5380_setup macros The NCR5380_local_declare and NCR5380_setup macros exist to define and initialize a particular local variable, to provide the address of the chip registers needed for the driver's implementation of its NCR5380_read/write register access macros. In cumana_1 and macscsi, these macros generate pointless code like this, struct Scsi_Host *_instance; _instance = instance; In pas16, the use of NCR5380_read/write in pas16_hw_detect() requires that the io_port local variable has been defined and initialized, but the NCR5380_local_declare and NCR5380_setup macros can't be used for that purpose because the Scsi_Host struct has not yet been instantiated. Moreover, these macros were removed from atari_NCR5380.c long ago and now they constitute yet another discrepancy between the two core driver forks. Remove these "optimizations". Signed-off-by: Finn Thain Reviewed-by: Hannes Reinecke Tested-by: Ondrej Zary Signed-off-by: Martin K. Petersen --- drivers/scsi/mac_scsi.c | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) (limited to 'drivers/scsi/mac_scsi.c') diff --git a/drivers/scsi/mac_scsi.c b/drivers/scsi/mac_scsi.c index d64a769b8155..e49a9b1d7c3d 100644 --- a/drivers/scsi/mac_scsi.c +++ b/drivers/scsi/mac_scsi.c @@ -32,11 +32,9 @@ #define PSEUDO_DMA #define NCR5380_implementation_fields unsigned char *pdma_base -#define NCR5380_local_declare() struct Scsi_Host *_instance -#define NCR5380_setup(instance) _instance = instance -#define NCR5380_read(reg) macscsi_read(_instance, reg) -#define NCR5380_write(reg, value) macscsi_write(_instance, reg, value) +#define NCR5380_read(reg) macscsi_read(instance, reg) +#define NCR5380_write(reg, value) macscsi_write(instance, reg, value) #define NCR5380_pread macscsi_pread #define NCR5380_pwrite macscsi_pwrite @@ -129,9 +127,6 @@ static void mac_scsi_reset_boot(struct Scsi_Host *instance) { unsigned long end; - NCR5380_local_declare(); - NCR5380_setup(instance); - /* * Do a SCSI reset to clean up the bus during initialization. No messing * with the queues, interrupts, or locks necessary here. @@ -235,9 +230,6 @@ static int macscsi_pread(struct Scsi_Host *instance, unsigned char *d; unsigned char *s; - NCR5380_local_declare(); - NCR5380_setup(instance); - s = hostdata->pdma_base + (INPUT_DATA_REG << 4); d = dst; @@ -329,9 +321,6 @@ static int macscsi_pwrite(struct Scsi_Host *instance, unsigned char *s; unsigned char *d; - NCR5380_local_declare(); - NCR5380_setup(instance); - s = src; d = hostdata->pdma_base + (OUTPUT_DATA_REG << 4); -- cgit v1.2.3 From 9c3f0e2b52ada30fe72beec27b83e91e12566609 Mon Sep 17 00:00:00 2001 From: Finn Thain Date: Sun, 3 Jan 2016 16:05:11 +1100 Subject: atari_NCR5380: Remove RESET_BOOT, CONFIG_ATARI_SCSI_TOSHIBA_DELAY and CONFIG_ATARI_SCSI_RESET_BOOT The atari_NCR5380.c core driver now takes care of bus reset upon driver initialization if required (same as NCR5380.c). Move the Toshiba CD-ROM support into the core driver, enabled with a host flag, so that all NCR5380 drivers can make use of it. Drop the RESET_BOOT macros and the ATARI_SCSI_RESET_BOOT and ATARI_SCSI_TOSHIBA_DELAY Kconfig symbols, which are now redundant. Remove the atari_scsi_reset_boot(), mac_scsi_reset_boot() and sun3_scsi_reset_boot() routines. None of this duplicated code is needed now that all drivers can use NCR5380_maybe_reset_bus(). This brings atari_scsi, mac_scsi and sun3_scsi into line with all of the other NCR5380 drivers. The bus reset may raise an interrupt. That would be new behaviour for atari_scsi only when CONFIG_ATARI_SCSI_RESET_BOOT=n. The ST DMA interrupt is not assigned to atari_scsi at this stage, so CONFIG_ATARI_SCSI_RESET_BOOT=y may well be problematic already. Regardless, do_reset() now raises and clears the interrupt within local_irq_save/restore which should avoid problems. Signed-off-by: Finn Thain Reviewed-by: Hannes Reinecke Tested-by: Ondrej Zary Tested-by: Michael Schmitz Signed-off-by: Martin K. Petersen --- drivers/scsi/Kconfig | 17 ------------ drivers/scsi/NCR5380.c | 17 ++++++++++-- drivers/scsi/NCR5380.h | 1 + drivers/scsi/atari_NCR5380.c | 22 ++++++++++----- drivers/scsi/atari_scsi.c | 60 ++++++---------------------------------- drivers/scsi/mac_scsi.c | 65 +++++++------------------------------------- drivers/scsi/sun3_scsi.c | 47 +------------------------------- 7 files changed, 51 insertions(+), 178 deletions(-) (limited to 'drivers/scsi/mac_scsi.c') diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index 37dce2380a52..abdd4360e219 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig @@ -1617,23 +1617,6 @@ config ATARI_SCSI ST-DMA, replacing ACSI). It does NOT support other schemes, like in the Hades (without DMA). -config ATARI_SCSI_TOSHIBA_DELAY - bool "Long delays for Toshiba CD-ROMs" - depends on ATARI_SCSI - help - This option increases the delay after a SCSI arbitration to - accommodate some flaky Toshiba CD-ROM drives. Say Y if you intend to - use a Toshiba CD-ROM drive; otherwise, the option is not needed and - would impact performance a bit, so say N. - -config ATARI_SCSI_RESET_BOOT - bool "Reset SCSI-devices at boottime" - depends on ATARI_SCSI - help - Reset the devices on your Atari whenever it boots. This makes the - boot process fractionally longer but may assist recovery from errors - that leave the devices with SCSI operations partway completed. - config MAC_SCSI tristate "Macintosh NCR5380 SCSI" depends on MAC && SCSI=y diff --git a/drivers/scsi/NCR5380.c b/drivers/scsi/NCR5380.c index 391ee8db5de1..7ccf2e37b6ad 100644 --- a/drivers/scsi/NCR5380.c +++ b/drivers/scsi/NCR5380.c @@ -618,7 +618,7 @@ static void prepare_info(struct Scsi_Host *instance) "base 0x%lx, irq %d, " "can_queue %d, cmd_per_lun %d, " "sg_tablesize %d, this_id %d, " - "flags { %s%s%s}, " + "flags { %s%s%s%s}, " #if defined(USLEEP_POLL) && defined(USLEEP_WAITLONG) "USLEEP_POLL %lu, USLEEP_WAITLONG %lu, " #endif @@ -630,6 +630,7 @@ static void prepare_info(struct Scsi_Host *instance) hostdata->flags & FLAG_NCR53C400 ? "NCR53C400 " : "", hostdata->flags & FLAG_DTC3181E ? "DTC3181E " : "", hostdata->flags & FLAG_NO_PSEUDO_DMA ? "NO_PSEUDO_DMA " : "", + hostdata->flags & FLAG_TOSHIBA_DELAY ? "TOSHIBA_DELAY " : "", #if defined(USLEEP_POLL) && defined(USLEEP_WAITLONG) USLEEP_POLL, USLEEP_WAITLONG, #endif @@ -831,6 +832,7 @@ static int NCR5380_init(struct Scsi_Host *instance, int flags) static int NCR5380_maybe_reset_bus(struct Scsi_Host *instance) { + struct NCR5380_hostdata *hostdata = shost_priv(instance); int pass; for (pass = 1; (NCR5380_read(STATUS_REG) & SR_BSY) && pass <= 6; ++pass) { @@ -849,6 +851,14 @@ static int NCR5380_maybe_reset_bus(struct Scsi_Host *instance) case 4: shost_printk(KERN_ERR, instance, "bus busy, attempting reset\n"); do_reset(instance); + /* Wait after a reset; the SCSI standard calls for + * 250ms, we wait 500ms to be on the safe side. + * But some Toshiba CD-ROMs need ten times that. + */ + if (hostdata->flags & FLAG_TOSHIBA_DELAY) + msleep(2500); + else + msleep(500); break; case 6: shost_printk(KERN_ERR, instance, "bus locked solid\n"); @@ -1253,7 +1263,10 @@ static int NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd) * a minimum so we'll udelay ceil(1.2) */ - udelay(2); + if (hostdata->flags & FLAG_TOSHIBA_DELAY) + udelay(15); + else + udelay(2); dprintk(NDEBUG_ARBITRATION, "scsi%d : won arbitration\n", instance->host_no); diff --git a/drivers/scsi/NCR5380.h b/drivers/scsi/NCR5380.h index 2057eaa66c20..f2f737a5f75a 100644 --- a/drivers/scsi/NCR5380.h +++ b/drivers/scsi/NCR5380.h @@ -243,6 +243,7 @@ #define FLAG_DTC3181E 16 /* DTC3181E */ #define FLAG_LATE_DMA_SETUP 32 /* Setup NCR before DMA H/W */ #define FLAG_TAGGED_QUEUING 64 /* as X3T9.2 spelled it */ +#define FLAG_TOSHIBA_DELAY 128 /* Allow for borken CD-ROMs */ #ifdef SUPPORT_TAGS struct tag_alloc { diff --git a/drivers/scsi/atari_NCR5380.c b/drivers/scsi/atari_NCR5380.c index a15b655aa2b0..de53cda4b153 100644 --- a/drivers/scsi/atari_NCR5380.c +++ b/drivers/scsi/atari_NCR5380.c @@ -674,13 +674,14 @@ static void prepare_info(struct Scsi_Host *instance) "base 0x%lx, irq %d, " "can_queue %d, cmd_per_lun %d, " "sg_tablesize %d, this_id %d, " - "flags { %s}, " + "flags { %s%s}, " "options { %s} ", instance->hostt->name, instance->io_port, instance->n_io_port, instance->base, instance->irq, instance->can_queue, instance->cmd_per_lun, instance->sg_tablesize, instance->this_id, hostdata->flags & FLAG_TAGGED_QUEUING ? "TAGGED_QUEUING " : "", + hostdata->flags & FLAG_TOSHIBA_DELAY ? "TOSHIBA_DELAY " : "", #ifdef DIFFERENTIAL "DIFFERENTIAL " #endif @@ -860,6 +861,7 @@ static int __init NCR5380_init(struct Scsi_Host *instance, int flags) static int NCR5380_maybe_reset_bus(struct Scsi_Host *instance) { + struct NCR5380_hostdata *hostdata = shost_priv(instance); int pass; for (pass = 1; (NCR5380_read(STATUS_REG) & SR_BSY) && pass <= 6; ++pass) { @@ -878,6 +880,14 @@ static int NCR5380_maybe_reset_bus(struct Scsi_Host *instance) case 4: shost_printk(KERN_ERR, instance, "bus busy, attempting reset\n"); do_reset(instance); + /* Wait after a reset; the SCSI standard calls for + * 250ms, we wait 500ms to be on the safe side. + * But some Toshiba CD-ROMs need ten times that. + */ + if (hostdata->flags & FLAG_TOSHIBA_DELAY) + msleep(2500); + else + msleep(500); break; case 6: shost_printk(KERN_ERR, instance, "bus locked solid\n"); @@ -1493,12 +1503,10 @@ static int NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd) * a minimum so we'll udelay ceil(1.2) */ -#ifdef CONFIG_ATARI_SCSI_TOSHIBA_DELAY - /* ++roman: But some targets (see above :-) seem to need a bit more... */ - udelay(15); -#else - udelay(2); -#endif + if (hostdata->flags & FLAG_TOSHIBA_DELAY) + udelay(15); + else + udelay(2); if (hostdata->connected) { NCR5380_write(MODE_REG, MR_BASE); diff --git a/drivers/scsi/atari_scsi.c b/drivers/scsi/atari_scsi.c index 1852ed6e8a48..5b233ccae962 100644 --- a/drivers/scsi/atari_scsi.c +++ b/drivers/scsi/atari_scsi.c @@ -164,15 +164,6 @@ static inline unsigned long SCSI_DMA_GETADR(void) #define HOSTDATA_DMALEN (((struct NCR5380_hostdata *) \ (atari_scsi_host->hostdata))->dma_len) -/* Time (in jiffies) to wait after a reset; the SCSI standard calls for 250ms, - * we usually do 0.5s to be on the safe side. But Toshiba CD-ROMs once more - * need ten times the standard value... */ -#ifndef CONFIG_ATARI_SCSI_TOSHIBA_DELAY -#define AFTER_RESET_DELAY (HZ/2) -#else -#define AFTER_RESET_DELAY (5*HZ/2) -#endif - #ifdef REAL_DMA static void atari_scsi_fetch_restbytes(void); #endif @@ -208,12 +199,12 @@ static int setup_cmd_per_lun = -1; module_param(setup_cmd_per_lun, int, 0); static int setup_sg_tablesize = -1; module_param(setup_sg_tablesize, int, 0); -#ifdef SUPPORT_TAGS static int setup_use_tagged_queuing = -1; module_param(setup_use_tagged_queuing, int, 0); -#endif static int setup_hostid = -1; module_param(setup_hostid, int, 0); +static int setup_toshiba_delay = -1; +module_param(setup_toshiba_delay, int, 0); #if defined(REAL_DMA) @@ -488,7 +479,7 @@ static int __init atari_scsi_setup(char *str) * Defaults depend on TT or Falcon, determined at run time. * Negative values mean don't change. */ - int ints[6]; + int ints[8]; get_options(str, ARRAY_SIZE(ints), ints); @@ -504,10 +495,11 @@ static int __init atari_scsi_setup(char *str) setup_sg_tablesize = ints[3]; if (ints[0] >= 4) setup_hostid = ints[4]; -#ifdef SUPPORT_TAGS if (ints[0] >= 5) setup_use_tagged_queuing = ints[5]; -#endif + /* ints[6] (use_pdma) is ignored */ + if (ints[0] >= 7) + setup_toshiba_delay = ints[7]; return 1; } @@ -516,38 +508,6 @@ __setup("atascsi=", atari_scsi_setup); #endif /* !MODULE */ -#ifdef CONFIG_ATARI_SCSI_RESET_BOOT -static void __init atari_scsi_reset_boot(void) -{ - unsigned long end; - - /* - * Do a SCSI reset to clean up the bus during initialization. No messing - * with the queues, interrupts, or locks necessary here. - */ - - printk("Atari SCSI: resetting the SCSI bus..."); - - /* get in phase */ - NCR5380_write(TARGET_COMMAND_REG, - PHASE_SR_TO_TCR(NCR5380_read(STATUS_REG))); - - /* assert RST */ - NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_RST); - /* The min. reset hold time is 25us, so 40us should be enough */ - udelay(50); - /* reset RST and interrupt */ - NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); - NCR5380_read(RESET_PARITY_INTERRUPT_REG); - - end = jiffies + AFTER_RESET_DELAY; - while (time_before(jiffies, end)) - barrier(); - - printk(" done\n"); -} -#endif - #if defined(REAL_DMA) static unsigned long atari_scsi_dma_setup(struct Scsi_Host *instance, @@ -917,17 +877,13 @@ static int __init atari_scsi_probe(struct platform_device *pdev) } atari_scsi_host = instance; -#ifdef CONFIG_ATARI_SCSI_RESET_BOOT - atari_scsi_reset_boot(); -#endif - instance->irq = irq->start; host_flags |= IS_A_TT() ? 0 : FLAG_LATE_DMA_SETUP; - #ifdef SUPPORT_TAGS host_flags |= setup_use_tagged_queuing > 0 ? FLAG_TAGGED_QUEUING : 0; #endif + host_flags |= setup_toshiba_delay > 0 ? FLAG_TOSHIBA_DELAY : 0; NCR5380_init(instance, host_flags); @@ -975,6 +931,8 @@ static int __init atari_scsi_probe(struct platform_device *pdev) #endif } + NCR5380_maybe_reset_bus(instance); + error = scsi_add_host(instance, NULL); if (error) goto fail_host; diff --git a/drivers/scsi/mac_scsi.c b/drivers/scsi/mac_scsi.c index e49a9b1d7c3d..4d26ef93e656 100644 --- a/drivers/scsi/mac_scsi.c +++ b/drivers/scsi/mac_scsi.c @@ -49,8 +49,6 @@ #include "NCR5380.h" -#define RESET_BOOT - static int setup_can_queue = -1; module_param(setup_can_queue, int, 0); static int setup_cmd_per_lun = -1; @@ -63,17 +61,8 @@ static int setup_use_tagged_queuing = -1; module_param(setup_use_tagged_queuing, int, 0); static int setup_hostid = -1; module_param(setup_hostid, int, 0); - -/* Time (in jiffies) to wait after a reset; the SCSI standard calls for 250ms, - * we usually do 0.5s to be on the safe side. But Toshiba CD-ROMs once more - * need ten times the standard value... */ -#define TOSHIBA_DELAY - -#ifdef TOSHIBA_DELAY -#define AFTER_RESET_DELAY (5*HZ/2) -#else -#define AFTER_RESET_DELAY (HZ/2) -#endif +static int setup_toshiba_delay = -1; +module_param(setup_toshiba_delay, int, 0); /* * NCR 5380 register access functions @@ -92,12 +81,12 @@ static inline void macscsi_write(struct Scsi_Host *instance, int reg, int value) #ifndef MODULE static int __init mac_scsi_setup(char *str) { - int ints[7]; + int ints[8]; (void)get_options(str, ARRAY_SIZE(ints), ints); - if (ints[0] < 1 || ints[0] > 6) { - pr_err("Usage: mac5380=[,[,[,[,[,]]]]]\n"); + if (ints[0] < 1) { + pr_err("Usage: mac5380=[,[,[,[,[,[,]]]]]]\n"); return 0; } if (ints[0] >= 1) @@ -112,47 +101,14 @@ static int __init mac_scsi_setup(char *str) setup_use_tagged_queuing = ints[5]; if (ints[0] >= 6) setup_use_pdma = ints[6]; + if (ints[0] >= 7) + setup_toshiba_delay = ints[7]; return 1; } __setup("mac5380=", mac_scsi_setup); #endif /* !MODULE */ -#ifdef RESET_BOOT -/* - * Our 'bus reset on boot' function - */ - -static void mac_scsi_reset_boot(struct Scsi_Host *instance) -{ - unsigned long end; - - /* - * Do a SCSI reset to clean up the bus during initialization. No messing - * with the queues, interrupts, or locks necessary here. - */ - - printk(KERN_INFO "Macintosh SCSI: resetting the SCSI bus..." ); - - /* get in phase */ - NCR5380_write( TARGET_COMMAND_REG, - PHASE_SR_TO_TCR( NCR5380_read(STATUS_REG) )); - - /* assert RST */ - NCR5380_write( INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_RST ); - /* The min. reset hold time is 25us, so 40us should be enough */ - udelay( 50 ); - /* reset RST and interrupt */ - NCR5380_write( INITIATOR_COMMAND_REG, ICR_BASE ); - NCR5380_read( RESET_PARITY_INTERRUPT_REG ); - - for( end = jiffies + AFTER_RESET_DELAY; time_before(jiffies, end); ) - barrier(); - - printk(KERN_INFO " done\n" ); -} -#endif - #ifdef PSEUDO_DMA /* Pseudo-DMA: (Ove Edlund) @@ -421,13 +377,10 @@ static int __init mac_scsi_probe(struct platform_device *pdev) } else host_flags |= FLAG_NO_PSEUDO_DMA; -#ifdef RESET_BOOT - mac_scsi_reset_boot(instance); -#endif - #ifdef SUPPORT_TAGS host_flags |= setup_use_tagged_queuing > 0 ? FLAG_TAGGED_QUEUING : 0; #endif + host_flags |= setup_toshiba_delay > 0 ? FLAG_TOSHIBA_DELAY : 0; NCR5380_init(instance, host_flags); @@ -438,6 +391,8 @@ static int __init mac_scsi_probe(struct platform_device *pdev) goto fail_irq; } + NCR5380_maybe_reset_bus(instance); + error = scsi_add_host(instance, NULL); if (error) goto fail_host; diff --git a/drivers/scsi/sun3_scsi.c b/drivers/scsi/sun3_scsi.c index 836f5ca6d209..9376b3d8bfdc 100644 --- a/drivers/scsi/sun3_scsi.c +++ b/drivers/scsi/sun3_scsi.c @@ -86,10 +86,6 @@ module_param(setup_use_tagged_queuing, int, 0); static int setup_hostid = -1; module_param(setup_hostid, int, 0); -/* #define RESET_BOOT */ - -#define AFTER_RESET_DELAY (HZ/2) - /* ms to wait after hitting dma regs */ #define SUN3_DMA_DELAY 10 @@ -144,45 +140,6 @@ static inline void sun3_udc_write(unsigned short val, unsigned char reg) } #endif -#ifdef RESET_BOOT -static void sun3_scsi_reset_boot(struct Scsi_Host *instance) -{ - unsigned long end; - - /* - * Do a SCSI reset to clean up the bus during initialization. No - * messing with the queues, interrupts, or locks necessary here. - */ - - printk( "Sun3 SCSI: resetting the SCSI bus..." ); - - /* switch off SCSI IRQ - catch an interrupt without IRQ bit set else */ -// sun3_disable_irq( IRQ_SUN3_SCSI ); - - /* get in phase */ - NCR5380_write( TARGET_COMMAND_REG, - PHASE_SR_TO_TCR( NCR5380_read(STATUS_REG) )); - - /* assert RST */ - NCR5380_write( INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_RST ); - - /* The min. reset hold time is 25us, so 40us should be enough */ - udelay( 50 ); - - /* reset RST and interrupt */ - NCR5380_write( INITIATOR_COMMAND_REG, ICR_BASE ); - NCR5380_read( RESET_PARITY_INTERRUPT_REG ); - - for( end = jiffies + AFTER_RESET_DELAY; time_before(jiffies, end); ) - barrier(); - - /* switch on SCSI IRQ again */ -// sun3_enable_irq( IRQ_SUN3_SCSI ); - - printk( " done\n" ); -} -#endif - // safe bits for the CSR #define CSR_GOOD 0x060f @@ -631,9 +588,7 @@ static int __init sun3_scsi_probe(struct platform_device *pdev) dregs->ivect = VME_DATA24 | (instance->irq & 0xff); #endif -#ifdef RESET_BOOT - sun3_scsi_reset_boot(instance); -#endif + NCR5380_maybe_reset_bus(instance); error = scsi_add_host(instance, NULL); if (error) -- cgit v1.2.3 From 0ad0eff98fec3c940ec199047ff580abaaa5bb1a Mon Sep 17 00:00:00 2001 From: Finn Thain Date: Sun, 3 Jan 2016 16:05:21 +1100 Subject: ncr5380: Introduce unbound workqueue Allocate a work queue that will permit busy waiting and sleeping. This means NCR5380_init() can potentially fail, so add this error path. Signed-off-by: Finn Thain Reviewed-by: Hannes Reinecke Tested-by: Ondrej Zary Tested-by: Michael Schmitz Signed-off-by: Martin K. Petersen --- drivers/scsi/NCR5380.c | 15 +++++++++++---- drivers/scsi/NCR5380.h | 1 + drivers/scsi/arm/cumana_1.c | 8 ++++++-- drivers/scsi/arm/oak.c | 8 ++++++-- drivers/scsi/atari_NCR5380.c | 8 +++++++- drivers/scsi/atari_scsi.c | 5 ++++- drivers/scsi/dmx3191d.c | 17 +++++++++++------ drivers/scsi/dtc.c | 11 +++++++++-- drivers/scsi/g_NCR5380.c | 31 +++++++++++++++---------------- drivers/scsi/mac_scsi.c | 5 ++++- drivers/scsi/pas16.c | 10 ++++++++-- drivers/scsi/sun3_scsi.c | 5 ++++- drivers/scsi/t128.c | 13 ++++++++++--- 13 files changed, 96 insertions(+), 41 deletions(-) (limited to 'drivers/scsi/mac_scsi.c') diff --git a/drivers/scsi/NCR5380.c b/drivers/scsi/NCR5380.c index 103c23e6d565..a66fffc83475 100644 --- a/drivers/scsi/NCR5380.c +++ b/drivers/scsi/NCR5380.c @@ -514,7 +514,7 @@ static int should_disconnect(unsigned char cmd) static void NCR5380_set_timer(struct NCR5380_hostdata *hostdata, unsigned long timeout) { hostdata->time_expires = jiffies + timeout; - schedule_delayed_work(&hostdata->coroutine, timeout); + queue_delayed_work(hostdata->work_q, &hostdata->coroutine, timeout); } @@ -791,7 +791,12 @@ static int NCR5380_init(struct Scsi_Host *instance, int flags) hostdata->disconnected_queue = NULL; INIT_DELAYED_WORK(&hostdata->coroutine, NCR5380_main); - + hostdata->work_q = alloc_workqueue("ncr5380_%d", + WQ_UNBOUND | WQ_MEM_RECLAIM, + 1, instance->host_no); + if (!hostdata->work_q) + return -ENOMEM; + /* The CHECK code seems to break the 53C400. Will check it later maybe */ if (flags & FLAG_NCR53C400) hostdata->flags = FLAG_HAS_LAST_BYTE_SENT | flags; @@ -872,6 +877,7 @@ static void NCR5380_exit(struct Scsi_Host *instance) struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata; cancel_delayed_work_sync(&hostdata->coroutine); + destroy_workqueue(hostdata->work_q); } /** @@ -932,7 +938,7 @@ static int NCR5380_queue_command_lck(struct scsi_cmnd *cmd, void (*done) (struct /* Run the coroutine if it isn't already running. */ /* Kick off command processing */ - schedule_delayed_work(&hostdata->coroutine, 0); + queue_delayed_work(hostdata->work_q, &hostdata->coroutine, 0); return 0; } @@ -1128,7 +1134,8 @@ static irqreturn_t NCR5380_intr(int dummy, void *dev_id) } /* if BASR_IRQ */ spin_unlock_irqrestore(instance->host_lock, flags); if(!done) - schedule_delayed_work(&hostdata->coroutine, 0); + queue_delayed_work(hostdata->work_q, + &hostdata->coroutine, 0); } while (!done); return IRQ_HANDLED; } diff --git a/drivers/scsi/NCR5380.h b/drivers/scsi/NCR5380.h index 25e28add0db8..f9c861d083d0 100644 --- a/drivers/scsi/NCR5380.h +++ b/drivers/scsi/NCR5380.h @@ -284,6 +284,7 @@ struct NCR5380_hostdata { unsigned spin_max_r; unsigned spin_max_w; #endif + struct workqueue_struct *work_q; }; #ifdef __KERNEL__ diff --git a/drivers/scsi/arm/cumana_1.c b/drivers/scsi/arm/cumana_1.c index 3b5ff105f1d6..0d0cb62b8cdb 100644 --- a/drivers/scsi/arm/cumana_1.c +++ b/drivers/scsi/arm/cumana_1.c @@ -238,7 +238,9 @@ static int cumanascsi1_probe(struct expansion_card *ec, host->irq = ec->irq; - NCR5380_init(host, 0); + ret = NCR5380_init(host, 0); + if (ret) + goto out_unmap; NCR5380_maybe_reset_bus(host); @@ -250,7 +252,7 @@ static int cumanascsi1_probe(struct expansion_card *ec, if (ret) { printk("scsi%d: IRQ%d not free: %d\n", host->host_no, host->irq, ret); - goto out_unmap; + goto out_exit; } ret = scsi_add_host(host, &ec->dev); @@ -262,6 +264,8 @@ static int cumanascsi1_probe(struct expansion_card *ec, out_free_irq: free_irq(host->irq, host); + out_exit: + NCR5380_exit(host); out_unmap: iounmap(priv(host)->base); iounmap(priv(host)->dma); diff --git a/drivers/scsi/arm/oak.c b/drivers/scsi/arm/oak.c index ca0f31d22f43..db337b998299 100644 --- a/drivers/scsi/arm/oak.c +++ b/drivers/scsi/arm/oak.c @@ -143,17 +143,21 @@ static int oakscsi_probe(struct expansion_card *ec, const struct ecard_id *id) host->irq = NO_IRQ; host->n_io_port = 255; - NCR5380_init(host, 0); + ret = NCR5380_init(host, 0); + if (ret) + goto out_unmap; NCR5380_maybe_reset_bus(host); ret = scsi_add_host(host, &ec->dev); if (ret) - goto out_unmap; + goto out_exit; scsi_scan_host(host); goto out; + out_exit: + NCR5380_exit(host); out_unmap: iounmap(priv(host)->base); unreg: diff --git a/drivers/scsi/atari_NCR5380.c b/drivers/scsi/atari_NCR5380.c index 1dd341ef89d4..0b0a225167bc 100644 --- a/drivers/scsi/atari_NCR5380.c +++ b/drivers/scsi/atari_NCR5380.c @@ -643,7 +643,7 @@ static inline void queue_main(struct NCR5380_hostdata *hostdata) queue it on the 'immediate' task queue, to be processed immediately after the current interrupt processing has finished. */ - schedule_work(&hostdata->main_task); + queue_work(hostdata->work_q, &hostdata->main_task); } /* else: nothing to do: the running NCR5380_main() will pick up any newly queued command. */ @@ -832,6 +832,11 @@ static int __init NCR5380_init(struct Scsi_Host *instance, int flags) hostdata->flags = flags; INIT_WORK(&hostdata->main_task, NCR5380_main); + hostdata->work_q = alloc_workqueue("ncr5380_%d", + WQ_UNBOUND | WQ_MEM_RECLAIM, + 1, instance->host_no); + if (!hostdata->work_q) + return -ENOMEM; prepare_info(instance); @@ -907,6 +912,7 @@ static void NCR5380_exit(struct Scsi_Host *instance) struct NCR5380_hostdata *hostdata = shost_priv(instance); cancel_work_sync(&hostdata->main_task); + destroy_workqueue(hostdata->work_q); } /** diff --git a/drivers/scsi/atari_scsi.c b/drivers/scsi/atari_scsi.c index 5b233ccae962..1c6c4ca0a82f 100644 --- a/drivers/scsi/atari_scsi.c +++ b/drivers/scsi/atari_scsi.c @@ -885,7 +885,9 @@ static int __init atari_scsi_probe(struct platform_device *pdev) #endif host_flags |= setup_toshiba_delay > 0 ? FLAG_TOSHIBA_DELAY : 0; - NCR5380_init(instance, host_flags); + error = NCR5380_init(instance, host_flags); + if (error) + goto fail_init; if (IS_A_TT()) { error = request_irq(instance->irq, scsi_tt_intr, 0, @@ -947,6 +949,7 @@ fail_host: free_irq(instance->irq, instance); fail_irq: NCR5380_exit(instance); +fail_init: scsi_host_put(instance); fail_alloc: if (atari_dma_buffer) diff --git a/drivers/scsi/dmx3191d.c b/drivers/scsi/dmx3191d.c index 2c0fd7641075..db415359fee8 100644 --- a/drivers/scsi/dmx3191d.c +++ b/drivers/scsi/dmx3191d.c @@ -95,7 +95,9 @@ static int dmx3191d_probe_one(struct pci_dev *pdev, */ shost->irq = NO_IRQ; - NCR5380_init(shost, FLAG_NO_PSEUDO_DMA | FLAG_DTC3181E); + error = NCR5380_init(shost, FLAG_NO_PSEUDO_DMA | FLAG_DTC3181E); + if (error) + goto out_host_put; NCR5380_maybe_reset_bus(shost); @@ -103,11 +105,15 @@ static int dmx3191d_probe_one(struct pci_dev *pdev, error = scsi_add_host(shost, &pdev->dev); if (error) - goto out_release_region; + goto out_exit; scsi_scan_host(shost); return 0; +out_exit: + NCR5380_exit(shost); +out_host_put: + scsi_host_put(shost); out_release_region: release_region(io, DMX3191D_REGION_LEN); out_disable_device: @@ -119,15 +125,14 @@ static int dmx3191d_probe_one(struct pci_dev *pdev, static void dmx3191d_remove_one(struct pci_dev *pdev) { struct Scsi_Host *shost = pci_get_drvdata(pdev); + unsigned long io = shost->io_port; scsi_remove_host(shost); NCR5380_exit(shost); - - release_region(shost->io_port, DMX3191D_REGION_LEN); - pci_disable_device(pdev); - scsi_host_put(shost); + release_region(io, DMX3191D_REGION_LEN); + pci_disable_device(pdev); } static struct pci_device_id dmx3191d_pci_tbl[] = { diff --git a/drivers/scsi/dtc.c b/drivers/scsi/dtc.c index 698bea067af9..bc856c8ba0dd 100644 --- a/drivers/scsi/dtc.c +++ b/drivers/scsi/dtc.c @@ -230,12 +230,13 @@ static int __init dtc_detect(struct scsi_host_template * tpnt) found: instance = scsi_register(tpnt, sizeof(struct NCR5380_hostdata)); if (instance == NULL) - break; + goto out_unmap; instance->base = addr; ((struct NCR5380_hostdata *)(instance)->hostdata)->base = base; - NCR5380_init(instance, 0); + if (NCR5380_init(instance, 0)) + goto out_unregister; NCR5380_maybe_reset_bus(instance); @@ -275,6 +276,12 @@ found: ++count; } return count; + +out_unregister: + scsi_unregister(instance); +out_unmap: + iounmap(base); + return count; } /* diff --git a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c index fa9f6d41548b..afd092ff0c2e 100644 --- a/drivers/scsi/g_NCR5380.c +++ b/drivers/scsi/g_NCR5380.c @@ -239,9 +239,6 @@ static int __init do_DTC3181E_setup(char *str) * and DTC436(ISAPnP) controllers. If overrides have been set we use * them. * - * The caller supplied NCR5380_init function is invoked from here, before - * the interrupt line is taken. - * * Locks: none */ @@ -402,15 +399,8 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt) } #endif instance = scsi_register(tpnt, sizeof(struct NCR5380_hostdata)); - if (instance == NULL) { -#ifndef SCSI_G_NCR5380_MEM - release_region(overrides[current_override].NCR5380_map_name, region_size); -#else - iounmap(iomem); - release_mem_region(base, NCR5380_region_size); -#endif - continue; - } + if (instance == NULL) + goto out_release; #ifndef SCSI_G_NCR5380_MEM instance->io_port = overrides[current_override].NCR5380_map_name; @@ -427,7 +417,8 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt) ((struct NCR5380_hostdata *)instance->hostdata)->iomem = iomem; #endif - NCR5380_init(instance, flags); + if (NCR5380_init(instance, flags)) + goto out_unregister; if (overrides[current_override].board == BOARD_NCR53C400) NCR5380_write(C400_CONTROL_STATUS_REG, CSR_BASE); @@ -459,6 +450,17 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt) ++count; } return count; + +out_unregister: + scsi_unregister(instance); +out_release: +#ifndef SCSI_G_NCR5380_MEM + release_region(overrides[current_override].NCR5380_map_name, region_size); +#else + iounmap(iomem); + release_mem_region(base, NCR5380_region_size); +#endif + return count; } /** @@ -475,15 +477,12 @@ static int generic_NCR5380_release_resources(struct Scsi_Host *instance) if (instance->irq != NO_IRQ) free_irq(instance->irq, instance); NCR5380_exit(instance); - #ifndef SCSI_G_NCR5380_MEM release_region(instance->io_port, instance->n_io_port); #else iounmap(((struct NCR5380_hostdata *)instance->hostdata)->iomem); release_mem_region(instance->base, NCR5380_region_size); #endif - - return 0; } diff --git a/drivers/scsi/mac_scsi.c b/drivers/scsi/mac_scsi.c index 4d26ef93e656..1317f54bab92 100644 --- a/drivers/scsi/mac_scsi.c +++ b/drivers/scsi/mac_scsi.c @@ -382,7 +382,9 @@ static int __init mac_scsi_probe(struct platform_device *pdev) #endif host_flags |= setup_toshiba_delay > 0 ? FLAG_TOSHIBA_DELAY : 0; - NCR5380_init(instance, host_flags); + error = NCR5380_init(instance, host_flags); + if (error) + goto fail_init; if (instance->irq != NO_IRQ) { error = request_irq(instance->irq, macscsi_intr, IRQF_SHARED, @@ -407,6 +409,7 @@ fail_host: free_irq(instance->irq, instance); fail_irq: NCR5380_exit(instance); +fail_init: scsi_host_put(instance); return error; } diff --git a/drivers/scsi/pas16.c b/drivers/scsi/pas16.c index e5c76eefa5e0..5e57ee01093c 100644 --- a/drivers/scsi/pas16.c +++ b/drivers/scsi/pas16.c @@ -378,11 +378,12 @@ static int __init pas16_detect(struct scsi_host_template *tpnt) instance = scsi_register (tpnt, sizeof(struct NCR5380_hostdata)); if(instance == NULL) - break; + goto out; instance->io_port = io_port; - NCR5380_init(instance, 0); + if (NCR5380_init(instance, 0)) + goto out_unregister; NCR5380_maybe_reset_bus(instance); @@ -418,6 +419,11 @@ static int __init pas16_detect(struct scsi_host_template *tpnt) ++count; } return count; + +out_unregister: + scsi_unregister(instance); +out: + return count; } /* diff --git a/drivers/scsi/sun3_scsi.c b/drivers/scsi/sun3_scsi.c index 9376b3d8bfdc..c4fcf2fa74fc 100644 --- a/drivers/scsi/sun3_scsi.c +++ b/drivers/scsi/sun3_scsi.c @@ -557,7 +557,9 @@ static int __init sun3_scsi_probe(struct platform_device *pdev) host_flags |= setup_use_tagged_queuing > 0 ? FLAG_TAGGED_QUEUING : 0; #endif - NCR5380_init(instance, host_flags); + error = NCR5380_init(instance, host_flags); + if (error) + goto fail_init; error = request_irq(instance->irq, scsi_sun3_intr, 0, "NCR5380", instance); @@ -604,6 +606,7 @@ fail_host: free_irq(instance->irq, instance); fail_irq: NCR5380_exit(instance); +fail_init: scsi_host_put(instance); fail_alloc: if (udc_regs) diff --git a/drivers/scsi/t128.c b/drivers/scsi/t128.c index 3adcae1150d2..3dac6d7f5d22 100644 --- a/drivers/scsi/t128.c +++ b/drivers/scsi/t128.c @@ -208,12 +208,13 @@ static int __init t128_detect(struct scsi_host_template *tpnt) found: instance = scsi_register (tpnt, sizeof(struct NCR5380_hostdata)); if(instance == NULL) - break; - + goto out_unmap; + instance->base = base; ((struct NCR5380_hostdata *)instance->hostdata)->base = p; - NCR5380_init(instance, 0); + if (NCR5380_init(instance, 0)) + goto out_unregister; NCR5380_maybe_reset_bus(instance); @@ -246,6 +247,12 @@ found: ++count; } return count; + +out_unregister: + scsi_unregister(instance); +out_unmap: + iounmap(p); + return count; } static int t128_release(struct Scsi_Host *shost) -- cgit v1.2.3 From ff3d4578840fd96a50558edf02ca0178b9ebb652 Mon Sep 17 00:00:00 2001 From: Finn Thain Date: Sun, 3 Jan 2016 16:05:25 +1100 Subject: ncr5380: Implement NCR5380_dma_xfer_len and remove LIMIT_TRANSFERSIZE macro Follow the example of the atari_NCR5380.c core driver and adopt the NCR5380_dma_xfer_len() hook. Implement NCR5380_dma_xfer_len() for dtc.c and g_NCR5380.c to take care of the limitations of these cards. Keep the default for drivers using PSEUDO_DMA. Eliminate the unused macro LIMIT_TRANSFERSIZE. Signed-off-by: Finn Thain Reviewed-by: Hannes Reinecke Tested-by: Ondrej Zary Tested-by: Michael Schmitz Signed-off-by: Martin K. Petersen --- drivers/scsi/NCR5380.c | 34 ++++++---------------------------- drivers/scsi/arm/cumana_1.c | 3 +++ drivers/scsi/arm/oak.c | 2 ++ drivers/scsi/atari_NCR5380.c | 8 +++++--- drivers/scsi/dtc.c | 14 ++++++++++++++ drivers/scsi/dtc.h | 3 +++ drivers/scsi/g_NCR5380.c | 15 +++++++++++++++ drivers/scsi/g_NCR5380.h | 3 +++ drivers/scsi/mac_scsi.c | 1 + drivers/scsi/pas16.h | 2 ++ drivers/scsi/t128.h | 2 ++ 11 files changed, 56 insertions(+), 31 deletions(-) (limited to 'drivers/scsi/mac_scsi.c') diff --git a/drivers/scsi/NCR5380.c b/drivers/scsi/NCR5380.c index 6a030139b41f..91eac63b5239 100644 --- a/drivers/scsi/NCR5380.c +++ b/drivers/scsi/NCR5380.c @@ -201,11 +201,6 @@ * DONT_USE_INTR - if defined, never use interrupts, even if we probe or * override-configure an IRQ. * - * LIMIT_TRANSFERSIZE - if defined, limit the pseudo-dma transfers to 512 - * bytes at a time. Since interrupts are disabled by default during - * these transfers, we might need this to give reasonable interrupt - * service time if the transfer size gets too large. - * * LINKED - if defined, linked commands are supported. * * PSEUDO_DMA - if defined, PSEUDO DMA is used during the data transfer phases. @@ -2000,29 +1995,12 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) { */ #if defined(PSEUDO_DMA) || defined(REAL_DMA_POLL) - /* KLL - * PSEUDO_DMA is defined here. If this is the g_NCR5380 - * driver then it will always be defined, so the - * FLAG_NO_PSEUDO_DMA is used to inhibit PDMA in the base - * NCR5380 case. I think this is a fairly clean solution. - * We supplement these 2 if's with the flag. - */ -#ifdef NCR5380_dma_xfer_len - if (!cmd->device->borken && !(hostdata->flags & FLAG_NO_PSEUDO_DMA) && (transfersize = NCR5380_dma_xfer_len(instance, cmd)) != 0) { -#else - transfersize = cmd->transfersize; - -#ifdef LIMIT_TRANSFERSIZE /* If we have problems with interrupt service */ - if (transfersize > 512) - transfersize = 512; -#endif /* LIMIT_TRANSFERSIZE */ - - if (!cmd->device->borken && transfersize && !(hostdata->flags & FLAG_NO_PSEUDO_DMA) && cmd->SCp.this_residual && !(cmd->SCp.this_residual % transfersize)) { - /* Limit transfers to 32K, for xx400 & xx406 - * pseudoDMA that transfers in 128 bytes blocks. */ - if (transfersize > 32 * 1024) - transfersize = 32 * 1024; -#endif + transfersize = 0; + if (!cmd->device->borken && + !(hostdata->flags & FLAG_NO_PSEUDO_DMA)) + transfersize = NCR5380_dma_xfer_len(instance, cmd, phase); + + if (transfersize) { len = transfersize; if (NCR5380_transfer_dma(instance, &phase, &len, (unsigned char **) &cmd->SCp.ptr)) { /* diff --git a/drivers/scsi/arm/cumana_1.c b/drivers/scsi/arm/cumana_1.c index 0d0cb62b8cdb..f9fb8dabdbbd 100644 --- a/drivers/scsi/arm/cumana_1.c +++ b/drivers/scsi/arm/cumana_1.c @@ -22,6 +22,9 @@ #define priv(host) ((struct NCR5380_hostdata *)(host)->hostdata) #define NCR5380_read(reg) cumanascsi_read(instance, reg) #define NCR5380_write(reg, value) cumanascsi_write(instance, reg, value) + +#define NCR5380_dma_xfer_len(instance, cmd, phase) (cmd->transfersize) + #define NCR5380_intr cumanascsi_intr #define NCR5380_queue_command cumanascsi_queue_command #define NCR5380_info cumanascsi_info diff --git a/drivers/scsi/arm/oak.c b/drivers/scsi/arm/oak.c index db337b998299..d95a1d4f4e02 100644 --- a/drivers/scsi/arm/oak.c +++ b/drivers/scsi/arm/oak.c @@ -26,6 +26,8 @@ #define NCR5380_write(reg, value) \ writeb(value, priv(instance)->base + ((reg) << 2)) +#define NCR5380_dma_xfer_len(instance, cmd, phase) (cmd->transfersize) + #define NCR5380_queue_command oakscsi_queue_command #define NCR5380_info oakscsi_info #define NCR5380_show_info oakscsi_show_info diff --git a/drivers/scsi/atari_NCR5380.c b/drivers/scsi/atari_NCR5380.c index 64ee92090de3..59b378057198 100644 --- a/drivers/scsi/atari_NCR5380.c +++ b/drivers/scsi/atari_NCR5380.c @@ -2170,11 +2170,13 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) */ #if defined(REAL_DMA) - if ( #if !defined(CONFIG_SUN3) - !cmd->device->borken && + transfersize = 0; + if (!cmd->device->borken) #endif - (transfersize = NCR5380_dma_xfer_len(instance, cmd, phase)) >= DMA_MIN_SIZE) { + transfersize = NCR5380_dma_xfer_len(instance, cmd, phase); + + if (transfersize >= DMA_MIN_SIZE) { len = transfersize; cmd->SCp.phase = phase; if (NCR5380_transfer_dma(instance, &phase, diff --git a/drivers/scsi/dtc.c b/drivers/scsi/dtc.c index bc856c8ba0dd..010d9b13aae7 100644 --- a/drivers/scsi/dtc.c +++ b/drivers/scsi/dtc.c @@ -419,6 +419,20 @@ static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src, return (0); } +static int dtc_dma_xfer_len(struct scsi_cmnd *cmd) +{ + int transfersize = cmd->transfersize; + + /* Limit transfers to 32K, for xx400 & xx406 + * pseudoDMA that transfers in 128 bytes blocks. + */ + if (transfersize > 32 * 1024 && cmd->SCp.this_residual && + !(cmd->SCp.this_residual % transfersize)) + transfersize = 32 * 1024; + + return transfersize; +} + MODULE_LICENSE("GPL"); #include "NCR5380.c" diff --git a/drivers/scsi/dtc.h b/drivers/scsi/dtc.h index 07b0ac98817c..e6c09a9174ce 100644 --- a/drivers/scsi/dtc.h +++ b/drivers/scsi/dtc.h @@ -27,6 +27,9 @@ #define NCR5380_read(reg) (readb(DTC_address(reg))) #define NCR5380_write(reg, value) (writeb(value, DTC_address(reg))) +#define NCR5380_dma_xfer_len(instance, cmd, phase) \ + dtc_dma_xfer_len(cmd) + #define NCR5380_intr dtc_intr #define NCR5380_queue_command dtc_queue_command #define NCR5380_abort dtc_abort diff --git a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c index afd092ff0c2e..5b3e03ad50ce 100644 --- a/drivers/scsi/g_NCR5380.c +++ b/drivers/scsi/g_NCR5380.c @@ -699,6 +699,21 @@ static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src, ; // TIMEOUT return 0; } + +static int generic_NCR5380_dma_xfer_len(struct scsi_cmnd *cmd) +{ + int transfersize = cmd->transfersize; + + /* Limit transfers to 32K, for xx400 & xx406 + * pseudoDMA that transfers in 128 bytes blocks. + */ + if (transfersize > 32 * 1024 && cmd->SCp.this_residual && + !(cmd->SCp.this_residual % transfersize)) + transfersize = 32 * 1024; + + return transfersize; +} + #endif /* PSEUDO_DMA */ /* diff --git a/drivers/scsi/g_NCR5380.h b/drivers/scsi/g_NCR5380.h index 5c656f163beb..0056790a9cbe 100644 --- a/drivers/scsi/g_NCR5380.h +++ b/drivers/scsi/g_NCR5380.h @@ -73,6 +73,9 @@ #endif +#define NCR5380_dma_xfer_len(instance, cmd, phase) \ + generic_NCR5380_dma_xfer_len(cmd) + #define NCR5380_intr generic_NCR5380_intr #define NCR5380_queue_command generic_NCR5380_queue_command #define NCR5380_abort generic_NCR5380_abort diff --git a/drivers/scsi/mac_scsi.c b/drivers/scsi/mac_scsi.c index 1317f54bab92..f8ed2acd1456 100644 --- a/drivers/scsi/mac_scsi.c +++ b/drivers/scsi/mac_scsi.c @@ -38,6 +38,7 @@ #define NCR5380_pread macscsi_pread #define NCR5380_pwrite macscsi_pwrite +#define NCR5380_dma_xfer_len(instance, cmd, phase) (cmd->transfersize) #define NCR5380_intr macscsi_intr #define NCR5380_queue_command macscsi_queue_command diff --git a/drivers/scsi/pas16.h b/drivers/scsi/pas16.h index 7247b67fb111..a827a7c1c133 100644 --- a/drivers/scsi/pas16.h +++ b/drivers/scsi/pas16.h @@ -110,6 +110,8 @@ #define NCR5380_read(reg) ( inb(PAS16_io_port(reg)) ) #define NCR5380_write(reg, value) ( outb((value),PAS16_io_port(reg)) ) +#define NCR5380_dma_xfer_len(instance, cmd, phase) (cmd->transfersize) + #define NCR5380_intr pas16_intr #define NCR5380_queue_command pas16_queue_command #define NCR5380_abort pas16_abort diff --git a/drivers/scsi/t128.h b/drivers/scsi/t128.h index ca93c97cf4ba..16691d5fb81b 100644 --- a/drivers/scsi/t128.h +++ b/drivers/scsi/t128.h @@ -84,6 +84,8 @@ #define NCR5380_read(reg) readb(T128_address(reg)) #define NCR5380_write(reg, value) writeb((value),(T128_address(reg))) +#define NCR5380_dma_xfer_len(instance, cmd, phase) (cmd->transfersize) + #define NCR5380_intr t128_intr #define NCR5380_queue_command t128_queue_command #define NCR5380_abort t128_abort -- cgit v1.2.3 From 161c0059a2a80aefe7000d9ab7ce5c36e5463b5f Mon Sep 17 00:00:00 2001 From: Finn Thain Date: Sun, 3 Jan 2016 16:05:46 +1100 Subject: ncr5380: Cleanup #include directives Remove unused includes (stat.h, signal.h, proc_fs.h) and move includes needed by the core drivers into the common header (delay.h etc). Signed-off-by: Finn Thain Reviewed-by: Hannes Reinecke Tested-by: Ondrej Zary Tested-by: Michael Schmitz Signed-off-by: Martin K. Petersen --- drivers/scsi/NCR5380.c | 2 -- drivers/scsi/NCR5380.h | 4 ++++ drivers/scsi/arm/cumana_1.c | 4 ---- drivers/scsi/arm/oak.c | 2 -- drivers/scsi/atari_NCR5380.c | 5 ----- drivers/scsi/atari_scsi.c | 1 - drivers/scsi/dmx3191d.c | 5 ----- drivers/scsi/dtc.c | 4 +--- drivers/scsi/g_NCR5380.c | 6 ++---- drivers/scsi/mac_scsi.c | 1 - drivers/scsi/pas16.c | 4 ---- drivers/scsi/t128.c | 3 --- 12 files changed, 7 insertions(+), 34 deletions(-) (limited to 'drivers/scsi/mac_scsi.c') diff --git a/drivers/scsi/NCR5380.c b/drivers/scsi/NCR5380.c index c6b69ee0021a..9ef26b64255a 100644 --- a/drivers/scsi/NCR5380.c +++ b/drivers/scsi/NCR5380.c @@ -79,8 +79,6 @@ * 4. Test SCSI-II tagged queueing (I have no devices which support * tagged queueing) */ -#include -#include #if (NDEBUG & NDEBUG_LISTS) #define LIST(x,y) {printk("LINE:%d Adding %p to %p\n", __LINE__, (void*)(x), (void*)(y)); if ((x)==(y)) udelay(5); } diff --git a/drivers/scsi/NCR5380.h b/drivers/scsi/NCR5380.h index e8a26eab32dd..9777602daa3d 100644 --- a/drivers/scsi/NCR5380.h +++ b/drivers/scsi/NCR5380.h @@ -22,8 +22,12 @@ #ifndef NCR5380_H #define NCR5380_H +#include #include +#include +#include #include +#include #define NDEBUG_ARBITRATION 0x1 #define NDEBUG_AUTOSENSE 0x2 diff --git a/drivers/scsi/arm/cumana_1.c b/drivers/scsi/arm/cumana_1.c index f9fb8dabdbbd..921c982886ae 100644 --- a/drivers/scsi/arm/cumana_1.c +++ b/drivers/scsi/arm/cumana_1.c @@ -4,9 +4,7 @@ * Copyright 1995-2002, Russell King */ #include -#include #include -#include #include #include @@ -15,8 +13,6 @@ #include -#include - #define PSEUDO_DMA #define priv(host) ((struct NCR5380_hostdata *)(host)->hostdata) diff --git a/drivers/scsi/arm/oak.c b/drivers/scsi/arm/oak.c index d95a1d4f4e02..719600a373d6 100644 --- a/drivers/scsi/arm/oak.c +++ b/drivers/scsi/arm/oak.c @@ -5,9 +5,7 @@ */ #include -#include #include -#include #include #include diff --git a/drivers/scsi/atari_NCR5380.c b/drivers/scsi/atari_NCR5380.c index c14cfb1cc3dd..8024f1cb9756 100644 --- a/drivers/scsi/atari_NCR5380.c +++ b/drivers/scsi/atari_NCR5380.c @@ -68,9 +68,6 @@ /* Adapted for the sun3 by Sam Creasey. */ -#include -#include - #if (NDEBUG & NDEBUG_LISTS) #define LIST(x, y) \ do { \ @@ -517,8 +514,6 @@ static inline int NCR5380_poll_politely(struct Scsi_Host *instance, reg, bit, val, wait); } -#include - #if NDEBUG static struct { unsigned char mask; diff --git a/drivers/scsi/atari_scsi.c b/drivers/scsi/atari_scsi.c index 1c6c4ca0a82f..2ba075749326 100644 --- a/drivers/scsi/atari_scsi.c +++ b/drivers/scsi/atari_scsi.c @@ -66,7 +66,6 @@ #include #include -#include #include #include #include diff --git a/drivers/scsi/dmx3191d.c b/drivers/scsi/dmx3191d.c index db415359fee8..05402830defe 100644 --- a/drivers/scsi/dmx3191d.c +++ b/drivers/scsi/dmx3191d.c @@ -41,11 +41,6 @@ #define NCR5380_implementation_fields /* none */ -/* - * Includes needed for NCR5380.[ch] (XXX: Move them to NCR5380.h) - */ -#include - #include "NCR5380.h" #include "NCR5380.c" diff --git a/drivers/scsi/dtc.c b/drivers/scsi/dtc.c index 1beefdbcbea8..6c96dad5cf23 100644 --- a/drivers/scsi/dtc.c +++ b/drivers/scsi/dtc.c @@ -46,15 +46,13 @@ #include -#include #include -#include -#include #include #include #include #include #include + #include "dtc.h" #define AUTOPROBE_IRQ #include "NCR5380.h" diff --git a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c index e71c79683925..1e8f29f500d5 100644 --- a/drivers/scsi/g_NCR5380.c +++ b/drivers/scsi/g_NCR5380.c @@ -63,16 +63,14 @@ #endif #include -#include #include +#include #include #include "g_NCR5380.h" #include "NCR5380.h" -#include #include #include #include -#include #include static int ncr_irq; @@ -732,7 +730,7 @@ static struct scsi_host_template driver_template = { .cmd_per_lun = CMD_PER_LUN, .use_clustering = DISABLE_CLUSTERING, }; -#include + #include "scsi_module.c" module_param(ncr_irq, int, 0); diff --git a/drivers/scsi/mac_scsi.c b/drivers/scsi/mac_scsi.c index f8ed2acd1456..420c2e204c13 100644 --- a/drivers/scsi/mac_scsi.c +++ b/drivers/scsi/mac_scsi.c @@ -12,7 +12,6 @@ */ #include -#include #include #include #include diff --git a/drivers/scsi/pas16.c b/drivers/scsi/pas16.c index 4570536187d8..6a5896dade20 100644 --- a/drivers/scsi/pas16.c +++ b/drivers/scsi/pas16.c @@ -69,14 +69,10 @@ #include -#include -#include #include #include #include -#include #include -#include #include #include diff --git a/drivers/scsi/t128.c b/drivers/scsi/t128.c index 3dac6d7f5d22..167c0750eba6 100644 --- a/drivers/scsi/t128.c +++ b/drivers/scsi/t128.c @@ -68,14 +68,11 @@ * 15 9-11 */ -#include #include #include #include -#include #include #include -#include #include #include "t128.h" -- cgit v1.2.3 From aa2e2cb1dde0e72e039f94210fb17e73661a6351 Mon Sep 17 00:00:00 2001 From: Finn Thain Date: Sun, 3 Jan 2016 16:05:48 +1100 Subject: ncr5380: Fix and cleanup scsi_host_template initializers Add missing .module initializer. Use distinct .proc_name values for the g_NCR5380 and g_NCR5380_mmio modules. Remove pointless CAN_QUEUE and CMD_PER_LUN override macros. Cleanup whitespace and code style. Signed-off-by: Finn Thain Reviewed-by: Hannes Reinecke Tested-by: Ondrej Zary Tested-by: Michael Schmitz Signed-off-by: Martin K. Petersen --- drivers/scsi/atari_scsi.c | 2 +- drivers/scsi/dmx3191d.c | 1 + drivers/scsi/dtc.c | 32 ++++++++++++++++---------------- drivers/scsi/dtc.h | 8 -------- drivers/scsi/g_NCR5380.c | 26 +++++++++++++------------- drivers/scsi/g_NCR5380.h | 10 ++-------- drivers/scsi/mac_scsi.c | 28 ++++++++++++++-------------- drivers/scsi/pas16.c | 32 ++++++++++++++++---------------- drivers/scsi/pas16.h | 8 -------- drivers/scsi/sun3_scsi.c | 6 +++--- drivers/scsi/t128.c | 32 ++++++++++++++++---------------- drivers/scsi/t128.h | 8 -------- 12 files changed, 82 insertions(+), 111 deletions(-) (limited to 'drivers/scsi/mac_scsi.c') diff --git a/drivers/scsi/atari_scsi.c b/drivers/scsi/atari_scsi.c index 2ba075749326..e263aa30282b 100644 --- a/drivers/scsi/atari_scsi.c +++ b/drivers/scsi/atari_scsi.c @@ -781,7 +781,7 @@ static struct scsi_host_template atari_scsi_template = { .eh_abort_handler = atari_scsi_abort, .eh_bus_reset_handler = atari_scsi_bus_reset, .this_id = 7, - .use_clustering = DISABLE_CLUSTERING + .use_clustering = DISABLE_CLUSTERING, }; static int __init atari_scsi_probe(struct platform_device *pdev) diff --git a/drivers/scsi/dmx3191d.c b/drivers/scsi/dmx3191d.c index 05402830defe..7f66c9e76c3b 100644 --- a/drivers/scsi/dmx3191d.c +++ b/drivers/scsi/dmx3191d.c @@ -49,6 +49,7 @@ static struct scsi_host_template dmx3191d_driver_template = { + .module = THIS_MODULE, .proc_name = DMX3191D_DRIVER_NAME, .name = "Domex DMX3191D", .info = NCR5380_info, diff --git a/drivers/scsi/dtc.c b/drivers/scsi/dtc.c index 6c96dad5cf23..d74661458f15 100644 --- a/drivers/scsi/dtc.c +++ b/drivers/scsi/dtc.c @@ -436,21 +436,21 @@ static int dtc_release(struct Scsi_Host *shost) } static struct scsi_host_template driver_template = { - .name = "DTC 3180/3280 ", - .detect = dtc_detect, - .release = dtc_release, - .proc_name = "dtc3x80", - .show_info = dtc_show_info, - .write_info = dtc_write_info, - .info = dtc_info, - .queuecommand = dtc_queue_command, - .eh_abort_handler = dtc_abort, - .eh_bus_reset_handler = dtc_bus_reset, - .bios_param = dtc_biosparam, - .can_queue = CAN_QUEUE, - .this_id = 7, - .sg_tablesize = SG_ALL, - .cmd_per_lun = CMD_PER_LUN, - .use_clustering = DISABLE_CLUSTERING, + .name = "DTC 3180/3280", + .detect = dtc_detect, + .release = dtc_release, + .proc_name = "dtc3x80", + .show_info = dtc_show_info, + .write_info = dtc_write_info, + .info = dtc_info, + .queuecommand = dtc_queue_command, + .eh_abort_handler = dtc_abort, + .eh_bus_reset_handler = dtc_bus_reset, + .bios_param = dtc_biosparam, + .can_queue = 32, + .this_id = 7, + .sg_tablesize = SG_ALL, + .cmd_per_lun = 2, + .use_clustering = DISABLE_CLUSTERING, }; #include "scsi_module.c" diff --git a/drivers/scsi/dtc.h b/drivers/scsi/dtc.h index e6c09a9174ce..56732cba8aba 100644 --- a/drivers/scsi/dtc.h +++ b/drivers/scsi/dtc.h @@ -10,14 +10,6 @@ #ifndef DTC3280_H #define DTC3280_H -#ifndef CMD_PER_LUN -#define CMD_PER_LUN 2 -#endif - -#ifndef CAN_QUEUE -#define CAN_QUEUE 32 -#endif - #define NCR5380_implementation_fields \ void __iomem *base diff --git a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c index 1e8f29f500d5..ea9d0de2fc85 100644 --- a/drivers/scsi/g_NCR5380.c +++ b/drivers/scsi/g_NCR5380.c @@ -305,7 +305,6 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt) } } #endif - tpnt->proc_name = "g_NCR5380"; for (count = 0; current_override < NO_OVERRIDES; ++current_override) { if (!(overrides[current_override].NCR5380_map_name)) @@ -715,20 +714,21 @@ static int generic_NCR5380_dma_xfer_len(struct scsi_cmnd *cmd) #include "NCR5380.c" static struct scsi_host_template driver_template = { - .show_info = generic_NCR5380_show_info, - .name = "Generic NCR5380/NCR53C400 SCSI", - .detect = generic_NCR5380_detect, - .release = generic_NCR5380_release_resources, - .info = generic_NCR5380_info, - .queuecommand = generic_NCR5380_queue_command, + .proc_name = DRV_MODULE_NAME, + .show_info = generic_NCR5380_show_info, + .name = "Generic NCR5380/NCR53C400 SCSI", + .detect = generic_NCR5380_detect, + .release = generic_NCR5380_release_resources, + .info = generic_NCR5380_info, + .queuecommand = generic_NCR5380_queue_command, .eh_abort_handler = generic_NCR5380_abort, .eh_bus_reset_handler = generic_NCR5380_bus_reset, - .bios_param = NCR5380_BIOSPARAM, - .can_queue = CAN_QUEUE, - .this_id = 7, - .sg_tablesize = SG_ALL, - .cmd_per_lun = CMD_PER_LUN, - .use_clustering = DISABLE_CLUSTERING, + .bios_param = NCR5380_BIOSPARAM, + .can_queue = 16, + .this_id = 7, + .sg_tablesize = SG_ALL, + .cmd_per_lun = 2, + .use_clustering = DISABLE_CLUSTERING, }; #include "scsi_module.c" diff --git a/drivers/scsi/g_NCR5380.h b/drivers/scsi/g_NCR5380.h index 0056790a9cbe..fd201e94f66b 100644 --- a/drivers/scsi/g_NCR5380.h +++ b/drivers/scsi/g_NCR5380.h @@ -21,18 +21,11 @@ #define NCR5380_BIOSPARAM NULL #endif -#ifndef CMD_PER_LUN -#define CMD_PER_LUN 2 -#endif - -#ifndef CAN_QUEUE -#define CAN_QUEUE 16 -#endif - #define __STRVAL(x) #x #define STRVAL(x) __STRVAL(x) #ifndef SCSI_G_NCR5380_MEM +#define DRV_MODULE_NAME "g_NCR5380" #define NCR5380_map_type int #define NCR5380_map_name port @@ -53,6 +46,7 @@ #else /* therefore SCSI_G_NCR5380_MEM */ +#define DRV_MODULE_NAME "g_NCR5380_mmio" #define NCR5380_map_type unsigned long #define NCR5380_map_name base diff --git a/drivers/scsi/mac_scsi.c b/drivers/scsi/mac_scsi.c index 420c2e204c13..e75bed25dd15 100644 --- a/drivers/scsi/mac_scsi.c +++ b/drivers/scsi/mac_scsi.c @@ -309,20 +309,20 @@ static int macscsi_pwrite(struct Scsi_Host *instance, #define PFX DRV_MODULE_NAME ": " static struct scsi_host_template mac_scsi_template = { - .module = THIS_MODULE, - .proc_name = DRV_MODULE_NAME, - .show_info = macscsi_show_info, - .write_info = macscsi_write_info, - .name = "Macintosh NCR5380 SCSI", - .info = macscsi_info, - .queuecommand = macscsi_queue_command, - .eh_abort_handler = macscsi_abort, - .eh_bus_reset_handler = macscsi_bus_reset, - .can_queue = 16, - .this_id = 7, - .sg_tablesize = SG_ALL, - .cmd_per_lun = 2, - .use_clustering = DISABLE_CLUSTERING + .module = THIS_MODULE, + .proc_name = DRV_MODULE_NAME, + .show_info = macscsi_show_info, + .write_info = macscsi_write_info, + .name = "Macintosh NCR5380 SCSI", + .info = macscsi_info, + .queuecommand = macscsi_queue_command, + .eh_abort_handler = macscsi_abort, + .eh_bus_reset_handler = macscsi_bus_reset, + .can_queue = 16, + .this_id = 7, + .sg_tablesize = SG_ALL, + .cmd_per_lun = 2, + .use_clustering = DISABLE_CLUSTERING, }; static int __init mac_scsi_probe(struct platform_device *pdev) diff --git a/drivers/scsi/pas16.c b/drivers/scsi/pas16.c index 6a5896dade20..5f8a8295a5c1 100644 --- a/drivers/scsi/pas16.c +++ b/drivers/scsi/pas16.c @@ -546,22 +546,22 @@ static int pas16_release(struct Scsi_Host *shost) } static struct scsi_host_template driver_template = { - .name = "Pro Audio Spectrum-16 SCSI", - .detect = pas16_detect, - .release = pas16_release, - .proc_name = "pas16", - .show_info = pas16_show_info, - .write_info = pas16_write_info, - .info = pas16_info, - .queuecommand = pas16_queue_command, - .eh_abort_handler = pas16_abort, - .eh_bus_reset_handler = pas16_bus_reset, - .bios_param = pas16_biosparam, - .can_queue = CAN_QUEUE, - .this_id = 7, - .sg_tablesize = SG_ALL, - .cmd_per_lun = CMD_PER_LUN, - .use_clustering = DISABLE_CLUSTERING, + .name = "Pro Audio Spectrum-16 SCSI", + .detect = pas16_detect, + .release = pas16_release, + .proc_name = "pas16", + .show_info = pas16_show_info, + .write_info = pas16_write_info, + .info = pas16_info, + .queuecommand = pas16_queue_command, + .eh_abort_handler = pas16_abort, + .eh_bus_reset_handler = pas16_bus_reset, + .bios_param = pas16_biosparam, + .can_queue = 32, + .this_id = 7, + .sg_tablesize = SG_ALL, + .cmd_per_lun = 2, + .use_clustering = DISABLE_CLUSTERING, }; #include "scsi_module.c" diff --git a/drivers/scsi/pas16.h b/drivers/scsi/pas16.h index a827a7c1c133..d37527717225 100644 --- a/drivers/scsi/pas16.h +++ b/drivers/scsi/pas16.h @@ -95,14 +95,6 @@ #define OPERATION_MODE_1 0xec03 #define IO_CONFIG_3 0xf002 -#ifndef CMD_PER_LUN -#define CMD_PER_LUN 2 -#endif - -#ifndef CAN_QUEUE -#define CAN_QUEUE 32 -#endif - #define NCR5380_implementation_fields /* none */ #define PAS16_io_port(reg) (instance->io_port + pas16_offset[(reg)]) diff --git a/drivers/scsi/sun3_scsi.c b/drivers/scsi/sun3_scsi.c index c4fcf2fa74fc..082c91a4c1c4 100644 --- a/drivers/scsi/sun3_scsi.c +++ b/drivers/scsi/sun3_scsi.c @@ -463,13 +463,13 @@ static struct scsi_host_template sun3_scsi_template = { .name = SUN3_SCSI_NAME, .info = sun3scsi_info, .queuecommand = sun3scsi_queue_command, - .eh_abort_handler = sun3scsi_abort, - .eh_bus_reset_handler = sun3scsi_bus_reset, + .eh_abort_handler = sun3scsi_abort, + .eh_bus_reset_handler = sun3scsi_bus_reset, .can_queue = 16, .this_id = 7, .sg_tablesize = SG_NONE, .cmd_per_lun = 2, - .use_clustering = DISABLE_CLUSTERING + .use_clustering = DISABLE_CLUSTERING, }; static int __init sun3_scsi_probe(struct platform_device *pdev) diff --git a/drivers/scsi/t128.c b/drivers/scsi/t128.c index 167c0750eba6..d1ed1f532a24 100644 --- a/drivers/scsi/t128.c +++ b/drivers/scsi/t128.c @@ -390,21 +390,21 @@ MODULE_LICENSE("GPL"); #include "NCR5380.c" static struct scsi_host_template driver_template = { - .name = "Trantor T128/T128F/T228", - .detect = t128_detect, - .release = t128_release, - .proc_name = "t128", - .show_info = t128_show_info, - .write_info = t128_write_info, - .info = t128_info, - .queuecommand = t128_queue_command, - .eh_abort_handler = t128_abort, - .eh_bus_reset_handler = t128_bus_reset, - .bios_param = t128_biosparam, - .can_queue = CAN_QUEUE, - .this_id = 7, - .sg_tablesize = SG_ALL, - .cmd_per_lun = CMD_PER_LUN, - .use_clustering = DISABLE_CLUSTERING, + .name = "Trantor T128/T128F/T228", + .detect = t128_detect, + .release = t128_release, + .proc_name = "t128", + .show_info = t128_show_info, + .write_info = t128_write_info, + .info = t128_info, + .queuecommand = t128_queue_command, + .eh_abort_handler = t128_abort, + .eh_bus_reset_handler = t128_bus_reset, + .bios_param = t128_biosparam, + .can_queue = 32, + .this_id = 7, + .sg_tablesize = SG_ALL, + .cmd_per_lun = 2, + .use_clustering = DISABLE_CLUSTERING, }; #include "scsi_module.c" diff --git a/drivers/scsi/t128.h b/drivers/scsi/t128.h index 16691d5fb81b..dd16d85497e1 100644 --- a/drivers/scsi/t128.h +++ b/drivers/scsi/t128.h @@ -67,14 +67,6 @@ #define T_DATA_REG_OFFSET 0x1e00 /* rw 512 bytes long */ -#ifndef CMD_PER_LUN -#define CMD_PER_LUN 2 -#endif - -#ifndef CAN_QUEUE -#define CAN_QUEUE 32 -#endif - #define NCR5380_implementation_fields \ void __iomem *base -- cgit v1.2.3 From 32b26a104237c1ba3575a6c8d47e46060cc416fb Mon Sep 17 00:00:00 2001 From: Finn Thain Date: Sun, 3 Jan 2016 16:05:58 +1100 Subject: ncr5380: Use standard list data structure The NCR5380 drivers have a home-spun linked list implementation for scsi_cmnd structs that uses cmd->host_scribble as a 'next' pointer. Adopt the standard list_head data structure and list operations instead. Remove the eh_abort_handler rather than convert it. Doing the conversion would only be churn because the existing EH handlers don't work and get replaced in a subsequent patch. Signed-off-by: Finn Thain Reviewed-by: Hannes Reinecke Tested-by: Ondrej Zary Tested-by: Michael Schmitz Signed-off-by: Martin K. Petersen --- drivers/scsi/NCR5380.c | 214 ++++++-------------------------- drivers/scsi/NCR5380.h | 16 ++- drivers/scsi/arm/cumana_1.c | 1 + drivers/scsi/arm/oak.c | 1 + drivers/scsi/atari_NCR5380.c | 287 +++++++------------------------------------ drivers/scsi/atari_scsi.c | 1 + drivers/scsi/dmx3191d.c | 1 + drivers/scsi/dtc.c | 1 + drivers/scsi/g_NCR5380.c | 1 + drivers/scsi/mac_scsi.c | 1 + drivers/scsi/pas16.c | 1 + drivers/scsi/sun3_scsi.c | 1 + drivers/scsi/t128.c | 1 + 13 files changed, 106 insertions(+), 421 deletions(-) (limited to 'drivers/scsi/mac_scsi.c') diff --git a/drivers/scsi/NCR5380.c b/drivers/scsi/NCR5380.c index 9e8636300c8a..6b861fd3fbb1 100644 --- a/drivers/scsi/NCR5380.c +++ b/drivers/scsi/NCR5380.c @@ -622,8 +622,9 @@ static int NCR5380_init(struct Scsi_Host *instance, int flags) #endif spin_lock_init(&hostdata->lock); hostdata->connected = NULL; - hostdata->issue_queue = NULL; - hostdata->disconnected_queue = NULL; + INIT_LIST_HEAD(&hostdata->unissued); + INIT_LIST_HEAD(&hostdata->disconnected); + hostdata->flags = flags; INIT_WORK(&hostdata->main_task, NCR5380_main); @@ -738,7 +739,7 @@ static int NCR5380_queue_command(struct Scsi_Host *instance, struct scsi_cmnd *cmd) { struct NCR5380_hostdata *hostdata = shost_priv(instance); - struct scsi_cmnd *tmp; + struct NCR5380_cmd *ncmd = scsi_cmd_priv(cmd); unsigned long flags; #if (NDEBUG & NDEBUG_NO_WRITE) @@ -752,12 +753,6 @@ static int NCR5380_queue_command(struct Scsi_Host *instance, } #endif /* (NDEBUG & NDEBUG_NO_WRITE) */ - /* - * We use the host_scribble field as a pointer to the next command - * in a queue - */ - - cmd->host_scribble = NULL; cmd->result = 0; spin_lock_irqsave(&hostdata->lock, flags); @@ -769,13 +764,11 @@ static int NCR5380_queue_command(struct Scsi_Host *instance, * sense data is only guaranteed to be valid while the condition exists. */ - if (!(hostdata->issue_queue) || (cmd->cmnd[0] == REQUEST_SENSE)) { - cmd->host_scribble = (unsigned char *) hostdata->issue_queue; - hostdata->issue_queue = cmd; - } else { - for (tmp = (struct scsi_cmnd *) hostdata->issue_queue; tmp->host_scribble; tmp = (struct scsi_cmnd *) tmp->host_scribble); - tmp->host_scribble = (unsigned char *) cmd; - } + if (cmd->cmnd[0] == REQUEST_SENSE) + list_add(&ncmd->list, &hostdata->unissued); + else + list_add_tail(&ncmd->list, &hostdata->unissued); + spin_unlock_irqrestore(&hostdata->lock, flags); dsprintk(NDEBUG_QUEUES, instance, "command %p added to %s of queue\n", @@ -803,7 +796,7 @@ static void NCR5380_main(struct work_struct *work) struct NCR5380_hostdata *hostdata = container_of(work, struct NCR5380_hostdata, main_task); struct Scsi_Host *instance = hostdata->host; - struct scsi_cmnd *tmp, *prev; + struct NCR5380_cmd *ncmd, *n; int done; spin_lock_irq(&hostdata->lock); @@ -816,23 +809,20 @@ static void NCR5380_main(struct work_struct *work) * Search through the issue_queue for a command destined * for a target that's not busy. */ - for (tmp = (struct scsi_cmnd *) hostdata->issue_queue, prev = NULL; tmp; prev = tmp, tmp = (struct scsi_cmnd *) tmp->host_scribble) - { + list_for_each_entry_safe(ncmd, n, &hostdata->unissued, + list) { + struct scsi_cmnd *tmp = NCR5380_to_scmd(ncmd); + dsprintk(NDEBUG_QUEUES, instance, "main: tmp=%p target=%d busy=%d lun=%llu\n", tmp, scmd_id(tmp), hostdata->busy[scmd_id(tmp)], tmp->device->lun); /* When we find one, remove it from the issue queue. */ if (!(hostdata->busy[tmp->device->id] & (1 << (u8)(tmp->device->lun & 0xff)))) { - if (prev) { - prev->host_scribble = tmp->host_scribble; - } else { - hostdata->issue_queue = (struct scsi_cmnd *) tmp->host_scribble; - } - tmp->host_scribble = NULL; + list_del(&ncmd->list); dsprintk(NDEBUG_MAIN | NDEBUG_QUEUES, - instance, "main: removed %p from issue queue %p\n", - tmp, prev); + instance, "main: removed %p from issue queue\n", + tmp); /* * Attempt to establish an I_T_L nexus here. @@ -851,8 +841,7 @@ static void NCR5380_main(struct work_struct *work) /* OK or bad target */ } else { /* Need to retry */ - tmp->host_scribble = (unsigned char *) hostdata->issue_queue; - hostdata->issue_queue = tmp; + list_add(&ncmd->list, &hostdata->unissued); dsprintk(NDEBUG_MAIN | NDEBUG_QUEUES, instance, "main: select() failed, %p returned to issue queue\n", tmp); @@ -1744,6 +1733,8 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) { struct scsi_cmnd *cmd; while ((cmd = hostdata->connected)) { + struct NCR5380_cmd *ncmd = scsi_cmd_priv(cmd); + tmp = NCR5380_read(STATUS_REG); /* We only have a valid SCSI phase when REQ is asserted */ if (tmp & SR_REQ) { @@ -1875,9 +1866,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) { if ((cmd->cmnd[0] != REQUEST_SENSE) && (status_byte(cmd->SCp.Status) == CHECK_CONDITION)) { scsi_eh_prep_cmnd(cmd, &hostdata->ses, NULL, 0, ~0); - cmd->host_scribble = (unsigned char *) - hostdata->issue_queue; - hostdata->issue_queue = (struct scsi_cmnd *) cmd; + list_add(&ncmd->list, &hostdata->unissued); dsprintk(NDEBUG_AUTOSENSE | NDEBUG_QUEUES, instance, "REQUEST SENSE cmd %p added to head of issue queue\n", cmd); @@ -1911,10 +1900,8 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) { case DISCONNECT:{ /* Accept message by clearing ACK */ NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); - cmd->host_scribble = (unsigned char *) - hostdata->disconnected_queue; hostdata->connected = NULL; - hostdata->disconnected_queue = cmd; + list_add(&ncmd->list, &hostdata->disconnected); dsprintk(NDEBUG_INFORMATION | NDEBUG_QUEUES, instance, "connected command %p for target %d lun %llu moved to disconnected queue\n", cmd, scmd_id(cmd), cmd->device->lun); @@ -2087,7 +2074,8 @@ static void NCR5380_reselect(struct Scsi_Host *instance) { int len; unsigned char msg[3]; unsigned char *data; - struct scsi_cmnd *tmp = NULL, *prev; + struct NCR5380_cmd *ncmd; + struct scsi_cmnd *tmp; /* * Disable arbitration, etc. since the host adapter obviously @@ -2156,16 +2144,14 @@ static void NCR5380_reselect(struct Scsi_Host *instance) { * just reestablished, and remove it from the disconnected queue. */ - for (tmp = (struct scsi_cmnd *) hostdata->disconnected_queue, prev = NULL; - tmp; prev = tmp, tmp = (struct scsi_cmnd *) tmp->host_scribble) { - if ((target_mask == (1 << tmp->device->id)) && (lun == (u8)tmp->device->lun)) { - if (prev) { - prev->host_scribble = tmp->host_scribble; - } else { - hostdata->disconnected_queue = - (struct scsi_cmnd *) tmp->host_scribble; - } - tmp->host_scribble = NULL; + tmp = NULL; + list_for_each_entry(ncmd, &hostdata->disconnected, list) { + struct scsi_cmnd *cmd = NCR5380_to_scmd(ncmd); + + if (target_mask == (1 << scmd_id(cmd)) && + lun == (u8)cmd->device->lun) { + list_del(&ncmd->list); + tmp = cmd; break; } } @@ -2261,146 +2247,18 @@ static int NCR5380_abort(struct scsi_cmnd *cmd) { struct Scsi_Host *instance = cmd->device->host; struct NCR5380_hostdata *hostdata = shost_priv(instance); - struct scsi_cmnd *tmp, **prev; unsigned long flags; - scmd_printk(KERN_WARNING, cmd, "aborting command\n"); - spin_lock_irqsave(&hostdata->lock, flags); +#if (NDEBUG & NDEBUG_ANY) + scmd_printk(KERN_INFO, cmd, "aborting command\n"); +#endif NCR5380_dprint(NDEBUG_ANY, instance); NCR5380_dprint_phase(NDEBUG_ANY, instance); - dprintk(NDEBUG_ABORT, "scsi%d : abort called\n", instance->host_no); - dprintk(NDEBUG_ABORT, " basr 0x%X, sr 0x%X\n", NCR5380_read(BUS_AND_STATUS_REG), NCR5380_read(STATUS_REG)); - -#if 0 -/* - * Case 1 : If the command is the currently executing command, - * we'll set the aborted flag and return control so that - * information transfer routine can exit cleanly. - */ - - if (hostdata->connected == cmd) { - dprintk(NDEBUG_ABORT, "scsi%d : aborting connected command\n", instance->host_no); -/* - * We should perform BSY checking, and make sure we haven't slipped - * into BUS FREE. - */ - - NCR5380_write(INITIATOR_COMMAND_REG, ICR_ASSERT_ATN); -/* - * Since we can't change phases until we've completed the current - * handshake, we have to source or sink a byte of data if the current - * phase is not MSGOUT. - */ - -/* - * Return control to the executing NCR drive so we can clear the - * aborted flag and get back into our main loop. - */ - - return SUCCESS; - } -#endif - -/* - * Case 2 : If the command hasn't been issued yet, we simply remove it - * from the issue queue. - */ - - dprintk(NDEBUG_ABORT, "scsi%d : abort going into loop.\n", instance->host_no); - for (prev = (struct scsi_cmnd **) &(hostdata->issue_queue), tmp = (struct scsi_cmnd *) hostdata->issue_queue; tmp; prev = (struct scsi_cmnd **) &(tmp->host_scribble), tmp = (struct scsi_cmnd *) tmp->host_scribble) - if (cmd == tmp) { - (*prev) = (struct scsi_cmnd *) tmp->host_scribble; - tmp->host_scribble = NULL; - spin_unlock_irqrestore(&hostdata->lock, flags); - tmp->result = DID_ABORT << 16; - dprintk(NDEBUG_ABORT, "scsi%d : abort removed command from issue queue.\n", instance->host_no); - tmp->scsi_done(tmp); - return SUCCESS; - } -#if (NDEBUG & NDEBUG_ABORT) - /* KLL */ - else if (prev == tmp) - printk(KERN_ERR "scsi%d : LOOP\n", instance->host_no); -#endif - -/* - * Case 3 : If any commands are connected, we're going to fail the abort - * and let the high level SCSI driver retry at a later time or - * issue a reset. - * - * Timeouts, and therefore aborted commands, will be highly unlikely - * and handling them cleanly in this situation would make the common - * case of noresets less efficient, and would pollute our code. So, - * we fail. - */ - - if (hostdata->connected) { - spin_unlock_irqrestore(&hostdata->lock, flags); - dprintk(NDEBUG_ABORT, "scsi%d : abort failed, command connected.\n", instance->host_no); - return FAILED; - } -/* - * Case 4: If the command is currently disconnected from the bus, and - * there are no connected commands, we reconnect the I_T_L or - * I_T_L_Q nexus associated with it, go into message out, and send - * an abort message. - * - * This case is especially ugly. In order to reestablish the nexus, we - * need to call NCR5380_select(). The easiest way to implement this - * function was to abort if the bus was busy, and let the interrupt - * handler triggered on the SEL for reselect take care of lost arbitrations - * where necessary, meaning interrupts need to be enabled. - * - * When interrupts are enabled, the queues may change - so we - * can't remove it from the disconnected queue before selecting it - * because that could cause a failure in hashing the nexus if that - * device reselected. - * - * Since the queues may change, we can't use the pointers from when we - * first locate it. - * - * So, we must first locate the command, and if NCR5380_select() - * succeeds, then issue the abort, relocate the command and remove - * it from the disconnected queue. - */ - - for (tmp = (struct scsi_cmnd *) hostdata->disconnected_queue; tmp; tmp = (struct scsi_cmnd *) tmp->host_scribble) - if (cmd == tmp) { - dprintk(NDEBUG_ABORT, "scsi%d : aborting disconnected command.\n", instance->host_no); - - if (NCR5380_select(instance, cmd)) { - spin_unlock_irq(&hostdata->lock); - return FAILED; - } - dprintk(NDEBUG_ABORT, "scsi%d : nexus reestablished.\n", instance->host_no); - - do_abort(instance); - - for (prev = (struct scsi_cmnd **) &(hostdata->disconnected_queue), tmp = (struct scsi_cmnd *) hostdata->disconnected_queue; tmp; prev = (struct scsi_cmnd **) &(tmp->host_scribble), tmp = (struct scsi_cmnd *) tmp->host_scribble) - if (cmd == tmp) { - *prev = (struct scsi_cmnd *) tmp->host_scribble; - tmp->host_scribble = NULL; - spin_unlock_irqrestore(&hostdata->lock, flags); - tmp->result = DID_ABORT << 16; - tmp->scsi_done(tmp); - return SUCCESS; - } - } -/* - * Case 5 : If we reached this point, the command was not found in any of - * the queues. - * - * We probably reached this point because of an unlikely race condition - * between the command completing successfully and the abortion code, - * so we won't panic, but we will notify the user in case something really - * broke. - */ spin_unlock_irqrestore(&hostdata->lock, flags); - printk(KERN_WARNING "scsi%d : warning : SCSI command probably completed successfully\n" - " before abortion\n", instance->host_no); + return FAILED; } diff --git a/drivers/scsi/NCR5380.h b/drivers/scsi/NCR5380.h index 87c2f2104e68..56252a5516d7 100644 --- a/drivers/scsi/NCR5380.h +++ b/drivers/scsi/NCR5380.h @@ -24,6 +24,7 @@ #include #include +#include #include #include #include @@ -254,8 +255,8 @@ struct NCR5380_hostdata { #endif unsigned char last_message; /* last message OUT */ struct scsi_cmnd *connected; /* currently connected cmnd */ - struct scsi_cmnd *issue_queue; /* waiting to be issued */ - struct scsi_cmnd *disconnected_queue; /* waiting for reconnect */ + struct list_head unissued; /* waiting to be issued */ + struct list_head disconnected; /* waiting for reconnect */ spinlock_t lock; /* protects this struct */ int flags; struct scsi_eh_save ses; @@ -277,6 +278,17 @@ struct NCR5380_hostdata { #ifdef __KERNEL__ +struct NCR5380_cmd { + struct list_head list; +}; + +#define NCR5380_CMD_SIZE (sizeof(struct NCR5380_cmd)) + +static inline struct scsi_cmnd *NCR5380_to_scmd(struct NCR5380_cmd *ncmd_ptr) +{ + return ((struct scsi_cmnd *)ncmd_ptr) - 1; +} + #ifndef NDEBUG #define NDEBUG (0) #endif diff --git a/drivers/scsi/arm/cumana_1.c b/drivers/scsi/arm/cumana_1.c index 921c982886ae..b526ba579ba3 100644 --- a/drivers/scsi/arm/cumana_1.c +++ b/drivers/scsi/arm/cumana_1.c @@ -208,6 +208,7 @@ static struct scsi_host_template cumanascsi_template = { .cmd_per_lun = 2, .use_clustering = DISABLE_CLUSTERING, .proc_name = "CumanaSCSI-1", + .cmd_size = NCR5380_CMD_SIZE, }; static int cumanascsi1_probe(struct expansion_card *ec, diff --git a/drivers/scsi/arm/oak.c b/drivers/scsi/arm/oak.c index 4eef3cdd9aa0..70e648513275 100644 --- a/drivers/scsi/arm/oak.c +++ b/drivers/scsi/arm/oak.c @@ -114,6 +114,7 @@ static struct scsi_host_template oakscsi_template = { .cmd_per_lun = 2, .use_clustering = DISABLE_CLUSTERING, .proc_name = "oakscsi", + .cmd_size = NCR5380_CMD_SIZE, }; static int oakscsi_probe(struct expansion_card *ec, const struct ecard_id *id) diff --git a/drivers/scsi/atari_NCR5380.c b/drivers/scsi/atari_NCR5380.c index 809ef25b7049..12b98cbe7b44 100644 --- a/drivers/scsi/atari_NCR5380.c +++ b/drivers/scsi/atari_NCR5380.c @@ -175,10 +175,6 @@ * possible) function may be used. */ -#define NEXT(cmd) ((struct scsi_cmnd *)(cmd)->host_scribble) -#define SET_NEXT(cmd,next) ((cmd)->host_scribble = (void *)(next)) -#define NEXTADDR(cmd) ((struct scsi_cmnd **)&(cmd)->host_scribble) - #define HOSTNO instance->host_no static int do_abort(struct Scsi_Host *); @@ -665,8 +661,9 @@ static int __init NCR5380_init(struct Scsi_Host *instance, int flags) #endif spin_lock_init(&hostdata->lock); hostdata->connected = NULL; - hostdata->issue_queue = NULL; - hostdata->disconnected_queue = NULL; + INIT_LIST_HEAD(&hostdata->unissued); + INIT_LIST_HEAD(&hostdata->disconnected); + hostdata->flags = flags; INIT_WORK(&hostdata->main_task, NCR5380_main); @@ -781,7 +778,7 @@ static int NCR5380_queue_command(struct Scsi_Host *instance, struct scsi_cmnd *cmd) { struct NCR5380_hostdata *hostdata = shost_priv(instance); - struct scsi_cmnd *tmp; + struct NCR5380_cmd *ncmd = scsi_cmd_priv(cmd); unsigned long flags; #if (NDEBUG & NDEBUG_NO_WRITE) @@ -795,12 +792,6 @@ static int NCR5380_queue_command(struct Scsi_Host *instance, } #endif /* (NDEBUG & NDEBUG_NO_WRITE) */ - /* - * We use the host_scribble field as a pointer to the next command - * in a queue - */ - - SET_NEXT(cmd, NULL); cmd->result = 0; /* @@ -834,15 +825,11 @@ static int NCR5380_queue_command(struct Scsi_Host *instance, * sense data is only guaranteed to be valid while the condition exists. */ - if (!(hostdata->issue_queue) || (cmd->cmnd[0] == REQUEST_SENSE)) { - SET_NEXT(cmd, hostdata->issue_queue); - hostdata->issue_queue = cmd; - } else { - for (tmp = (struct scsi_cmnd *)hostdata->issue_queue; - NEXT(tmp); tmp = NEXT(tmp)) - ; - SET_NEXT(tmp, cmd); - } + if (cmd->cmnd[0] == REQUEST_SENSE) + list_add(&ncmd->list, &hostdata->unissued); + else + list_add_tail(&ncmd->list, &hostdata->unissued); + spin_unlock_irqrestore(&hostdata->lock, flags); dsprintk(NDEBUG_QUEUES, instance, "command %p added to %s of queue\n", @@ -858,8 +845,8 @@ static inline void maybe_release_dma_irq(struct Scsi_Host *instance) struct NCR5380_hostdata *hostdata = shost_priv(instance); /* Caller does the locking needed to set & test these data atomically */ - if (!hostdata->disconnected_queue && - !hostdata->issue_queue && + if (list_empty(&hostdata->disconnected) && + list_empty(&hostdata->unissued) && !hostdata->connected && !hostdata->retain_dma_intr) NCR5380_release_dma_irq(instance); @@ -881,7 +868,7 @@ static void NCR5380_main(struct work_struct *work) struct NCR5380_hostdata *hostdata = container_of(work, struct NCR5380_hostdata, main_task); struct Scsi_Host *instance = hostdata->host; - struct scsi_cmnd *tmp, *prev; + struct NCR5380_cmd *ncmd, *n; int done; /* @@ -900,17 +887,9 @@ static void NCR5380_main(struct work_struct *work) * Search through the issue_queue for a command destined * for a target that's not busy. */ -#if (NDEBUG & NDEBUG_LISTS) - for (tmp = (struct scsi_cmnd *) hostdata->issue_queue, prev = NULL; - tmp && (tmp != prev); prev = tmp, tmp = NEXT(tmp)) - ; - /*printk("%p ", tmp);*/ - if ((tmp == prev) && tmp) - printk(" LOOP\n"); - /* else printk("\n"); */ -#endif - for (tmp = (struct scsi_cmnd *) hostdata->issue_queue, - prev = NULL; tmp; prev = tmp, tmp = NEXT(tmp)) { + list_for_each_entry_safe(ncmd, n, &hostdata->unissued, + list) { + struct scsi_cmnd *tmp = NCR5380_to_scmd(ncmd); u8 lun = tmp->device->lun; dsprintk(NDEBUG_QUEUES, instance, "main: tmp=%p target=%d busy=%d lun=%d\n", @@ -923,15 +902,10 @@ static void NCR5380_main(struct work_struct *work) !(hostdata->busy[tmp->device->id] & (1 << lun)) #endif ) { - if (prev) { - SET_NEXT(prev, NEXT(tmp)); - } else { - hostdata->issue_queue = NEXT(tmp); - } - SET_NEXT(tmp, NULL); + list_del(&ncmd->list); dsprintk(NDEBUG_MAIN | NDEBUG_QUEUES, - instance, "main: removed %p from issue queue %p\n", - tmp, prev); + instance, "main: removed %p from issue queue\n", + tmp); hostdata->retain_dma_intr++; @@ -960,8 +934,7 @@ static void NCR5380_main(struct work_struct *work) maybe_release_dma_irq(instance); } else { /* Need to retry */ - SET_NEXT(tmp, hostdata->issue_queue); - hostdata->issue_queue = tmp; + list_add(&ncmd->list, &hostdata->unissued); dsprintk(NDEBUG_MAIN | NDEBUG_QUEUES, instance, "main: select() failed, %p returned to issue queue\n", tmp); @@ -1834,6 +1807,8 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) #endif while ((cmd = hostdata->connected)) { + struct NCR5380_cmd *ncmd = scsi_cmd_priv(cmd); + tmp = NCR5380_read(STATUS_REG); /* We only have a valid SCSI phase when REQ is asserted */ if (tmp & SR_REQ) { @@ -2042,8 +2017,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) (status_byte(cmd->SCp.Status) == CHECK_CONDITION)) { scsi_eh_prep_cmnd(cmd, &hostdata->ses, NULL, 0, ~0); - SET_NEXT(cmd, hostdata->issue_queue); - hostdata->issue_queue = (struct scsi_cmnd *) cmd; + list_add(&ncmd->list, &hostdata->unissued); dsprintk(NDEBUG_AUTOSENSE | NDEBUG_QUEUES, instance, "REQUEST SENSE cmd %p added to head of issue queue\n", cmd); @@ -2092,9 +2066,8 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) case DISCONNECT: /* Accept message by clearing ACK */ NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); - SET_NEXT(cmd, hostdata->disconnected_queue); hostdata->connected = NULL; - hostdata->disconnected_queue = cmd; + list_add(&ncmd->list, &hostdata->disconnected); dsprintk(NDEBUG_INFORMATION | NDEBUG_QUEUES, instance, "connected command %p for target %d lun %llu moved to disconnected queue\n", cmd, scmd_id(cmd), cmd->device->lun); @@ -2288,7 +2261,8 @@ static void NCR5380_reselect(struct Scsi_Host *instance) unsigned char msg[3]; int __maybe_unused len; unsigned char __maybe_unused *data, __maybe_unused phase; - struct scsi_cmnd *tmp = NULL, *prev; + struct NCR5380_cmd *ncmd; + struct scsi_cmnd *tmp; /* * Disable arbitration, etc. since the host adapter obviously @@ -2379,19 +2353,18 @@ static void NCR5380_reselect(struct Scsi_Host *instance) * just reestablished, and remove it from the disconnected queue. */ - for (tmp = (struct scsi_cmnd *) hostdata->disconnected_queue, prev = NULL; - tmp; prev = tmp, tmp = NEXT(tmp)) { - if ((target_mask == (1 << tmp->device->id)) && (lun == (u8)tmp->device->lun) + tmp = NULL; + list_for_each_entry(ncmd, &hostdata->disconnected, list) { + struct scsi_cmnd *cmd = NCR5380_to_scmd(ncmd); + + if (target_mask == (1 << scmd_id(cmd)) && + lun == (u8)cmd->device->lun #ifdef SUPPORT_TAGS - && (tag == tmp->tag) + && (tag == cmd->tag) #endif ) { - if (prev) { - SET_NEXT(prev, NEXT(tmp)); - } else { - hostdata->disconnected_queue = NEXT(tmp); - } - SET_NEXT(tmp, NULL); + list_del(&ncmd->list); + tmp = cmd; break; } } @@ -2489,188 +2462,18 @@ int NCR5380_abort(struct scsi_cmnd *cmd) { struct Scsi_Host *instance = cmd->device->host; struct NCR5380_hostdata *hostdata = shost_priv(instance); - struct scsi_cmnd *tmp, **prev; unsigned long flags; - scmd_printk(KERN_NOTICE, cmd, "aborting command\n"); - spin_lock_irqsave(&hostdata->lock, flags); +#if (NDEBUG & NDEBUG_ANY) + scmd_printk(KERN_INFO, cmd, "aborting command\n"); +#endif NCR5380_dprint(NDEBUG_ANY, instance); NCR5380_dprint_phase(NDEBUG_ANY, instance); - dprintk(NDEBUG_ABORT, "scsi%d: abort called basr 0x%02x, sr 0x%02x\n", HOSTNO, - NCR5380_read(BUS_AND_STATUS_REG), - NCR5380_read(STATUS_REG)); - -#if 1 - /* - * Case 1 : If the command is the currently executing command, - * we'll set the aborted flag and return control so that - * information transfer routine can exit cleanly. - */ - - if (hostdata->connected == cmd) { - - dprintk(NDEBUG_ABORT, "scsi%d: aborting connected command\n", HOSTNO); - /* - * We should perform BSY checking, and make sure we haven't slipped - * into BUS FREE. - */ - - /* NCR5380_write(INITIATOR_COMMAND_REG, ICR_ASSERT_ATN); */ - /* - * Since we can't change phases until we've completed the current - * handshake, we have to source or sink a byte of data if the current - * phase is not MSGOUT. - */ - - /* - * Return control to the executing NCR drive so we can clear the - * aborted flag and get back into our main loop. - */ - - if (do_abort(instance) == 0) { - hostdata->connected = NULL; - cmd->result = DID_ABORT << 16; -#ifdef SUPPORT_TAGS - cmd_free_tag(cmd); -#else - hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun); -#endif - maybe_release_dma_irq(instance); - spin_unlock_irqrestore(&hostdata->lock, flags); - cmd->scsi_done(cmd); - return SUCCESS; - } else { - spin_unlock_irqrestore(&hostdata->lock, flags); - printk("scsi%d: abort of connected command failed!\n", HOSTNO); - return FAILED; - } - } -#endif - - /* - * Case 2 : If the command hasn't been issued yet, we simply remove it - * from the issue queue. - */ - for (prev = (struct scsi_cmnd **)&(hostdata->issue_queue), - tmp = (struct scsi_cmnd *)hostdata->issue_queue; - tmp; prev = NEXTADDR(tmp), tmp = NEXT(tmp)) { - if (cmd == tmp) { - (*prev) = NEXT(tmp); - SET_NEXT(tmp, NULL); - tmp->result = DID_ABORT << 16; - maybe_release_dma_irq(instance); - spin_unlock_irqrestore(&hostdata->lock, flags); - dprintk(NDEBUG_ABORT, "scsi%d: abort removed command from issue queue.\n", - HOSTNO); - /* Tagged queuing note: no tag to free here, hasn't been assigned - * yet... */ - tmp->scsi_done(tmp); - return SUCCESS; - } - } - - /* - * Case 3 : If any commands are connected, we're going to fail the abort - * and let the high level SCSI driver retry at a later time or - * issue a reset. - * - * Timeouts, and therefore aborted commands, will be highly unlikely - * and handling them cleanly in this situation would make the common - * case of noresets less efficient, and would pollute our code. So, - * we fail. - */ - - if (hostdata->connected) { - spin_unlock_irqrestore(&hostdata->lock, flags); - dprintk(NDEBUG_ABORT, "scsi%d: abort failed, command connected.\n", HOSTNO); - return FAILED; - } - - /* - * Case 4: If the command is currently disconnected from the bus, and - * there are no connected commands, we reconnect the I_T_L or - * I_T_L_Q nexus associated with it, go into message out, and send - * an abort message. - * - * This case is especially ugly. In order to reestablish the nexus, we - * need to call NCR5380_select(). The easiest way to implement this - * function was to abort if the bus was busy, and let the interrupt - * handler triggered on the SEL for reselect take care of lost arbitrations - * where necessary, meaning interrupts need to be enabled. - * - * When interrupts are enabled, the queues may change - so we - * can't remove it from the disconnected queue before selecting it - * because that could cause a failure in hashing the nexus if that - * device reselected. - * - * Since the queues may change, we can't use the pointers from when we - * first locate it. - * - * So, we must first locate the command, and if NCR5380_select() - * succeeds, then issue the abort, relocate the command and remove - * it from the disconnected queue. - */ - - for (tmp = (struct scsi_cmnd *) hostdata->disconnected_queue; tmp; - tmp = NEXT(tmp)) { - if (cmd == tmp) { - dprintk(NDEBUG_ABORT, "scsi%d: aborting disconnected command.\n", HOSTNO); - - if (NCR5380_select(instance, cmd)) { - spin_unlock_irq(&hostdata->lock); - return FAILED; - } - dprintk(NDEBUG_ABORT, "scsi%d: nexus reestablished.\n", HOSTNO); - - do_abort(instance); - - for (prev = (struct scsi_cmnd **)&(hostdata->disconnected_queue), - tmp = (struct scsi_cmnd *)hostdata->disconnected_queue; - tmp; prev = NEXTADDR(tmp), tmp = NEXT(tmp)) { - if (cmd == tmp) { - *prev = NEXT(tmp); - SET_NEXT(tmp, NULL); - tmp->result = DID_ABORT << 16; - /* We must unlock the tag/LUN immediately here, since the - * target goes to BUS FREE and doesn't send us another - * message (COMMAND_COMPLETE or the like) - */ -#ifdef SUPPORT_TAGS - cmd_free_tag(tmp); -#else - hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun); -#endif - maybe_release_dma_irq(instance); - spin_unlock_irqrestore(&hostdata->lock, flags); - tmp->scsi_done(tmp); - return SUCCESS; - } - } - } - } - - /* Maybe it is sufficient just to release the ST-DMA lock... (if - * possible at all) At least, we should check if the lock could be - * released after the abort, in case it is kept due to some bug. - */ - maybe_release_dma_irq(instance); spin_unlock_irqrestore(&hostdata->lock, flags); - /* - * Case 5 : If we reached this point, the command was not found in any of - * the queues. - * - * We probably reached this point because of an unlikely race condition - * between the command completing successfully and the abortion code, - * so we won't panic, but we will notify the user in case something really - * broke. - */ - - printk(KERN_INFO "scsi%d: warning : SCSI command probably completed successfully before abortion\n", HOSTNO); - return FAILED; } @@ -2710,16 +2513,18 @@ static int NCR5380_bus_reset(struct scsi_cmnd *cmd) * commands! */ - if (hostdata->issue_queue) - dsprintk(NDEBUG_ABORT, instance, "reset aborted issued command(s)\n"); if (hostdata->connected) dsprintk(NDEBUG_ABORT, instance, "reset aborted a connected command\n"); - if (hostdata->disconnected_queue) - dsprintk(NDEBUG_ABORT, instance, "reset aborted disconnected command(s)\n"); - - hostdata->issue_queue = NULL; hostdata->connected = NULL; - hostdata->disconnected_queue = NULL; + + if (!list_empty(&hostdata->unissued)) + dsprintk(NDEBUG_ABORT, instance, "reset aborted unissued list\n"); + INIT_LIST_HEAD(&hostdata->unissued); + + if (!list_empty(&hostdata->disconnected)) + dsprintk(NDEBUG_ABORT, instance, "reset aborted disconnected list\n"); + INIT_LIST_HEAD(&hostdata->disconnected); + #ifdef SUPPORT_TAGS free_all_tags(hostdata); #endif diff --git a/drivers/scsi/atari_scsi.c b/drivers/scsi/atari_scsi.c index e271b08ccbb2..263cf06a8f30 100644 --- a/drivers/scsi/atari_scsi.c +++ b/drivers/scsi/atari_scsi.c @@ -780,6 +780,7 @@ static struct scsi_host_template atari_scsi_template = { .eh_bus_reset_handler = atari_scsi_bus_reset, .this_id = 7, .use_clustering = DISABLE_CLUSTERING, + .cmd_size = NCR5380_CMD_SIZE, }; static int __init atari_scsi_probe(struct platform_device *pdev) diff --git a/drivers/scsi/dmx3191d.c b/drivers/scsi/dmx3191d.c index 51e63fe957c5..ddb4e616bfed 100644 --- a/drivers/scsi/dmx3191d.c +++ b/drivers/scsi/dmx3191d.c @@ -61,6 +61,7 @@ static struct scsi_host_template dmx3191d_driver_template = { .sg_tablesize = SG_ALL, .cmd_per_lun = 2, .use_clustering = DISABLE_CLUSTERING, + .cmd_size = NCR5380_CMD_SIZE, }; static int dmx3191d_probe_one(struct pci_dev *pdev, diff --git a/drivers/scsi/dtc.c b/drivers/scsi/dtc.c index d74661458f15..f6166e34e3b0 100644 --- a/drivers/scsi/dtc.c +++ b/drivers/scsi/dtc.c @@ -452,5 +452,6 @@ static struct scsi_host_template driver_template = { .sg_tablesize = SG_ALL, .cmd_per_lun = 2, .use_clustering = DISABLE_CLUSTERING, + .cmd_size = NCR5380_CMD_SIZE, }; #include "scsi_module.c" diff --git a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c index 0f2b3d9a6ae8..30472064170e 100644 --- a/drivers/scsi/g_NCR5380.c +++ b/drivers/scsi/g_NCR5380.c @@ -728,6 +728,7 @@ static struct scsi_host_template driver_template = { .sg_tablesize = SG_ALL, .cmd_per_lun = 2, .use_clustering = DISABLE_CLUSTERING, + .cmd_size = NCR5380_CMD_SIZE, }; #include "scsi_module.c" diff --git a/drivers/scsi/mac_scsi.c b/drivers/scsi/mac_scsi.c index e75bed25dd15..18f74b4a0b95 100644 --- a/drivers/scsi/mac_scsi.c +++ b/drivers/scsi/mac_scsi.c @@ -323,6 +323,7 @@ static struct scsi_host_template mac_scsi_template = { .sg_tablesize = SG_ALL, .cmd_per_lun = 2, .use_clustering = DISABLE_CLUSTERING, + .cmd_size = NCR5380_CMD_SIZE, }; static int __init mac_scsi_probe(struct platform_device *pdev) diff --git a/drivers/scsi/pas16.c b/drivers/scsi/pas16.c index 5f8a8295a5c1..77789405f4a9 100644 --- a/drivers/scsi/pas16.c +++ b/drivers/scsi/pas16.c @@ -562,6 +562,7 @@ static struct scsi_host_template driver_template = { .sg_tablesize = SG_ALL, .cmd_per_lun = 2, .use_clustering = DISABLE_CLUSTERING, + .cmd_size = NCR5380_CMD_SIZE, }; #include "scsi_module.c" diff --git a/drivers/scsi/sun3_scsi.c b/drivers/scsi/sun3_scsi.c index 14835540fecb..c10782b4843e 100644 --- a/drivers/scsi/sun3_scsi.c +++ b/drivers/scsi/sun3_scsi.c @@ -468,6 +468,7 @@ static struct scsi_host_template sun3_scsi_template = { .sg_tablesize = SG_NONE, .cmd_per_lun = 2, .use_clustering = DISABLE_CLUSTERING, + .cmd_size = NCR5380_CMD_SIZE, }; static int __init sun3_scsi_probe(struct platform_device *pdev) diff --git a/drivers/scsi/t128.c b/drivers/scsi/t128.c index d1ed1f532a24..e50881ab9eb4 100644 --- a/drivers/scsi/t128.c +++ b/drivers/scsi/t128.c @@ -406,5 +406,6 @@ static struct scsi_host_template driver_template = { .sg_tablesize = SG_ALL, .cmd_per_lun = 2, .use_clustering = DISABLE_CLUSTERING, + .cmd_size = NCR5380_CMD_SIZE, }; #include "scsi_module.c" -- cgit v1.2.3 From 0a4e36125451165847c6d4e7d5633d92e53f5c69 Mon Sep 17 00:00:00 2001 From: Finn Thain Date: Sun, 3 Jan 2016 16:06:07 +1100 Subject: ncr5380: Fix soft lockups Because of the rudimentary design of the chip, it is necessary to poll the SCSI bus signals during PIO and this tends to hog the CPU. The driver will accept new commands while others execute, and this causes a soft lockup because the workqueue item will not terminate until the issue queue is emptied. When exercising dmx3191d using sequential IO from dd, the driver is sent 512 KiB WRITE commands and 128 KiB READs. For a PIO transfer, the rate is is only about 300 KiB/s, so these are long-running commands. And although PDMA may run at several MiB/s, interrupts are disabled for the duration of the transfer. Fix the unresponsiveness and soft lockup issues by calling cond_resched() after each command is completed and by limiting max_sectors for drivers that don't implement real DMA. Signed-off-by: Finn Thain Reviewed-by: Hannes Reinecke Tested-by: Ondrej Zary Tested-by: Michael Schmitz Signed-off-by: Martin K. Petersen --- drivers/scsi/NCR5380.c | 6 ++++-- drivers/scsi/arm/cumana_1.c | 1 + drivers/scsi/arm/oak.c | 1 + drivers/scsi/atari_NCR5380.c | 6 ++++-- drivers/scsi/dmx3191d.c | 1 + drivers/scsi/dtc.c | 1 + drivers/scsi/g_NCR5380.c | 1 + drivers/scsi/mac_scsi.c | 1 + drivers/scsi/pas16.c | 1 + drivers/scsi/t128.c | 1 + 10 files changed, 16 insertions(+), 4 deletions(-) (limited to 'drivers/scsi/mac_scsi.c') diff --git a/drivers/scsi/NCR5380.c b/drivers/scsi/NCR5380.c index 9616f397e134..38b03af36a6a 100644 --- a/drivers/scsi/NCR5380.c +++ b/drivers/scsi/NCR5380.c @@ -890,10 +890,10 @@ static void NCR5380_main(struct work_struct *work) struct scsi_cmnd *cmd; int done; - spin_lock_irq(&hostdata->lock); do { done = 1; + spin_lock_irq(&hostdata->lock); while (!hostdata->connected && (cmd = dequeue_next_cmd(instance))) { @@ -930,8 +930,10 @@ static void NCR5380_main(struct work_struct *work) NCR5380_information_transfer(instance); done = 0; } + spin_unlock_irq(&hostdata->lock); + if (!done) + cond_resched(); } while (!done); - spin_unlock_irq(&hostdata->lock); } #ifndef DONT_USE_INTR diff --git a/drivers/scsi/arm/cumana_1.c b/drivers/scsi/arm/cumana_1.c index b526ba579ba3..221f18c5df93 100644 --- a/drivers/scsi/arm/cumana_1.c +++ b/drivers/scsi/arm/cumana_1.c @@ -209,6 +209,7 @@ static struct scsi_host_template cumanascsi_template = { .use_clustering = DISABLE_CLUSTERING, .proc_name = "CumanaSCSI-1", .cmd_size = NCR5380_CMD_SIZE, + .max_sectors = 128, }; static int cumanascsi1_probe(struct expansion_card *ec, diff --git a/drivers/scsi/arm/oak.c b/drivers/scsi/arm/oak.c index 70e648513275..1fab1d1896b1 100644 --- a/drivers/scsi/arm/oak.c +++ b/drivers/scsi/arm/oak.c @@ -115,6 +115,7 @@ static struct scsi_host_template oakscsi_template = { .use_clustering = DISABLE_CLUSTERING, .proc_name = "oakscsi", .cmd_size = NCR5380_CMD_SIZE, + .max_sectors = 128, }; static int oakscsi_probe(struct expansion_card *ec, const struct ecard_id *id) diff --git a/drivers/scsi/atari_NCR5380.c b/drivers/scsi/atari_NCR5380.c index b36fadab422b..a01921dfed0b 100644 --- a/drivers/scsi/atari_NCR5380.c +++ b/drivers/scsi/atari_NCR5380.c @@ -976,10 +976,10 @@ static void NCR5380_main(struct work_struct *work) * alter queues and touch the Falcon lock. */ - spin_lock_irq(&hostdata->lock); do { done = 1; + spin_lock_irq(&hostdata->lock); while (!hostdata->connected && (cmd = dequeue_next_cmd(instance))) { @@ -1026,8 +1026,10 @@ static void NCR5380_main(struct work_struct *work) NCR5380_information_transfer(instance); done = 0; } + spin_unlock_irq(&hostdata->lock); + if (!done) + cond_resched(); } while (!done); - spin_unlock_irq(&hostdata->lock); } diff --git a/drivers/scsi/dmx3191d.c b/drivers/scsi/dmx3191d.c index ddb4e616bfed..6c14e68b9e1a 100644 --- a/drivers/scsi/dmx3191d.c +++ b/drivers/scsi/dmx3191d.c @@ -62,6 +62,7 @@ static struct scsi_host_template dmx3191d_driver_template = { .cmd_per_lun = 2, .use_clustering = DISABLE_CLUSTERING, .cmd_size = NCR5380_CMD_SIZE, + .max_sectors = 128, }; static int dmx3191d_probe_one(struct pci_dev *pdev, diff --git a/drivers/scsi/dtc.c b/drivers/scsi/dtc.c index f6166e34e3b0..6c736b071cf4 100644 --- a/drivers/scsi/dtc.c +++ b/drivers/scsi/dtc.c @@ -453,5 +453,6 @@ static struct scsi_host_template driver_template = { .cmd_per_lun = 2, .use_clustering = DISABLE_CLUSTERING, .cmd_size = NCR5380_CMD_SIZE, + .max_sectors = 128, }; #include "scsi_module.c" diff --git a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c index 30472064170e..cd79ef402d7a 100644 --- a/drivers/scsi/g_NCR5380.c +++ b/drivers/scsi/g_NCR5380.c @@ -729,6 +729,7 @@ static struct scsi_host_template driver_template = { .cmd_per_lun = 2, .use_clustering = DISABLE_CLUSTERING, .cmd_size = NCR5380_CMD_SIZE, + .max_sectors = 128, }; #include "scsi_module.c" diff --git a/drivers/scsi/mac_scsi.c b/drivers/scsi/mac_scsi.c index 18f74b4a0b95..bb2381314a2b 100644 --- a/drivers/scsi/mac_scsi.c +++ b/drivers/scsi/mac_scsi.c @@ -324,6 +324,7 @@ static struct scsi_host_template mac_scsi_template = { .cmd_per_lun = 2, .use_clustering = DISABLE_CLUSTERING, .cmd_size = NCR5380_CMD_SIZE, + .max_sectors = 128, }; static int __init mac_scsi_probe(struct platform_device *pdev) diff --git a/drivers/scsi/pas16.c b/drivers/scsi/pas16.c index 77789405f4a9..512037e27783 100644 --- a/drivers/scsi/pas16.c +++ b/drivers/scsi/pas16.c @@ -563,6 +563,7 @@ static struct scsi_host_template driver_template = { .cmd_per_lun = 2, .use_clustering = DISABLE_CLUSTERING, .cmd_size = NCR5380_CMD_SIZE, + .max_sectors = 128, }; #include "scsi_module.c" diff --git a/drivers/scsi/t128.c b/drivers/scsi/t128.c index e50881ab9eb4..4615fda60dbd 100644 --- a/drivers/scsi/t128.c +++ b/drivers/scsi/t128.c @@ -407,5 +407,6 @@ static struct scsi_host_template driver_template = { .cmd_per_lun = 2, .use_clustering = DISABLE_CLUSTERING, .cmd_size = NCR5380_CMD_SIZE, + .max_sectors = 128, }; #include "scsi_module.c" -- cgit v1.2.3