diff options
author | James Bottomley <James.Bottomley@HansenPartnership.com> | 2016-01-13 19:29:30 -0500 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2016-01-13 19:29:30 -0500 |
commit | 60539fa3a1e3caf458a943b1a14154e3fa44d0d1 (patch) | |
tree | 9bca5f667844338ed877cb8b1684c9f661a003c3 /drivers/scsi | |
parent | abaee091a18c19ccd86feb1c8374585d82e96777 (diff) | |
parent | a290dd57926cb0c54eec7ea506885119e296b755 (diff) |
Merge remote-tracking branch 'mkp-scsi/4.5/scsi-queue' into misc
Diffstat (limited to 'drivers/scsi')
-rw-r--r-- | drivers/scsi/3w-xxxx.c | 3 | ||||
-rw-r--r-- | drivers/scsi/Kconfig | 17 | ||||
-rw-r--r-- | drivers/scsi/NCR5380.c | 2868 | ||||
-rw-r--r-- | drivers/scsi/NCR5380.h | 87 | ||||
-rw-r--r-- | drivers/scsi/arm/cumana_1.c | 31 | ||||
-rw-r--r-- | drivers/scsi/arm/oak.c | 27 | ||||
-rw-r--r-- | drivers/scsi/atari_NCR5380.c | 2266 | ||||
-rw-r--r-- | drivers/scsi/atari_scsi.c | 102 | ||||
-rw-r--r-- | drivers/scsi/cxgbi/cxgb3i/cxgb3i.c | 2 | ||||
-rw-r--r-- | drivers/scsi/dmx3191d.c | 33 | ||||
-rw-r--r-- | drivers/scsi/dtc.c | 115 | ||||
-rw-r--r-- | drivers/scsi/dtc.h | 45 | ||||
-rw-r--r-- | drivers/scsi/g_NCR5380.c | 408 | ||||
-rw-r--r-- | drivers/scsi/g_NCR5380.h | 66 | ||||
-rw-r--r-- | drivers/scsi/hisi_sas/hisi_sas_v1_hw.c | 40 | ||||
-rw-r--r-- | drivers/scsi/imm.c | 50 | ||||
-rw-r--r-- | drivers/scsi/ipr.c | 5 | ||||
-rw-r--r-- | drivers/scsi/mac_scsi.c | 117 | ||||
-rw-r--r-- | drivers/scsi/megaraid/megaraid_mm.c | 4 | ||||
-rw-r--r-- | drivers/scsi/pas16.c | 116 | ||||
-rw-r--r-- | drivers/scsi/pas16.h | 40 | ||||
-rw-r--r-- | drivers/scsi/scsi_devinfo.c | 1 | ||||
-rw-r--r-- | drivers/scsi/storvsc_drv.c | 2 | ||||
-rw-r--r-- | drivers/scsi/sun3_scsi.c | 141 | ||||
-rw-r--r-- | drivers/scsi/t128.c | 102 | ||||
-rw-r--r-- | drivers/scsi/t128.h | 39 |
26 files changed, 3009 insertions, 3718 deletions
diff --git a/drivers/scsi/3w-xxxx.c b/drivers/scsi/3w-xxxx.c index 2940bd769936..25aba1613e21 100644 --- a/drivers/scsi/3w-xxxx.c +++ b/drivers/scsi/3w-xxxx.c | |||
@@ -1045,6 +1045,9 @@ static int tw_chrdev_open(struct inode *inode, struct file *file) | |||
1045 | static const struct file_operations tw_fops = { | 1045 | static const struct file_operations tw_fops = { |
1046 | .owner = THIS_MODULE, | 1046 | .owner = THIS_MODULE, |
1047 | .unlocked_ioctl = tw_chrdev_ioctl, | 1047 | .unlocked_ioctl = tw_chrdev_ioctl, |
1048 | #ifdef CONFIG_COMPAT | ||
1049 | .compat_ioctl = tw_chrdev_ioctl, | ||
1050 | #endif | ||
1048 | .open = tw_chrdev_open, | 1051 | .open = tw_chrdev_open, |
1049 | .release = NULL, | 1052 | .release = NULL, |
1050 | .llseek = noop_llseek, | 1053 | .llseek = noop_llseek, |
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index c1fe0d2f90ca..23d862dfdde3 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig | |||
@@ -1620,23 +1620,6 @@ config ATARI_SCSI | |||
1620 | ST-DMA, replacing ACSI). It does NOT support other schemes, like | 1620 | ST-DMA, replacing ACSI). It does NOT support other schemes, like |
1621 | in the Hades (without DMA). | 1621 | in the Hades (without DMA). |
1622 | 1622 | ||
1623 | config ATARI_SCSI_TOSHIBA_DELAY | ||
1624 | bool "Long delays for Toshiba CD-ROMs" | ||
1625 | depends on ATARI_SCSI | ||
1626 | help | ||
1627 | This option increases the delay after a SCSI arbitration to | ||
1628 | accommodate some flaky Toshiba CD-ROM drives. Say Y if you intend to | ||
1629 | use a Toshiba CD-ROM drive; otherwise, the option is not needed and | ||
1630 | would impact performance a bit, so say N. | ||
1631 | |||
1632 | config ATARI_SCSI_RESET_BOOT | ||
1633 | bool "Reset SCSI-devices at boottime" | ||
1634 | depends on ATARI_SCSI | ||
1635 | help | ||
1636 | Reset the devices on your Atari whenever it boots. This makes the | ||
1637 | boot process fractionally longer but may assist recovery from errors | ||
1638 | that leave the devices with SCSI operations partway completed. | ||
1639 | |||
1640 | config MAC_SCSI | 1623 | config MAC_SCSI |
1641 | tristate "Macintosh NCR5380 SCSI" | 1624 | tristate "Macintosh NCR5380 SCSI" |
1642 | depends on MAC && SCSI=y | 1625 | depends on MAC && SCSI=y |
diff --git a/drivers/scsi/NCR5380.c b/drivers/scsi/NCR5380.c index a777e5c412df..d72867257346 100644 --- a/drivers/scsi/NCR5380.c +++ b/drivers/scsi/NCR5380.c | |||
@@ -1,17 +1,17 @@ | |||
1 | /* | 1 | /* |
2 | * NCR 5380 generic driver routines. These should make it *trivial* | 2 | * NCR 5380 generic driver routines. These should make it *trivial* |
3 | * to implement 5380 SCSI drivers under Linux with a non-trantor | 3 | * to implement 5380 SCSI drivers under Linux with a non-trantor |
4 | * architecture. | 4 | * architecture. |
5 | * | 5 | * |
6 | * Note that these routines also work with NR53c400 family chips. | 6 | * Note that these routines also work with NR53c400 family chips. |
7 | * | 7 | * |
8 | * Copyright 1993, Drew Eckhardt | 8 | * Copyright 1993, Drew Eckhardt |
9 | * Visionary Computing | 9 | * Visionary Computing |
10 | * (Unix and Linux consulting and custom programming) | 10 | * (Unix and Linux consulting and custom programming) |
11 | * drew@colorado.edu | 11 | * drew@colorado.edu |
12 | * +1 (303) 666-5836 | 12 | * +1 (303) 666-5836 |
13 | * | 13 | * |
14 | * For more information, please consult | 14 | * For more information, please consult |
15 | * | 15 | * |
16 | * NCR 5380 Family | 16 | * NCR 5380 Family |
17 | * SCSI Protocol Controller | 17 | * SCSI Protocol Controller |
@@ -25,84 +25,28 @@ | |||
25 | */ | 25 | */ |
26 | 26 | ||
27 | /* | 27 | /* |
28 | * Revision 1.10 1998/9/2 Alan Cox | 28 | * With contributions from Ray Van Tassle, Ingmar Baumgart, |
29 | * (alan@lxorguk.ukuu.org.uk) | 29 | * Ronald van Cuijlenborg, Alan Cox and others. |
30 | * Fixed up the timer lockups reported so far. Things still suck. Looking | ||
31 | * forward to 2.3 and per device request queues. Then it'll be possible to | ||
32 | * SMP thread this beast and improve life no end. | ||
33 | |||
34 | * Revision 1.9 1997/7/27 Ronald van Cuijlenborg | ||
35 | * (ronald.van.cuijlenborg@tip.nl or nutty@dds.nl) | ||
36 | * (hopefully) fixed and enhanced USLEEP | ||
37 | * added support for DTC3181E card (for Mustek scanner) | ||
38 | * | ||
39 | |||
40 | * Revision 1.8 Ingmar Baumgart | ||
41 | * (ingmar@gonzo.schwaben.de) | ||
42 | * added support for NCR53C400a card | ||
43 | * | ||
44 | |||
45 | * Revision 1.7 1996/3/2 Ray Van Tassle (rayvt@comm.mot.com) | ||
46 | * added proc_info | ||
47 | * added support needed for DTC 3180/3280 | ||
48 | * fixed a couple of bugs | ||
49 | * | ||
50 | |||
51 | * Revision 1.5 1994/01/19 09:14:57 drew | ||
52 | * Fixed udelay() hack that was being used on DATAOUT phases | ||
53 | * instead of a proper wait for the final handshake. | ||
54 | * | ||
55 | * Revision 1.4 1994/01/19 06:44:25 drew | ||
56 | * *** empty log message *** | ||
57 | * | ||
58 | * Revision 1.3 1994/01/19 05:24:40 drew | ||
59 | * Added support for TCR LAST_BYTE_SENT bit. | ||
60 | * | ||
61 | * Revision 1.2 1994/01/15 06:14:11 drew | ||
62 | * REAL DMA support, bug fixes. | ||
63 | * | ||
64 | * Revision 1.1 1994/01/15 06:00:54 drew | ||
65 | * Initial revision | ||
66 | * | ||
67 | */ | 30 | */ |
68 | 31 | ||
69 | /* | 32 | /* |
70 | * Further development / testing that should be done : | 33 | * Further development / testing that should be done : |
71 | * 1. Cleanup the NCR5380_transfer_dma function and DMA operation complete | 34 | * 1. Cleanup the NCR5380_transfer_dma function and DMA operation complete |
72 | * code so that everything does the same thing that's done at the | 35 | * code so that everything does the same thing that's done at the |
73 | * end of a pseudo-DMA read operation. | 36 | * end of a pseudo-DMA read operation. |
74 | * | 37 | * |
75 | * 2. Fix REAL_DMA (interrupt driven, polled works fine) - | 38 | * 2. Fix REAL_DMA (interrupt driven, polled works fine) - |
76 | * basically, transfer size needs to be reduced by one | 39 | * basically, transfer size needs to be reduced by one |
77 | * and the last byte read as is done with PSEUDO_DMA. | 40 | * and the last byte read as is done with PSEUDO_DMA. |
78 | * | 41 | * |
79 | * 4. Test SCSI-II tagged queueing (I have no devices which support | 42 | * 4. Test SCSI-II tagged queueing (I have no devices which support |
80 | * tagged queueing) | 43 | * tagged queueing) |
81 | * | ||
82 | * 5. Test linked command handling code after Eric is ready with | ||
83 | * the high level code. | ||
84 | */ | 44 | */ |
85 | #include <scsi/scsi_dbg.h> | ||
86 | #include <scsi/scsi_transport_spi.h> | ||
87 | |||
88 | #if (NDEBUG & NDEBUG_LISTS) | ||
89 | #define LIST(x,y) {printk("LINE:%d Adding %p to %p\n", __LINE__, (void*)(x), (void*)(y)); if ((x)==(y)) udelay(5); } | ||
90 | #define REMOVE(w,x,y,z) {printk("LINE:%d Removing: %p->%p %p->%p \n", __LINE__, (void*)(w), (void*)(x), (void*)(y), (void*)(z)); if ((x)==(y)) udelay(5); } | ||
91 | #else | ||
92 | #define LIST(x,y) | ||
93 | #define REMOVE(w,x,y,z) | ||
94 | #endif | ||
95 | 45 | ||
96 | #ifndef notyet | 46 | #ifndef notyet |
97 | #undef LINKED | ||
98 | #undef REAL_DMA | 47 | #undef REAL_DMA |
99 | #endif | 48 | #endif |
100 | 49 | ||
101 | #ifdef REAL_DMA_POLL | ||
102 | #undef READ_OVERRUNS | ||
103 | #define READ_OVERRUNS | ||
104 | #endif | ||
105 | |||
106 | #ifdef BOARD_REQUIRES_NO_DELAY | 50 | #ifdef BOARD_REQUIRES_NO_DELAY |
107 | #define io_recovery_delay(x) | 51 | #define io_recovery_delay(x) |
108 | #else | 52 | #else |
@@ -112,44 +56,28 @@ | |||
112 | /* | 56 | /* |
113 | * Design | 57 | * Design |
114 | * | 58 | * |
115 | * This is a generic 5380 driver. To use it on a different platform, | 59 | * This is a generic 5380 driver. To use it on a different platform, |
116 | * one simply writes appropriate system specific macros (ie, data | 60 | * one simply writes appropriate system specific macros (ie, data |
117 | * transfer - some PC's will use the I/O bus, 68K's must use | 61 | * transfer - some PC's will use the I/O bus, 68K's must use |
118 | * memory mapped) and drops this file in their 'C' wrapper. | 62 | * memory mapped) and drops this file in their 'C' wrapper. |
119 | * | 63 | * |
120 | * (Note from hch: unfortunately it was not enough for the different | 64 | * As far as command queueing, two queues are maintained for |
121 | * m68k folks and instead of improving this driver they copied it | ||
122 | * and hacked it up for their needs. As a consequence they lost | ||
123 | * most updates to this driver. Maybe someone will fix all these | ||
124 | * drivers to use a common core one day..) | ||
125 | * | ||
126 | * As far as command queueing, two queues are maintained for | ||
127 | * each 5380 in the system - commands that haven't been issued yet, | 65 | * each 5380 in the system - commands that haven't been issued yet, |
128 | * and commands that are currently executing. This means that an | 66 | * and commands that are currently executing. This means that an |
129 | * unlimited number of commands may be queued, letting | 67 | * unlimited number of commands may be queued, letting |
130 | * more commands propagate from the higher driver levels giving higher | 68 | * more commands propagate from the higher driver levels giving higher |
131 | * throughput. Note that both I_T_L and I_T_L_Q nexuses are supported, | 69 | * throughput. Note that both I_T_L and I_T_L_Q nexuses are supported, |
132 | * allowing multiple commands to propagate all the way to a SCSI-II device | 70 | * allowing multiple commands to propagate all the way to a SCSI-II device |
133 | * while a command is already executing. | 71 | * while a command is already executing. |
134 | * | 72 | * |
135 | * | 73 | * |
136 | * Issues specific to the NCR5380 : | 74 | * Issues specific to the NCR5380 : |
137 | * | 75 | * |
138 | * When used in a PIO or pseudo-dma mode, the NCR5380 is a braindead | 76 | * When used in a PIO or pseudo-dma mode, the NCR5380 is a braindead |
139 | * piece of hardware that requires you to sit in a loop polling for | 77 | * piece of hardware that requires you to sit in a loop polling for |
140 | * the REQ signal as long as you are connected. Some devices are | 78 | * the REQ signal as long as you are connected. Some devices are |
141 | * brain dead (ie, many TEXEL CD ROM drives) and won't disconnect | 79 | * brain dead (ie, many TEXEL CD ROM drives) and won't disconnect |
142 | * while doing long seek operations. | 80 | * while doing long seek operations. [...] These |
143 | * | ||
144 | * The workaround for this is to keep track of devices that have | ||
145 | * disconnected. If the device hasn't disconnected, for commands that | ||
146 | * should disconnect, we do something like | ||
147 | * | ||
148 | * while (!REQ is asserted) { sleep for N usecs; poll for M usecs } | ||
149 | * | ||
150 | * Some tweaking of N and M needs to be done. An algorithm based | ||
151 | * on "time to data" would give the best results as long as short time | ||
152 | * to datas (ie, on the same track) were considered, however these | ||
153 | * broken devices are the exception rather than the rule and I'd rather | 81 | * broken devices are the exception rather than the rule and I'd rather |
154 | * spend my time optimizing for the normal case. | 82 | * spend my time optimizing for the normal case. |
155 | * | 83 | * |
@@ -159,23 +87,23 @@ | |||
159 | * which is started from a workqueue for each NCR5380 host in the | 87 | * which is started from a workqueue for each NCR5380 host in the |
160 | * system. It attempts to establish I_T_L or I_T_L_Q nexuses by | 88 | * system. It attempts to establish I_T_L or I_T_L_Q nexuses by |
161 | * removing the commands from the issue queue and calling | 89 | * removing the commands from the issue queue and calling |
162 | * NCR5380_select() if a nexus is not established. | 90 | * NCR5380_select() if a nexus is not established. |
163 | * | 91 | * |
164 | * Once a nexus is established, the NCR5380_information_transfer() | 92 | * Once a nexus is established, the NCR5380_information_transfer() |
165 | * phase goes through the various phases as instructed by the target. | 93 | * phase goes through the various phases as instructed by the target. |
166 | * if the target goes into MSG IN and sends a DISCONNECT message, | 94 | * if the target goes into MSG IN and sends a DISCONNECT message, |
167 | * the command structure is placed into the per instance disconnected | 95 | * the command structure is placed into the per instance disconnected |
168 | * queue, and NCR5380_main tries to find more work. If the target is | 96 | * queue, and NCR5380_main tries to find more work. If the target is |
169 | * idle for too long, the system will try to sleep. | 97 | * idle for too long, the system will try to sleep. |
170 | * | 98 | * |
171 | * If a command has disconnected, eventually an interrupt will trigger, | 99 | * If a command has disconnected, eventually an interrupt will trigger, |
172 | * calling NCR5380_intr() which will in turn call NCR5380_reselect | 100 | * calling NCR5380_intr() which will in turn call NCR5380_reselect |
173 | * to reestablish a nexus. This will run main if necessary. | 101 | * to reestablish a nexus. This will run main if necessary. |
174 | * | 102 | * |
175 | * On command termination, the done function will be called as | 103 | * On command termination, the done function will be called as |
176 | * appropriate. | 104 | * appropriate. |
177 | * | 105 | * |
178 | * SCSI pointers are maintained in the SCp field of SCSI command | 106 | * SCSI pointers are maintained in the SCp field of SCSI command |
179 | * structures, being initialized after the command is connected | 107 | * structures, being initialized after the command is connected |
180 | * in NCR5380_select, and set as appropriate in NCR5380_information_transfer. | 108 | * in NCR5380_select, and set as appropriate in NCR5380_information_transfer. |
181 | * Note that in violation of the standard, an implicit SAVE POINTERS operation | 109 | * Note that in violation of the standard, an implicit SAVE POINTERS operation |
@@ -185,73 +113,48 @@ | |||
185 | /* | 113 | /* |
186 | * Using this file : | 114 | * Using this file : |
187 | * This file a skeleton Linux SCSI driver for the NCR 5380 series | 115 | * This file a skeleton Linux SCSI driver for the NCR 5380 series |
188 | * of chips. To use it, you write an architecture specific functions | 116 | * of chips. To use it, you write an architecture specific functions |
189 | * and macros and include this file in your driver. | 117 | * and macros and include this file in your driver. |
190 | * | 118 | * |
191 | * These macros control options : | 119 | * These macros control options : |
192 | * AUTOPROBE_IRQ - if defined, the NCR5380_probe_irq() function will be | 120 | * AUTOPROBE_IRQ - if defined, the NCR5380_probe_irq() function will be |
193 | * defined. | 121 | * defined. |
194 | * | 122 | * |
195 | * AUTOSENSE - if defined, REQUEST SENSE will be performed automatically | 123 | * AUTOSENSE - if defined, REQUEST SENSE will be performed automatically |
196 | * for commands that return with a CHECK CONDITION status. | 124 | * for commands that return with a CHECK CONDITION status. |
197 | * | 125 | * |
198 | * DIFFERENTIAL - if defined, NCR53c81 chips will use external differential | 126 | * DIFFERENTIAL - if defined, NCR53c81 chips will use external differential |
199 | * transceivers. | 127 | * transceivers. |
200 | * | 128 | * |
201 | * DONT_USE_INTR - if defined, never use interrupts, even if we probe or | 129 | * DONT_USE_INTR - if defined, never use interrupts, even if we probe or |
202 | * override-configure an IRQ. | 130 | * override-configure an IRQ. |
203 | * | ||
204 | * LIMIT_TRANSFERSIZE - if defined, limit the pseudo-dma transfers to 512 | ||
205 | * bytes at a time. Since interrupts are disabled by default during | ||
206 | * these transfers, we might need this to give reasonable interrupt | ||
207 | * service time if the transfer size gets too large. | ||
208 | * | ||
209 | * LINKED - if defined, linked commands are supported. | ||
210 | * | 131 | * |
211 | * PSEUDO_DMA - if defined, PSEUDO DMA is used during the data transfer phases. | 132 | * PSEUDO_DMA - if defined, PSEUDO DMA is used during the data transfer phases. |
212 | * | 133 | * |
213 | * REAL_DMA - if defined, REAL DMA is used during the data transfer phases. | 134 | * REAL_DMA - if defined, REAL DMA is used during the data transfer phases. |
214 | * | 135 | * |
215 | * REAL_DMA_POLL - if defined, REAL DMA is used but the driver doesn't | 136 | * REAL_DMA_POLL - if defined, REAL DMA is used but the driver doesn't |
216 | * rely on phase mismatch and EOP interrupts to determine end | 137 | * rely on phase mismatch and EOP interrupts to determine end |
217 | * of phase. | 138 | * of phase. |
218 | * | ||
219 | * UNSAFE - leave interrupts enabled during pseudo-DMA transfers. You | ||
220 | * only really want to use this if you're having a problem with | ||
221 | * dropped characters during high speed communications, and even | ||
222 | * then, you're going to be better off twiddling with transfersize | ||
223 | * in the high level code. | ||
224 | * | ||
225 | * Defaults for these will be provided although the user may want to adjust | ||
226 | * these to allocate CPU resources to the SCSI driver or "real" code. | ||
227 | * | ||
228 | * USLEEP_SLEEP - amount of time, in jiffies, to sleep | ||
229 | * | ||
230 | * USLEEP_POLL - amount of time, in jiffies, to poll | ||
231 | * | 139 | * |
232 | * These macros MUST be defined : | 140 | * These macros MUST be defined : |
233 | * NCR5380_local_declare() - declare any local variables needed for your | ||
234 | * transfer routines. | ||
235 | * | 141 | * |
236 | * NCR5380_setup(instance) - initialize any local variables needed from a given | ||
237 | * instance of the host adapter for NCR5380_{read,write,pread,pwrite} | ||
238 | * | ||
239 | * NCR5380_read(register) - read from the specified register | 142 | * NCR5380_read(register) - read from the specified register |
240 | * | 143 | * |
241 | * NCR5380_write(register, value) - write to the specific register | 144 | * NCR5380_write(register, value) - write to the specific register |
242 | * | 145 | * |
243 | * NCR5380_implementation_fields - additional fields needed for this | 146 | * NCR5380_implementation_fields - additional fields needed for this |
244 | * specific implementation of the NCR5380 | 147 | * specific implementation of the NCR5380 |
245 | * | 148 | * |
246 | * Either real DMA *or* pseudo DMA may be implemented | 149 | * Either real DMA *or* pseudo DMA may be implemented |
247 | * REAL functions : | 150 | * REAL functions : |
248 | * NCR5380_REAL_DMA should be defined if real DMA is to be used. | 151 | * NCR5380_REAL_DMA should be defined if real DMA is to be used. |
249 | * Note that the DMA setup functions should return the number of bytes | 152 | * Note that the DMA setup functions should return the number of bytes |
250 | * that they were able to program the controller for. | 153 | * that they were able to program the controller for. |
251 | * | 154 | * |
252 | * Also note that generic i386/PC versions of these macros are | 155 | * Also note that generic i386/PC versions of these macros are |
253 | * available as NCR5380_i386_dma_write_setup, | 156 | * available as NCR5380_i386_dma_write_setup, |
254 | * NCR5380_i386_dma_read_setup, and NCR5380_i386_dma_residual. | 157 | * NCR5380_i386_dma_read_setup, and NCR5380_i386_dma_residual. |
255 | * | 158 | * |
256 | * NCR5380_dma_write_setup(instance, src, count) - initialize | 159 | * NCR5380_dma_write_setup(instance, src, count) - initialize |
257 | * NCR5380_dma_read_setup(instance, dst, count) - initialize | 160 | * NCR5380_dma_read_setup(instance, dst, count) - initialize |
@@ -262,25 +165,25 @@ | |||
262 | * NCR5380_pread(instance, dst, count); | 165 | * NCR5380_pread(instance, dst, count); |
263 | * | 166 | * |
264 | * The generic driver is initialized by calling NCR5380_init(instance), | 167 | * The generic driver is initialized by calling NCR5380_init(instance), |
265 | * after setting the appropriate host specific fields and ID. If the | 168 | * after setting the appropriate host specific fields and ID. If the |
266 | * driver wishes to autoprobe for an IRQ line, the NCR5380_probe_irq(instance, | 169 | * driver wishes to autoprobe for an IRQ line, the NCR5380_probe_irq(instance, |
267 | * possible) function may be used. | 170 | * possible) function may be used. |
268 | */ | 171 | */ |
269 | 172 | ||
270 | static int do_abort(struct Scsi_Host *host); | 173 | static int do_abort(struct Scsi_Host *); |
271 | static void do_reset(struct Scsi_Host *host); | 174 | static void do_reset(struct Scsi_Host *); |
272 | 175 | ||
273 | /* | 176 | /** |
274 | * initialize_SCp - init the scsi pointer field | 177 | * initialize_SCp - init the scsi pointer field |
275 | * @cmd: command block to set up | 178 | * @cmd: command block to set up |
276 | * | 179 | * |
277 | * Set up the internal fields in the SCSI command. | 180 | * Set up the internal fields in the SCSI command. |
278 | */ | 181 | */ |
279 | 182 | ||
280 | static inline void initialize_SCp(struct scsi_cmnd *cmd) | 183 | static inline void initialize_SCp(struct scsi_cmnd *cmd) |
281 | { | 184 | { |
282 | /* | 185 | /* |
283 | * Initialize the Scsi Pointer field so that all of the commands in the | 186 | * Initialize the Scsi Pointer field so that all of the commands in the |
284 | * various queues are valid. | 187 | * various queues are valid. |
285 | */ | 188 | */ |
286 | 189 | ||
@@ -295,120 +198,123 @@ static inline void initialize_SCp(struct scsi_cmnd *cmd) | |||
295 | cmd->SCp.ptr = NULL; | 198 | cmd->SCp.ptr = NULL; |
296 | cmd->SCp.this_residual = 0; | 199 | cmd->SCp.this_residual = 0; |
297 | } | 200 | } |
201 | |||
202 | cmd->SCp.Status = 0; | ||
203 | cmd->SCp.Message = 0; | ||
298 | } | 204 | } |
299 | 205 | ||
300 | /** | 206 | /** |
301 | * NCR5380_poll_politely - wait for NCR5380 status bits | 207 | * NCR5380_poll_politely2 - wait for two chip register values |
302 | * @instance: controller to poll | 208 | * @instance: controller to poll |
303 | * @reg: 5380 register to poll | 209 | * @reg1: 5380 register to poll |
304 | * @bit: Bitmask to check | 210 | * @bit1: Bitmask to check |
305 | * @val: Value required to exit | 211 | * @val1: Expected value |
306 | * | 212 | * @reg2: Second 5380 register to poll |
307 | * Polls the NCR5380 in a reasonably efficient manner waiting for | 213 | * @bit2: Second bitmask to check |
308 | * an event to occur, after a short quick poll we begin giving the | 214 | * @val2: Second expected value |
309 | * CPU back in non IRQ contexts | 215 | * @wait: Time-out in jiffies |
310 | * | 216 | * |
311 | * Returns the value of the register or a negative error code. | 217 | * Polls the chip in a reasonably efficient manner waiting for an |
218 | * event to occur. After a short quick poll we begin to yield the CPU | ||
219 | * (if possible). In irq contexts the time-out is arbitrarily limited. | ||
220 | * Callers may hold locks as long as they are held in irq mode. | ||
221 | * | ||
222 | * Returns 0 if either or both event(s) occurred otherwise -ETIMEDOUT. | ||
312 | */ | 223 | */ |
313 | 224 | ||
314 | static int NCR5380_poll_politely(struct Scsi_Host *instance, int reg, int bit, int val, int t) | 225 | static int NCR5380_poll_politely2(struct Scsi_Host *instance, |
226 | int reg1, int bit1, int val1, | ||
227 | int reg2, int bit2, int val2, int wait) | ||
315 | { | 228 | { |
316 | NCR5380_local_declare(); | 229 | struct NCR5380_hostdata *hostdata = shost_priv(instance); |
317 | int n = 500; /* At about 8uS a cycle for the cpu access */ | 230 | unsigned long deadline = jiffies + wait; |
318 | unsigned long end = jiffies + t; | 231 | unsigned long n; |
319 | int r; | 232 | |
320 | 233 | /* Busy-wait for up to 10 ms */ | |
321 | NCR5380_setup(instance); | 234 | n = min(10000U, jiffies_to_usecs(wait)); |
322 | 235 | n *= hostdata->accesses_per_ms; | |
323 | while( n-- > 0) | 236 | n /= 2000; |
324 | { | 237 | do { |
325 | r = NCR5380_read(reg); | 238 | if ((NCR5380_read(reg1) & bit1) == val1) |
326 | if((r & bit) == val) | 239 | return 0; |
240 | if ((NCR5380_read(reg2) & bit2) == val2) | ||
327 | return 0; | 241 | return 0; |
328 | cpu_relax(); | 242 | cpu_relax(); |
329 | } | 243 | } while (n--); |
330 | 244 | ||
331 | /* t time yet ? */ | 245 | if (irqs_disabled() || in_interrupt()) |
332 | while(time_before(jiffies, end)) | 246 | return -ETIMEDOUT; |
333 | { | 247 | |
334 | r = NCR5380_read(reg); | 248 | /* Repeatedly sleep for 1 ms until deadline */ |
335 | if((r & bit) == val) | 249 | while (time_is_after_jiffies(deadline)) { |
250 | schedule_timeout_uninterruptible(1); | ||
251 | if ((NCR5380_read(reg1) & bit1) == val1) | ||
252 | return 0; | ||
253 | if ((NCR5380_read(reg2) & bit2) == val2) | ||
336 | return 0; | 254 | return 0; |
337 | if(!in_interrupt()) | ||
338 | cond_resched(); | ||
339 | else | ||
340 | cpu_relax(); | ||
341 | } | 255 | } |
256 | |||
342 | return -ETIMEDOUT; | 257 | return -ETIMEDOUT; |
343 | } | 258 | } |
344 | 259 | ||
345 | static struct { | 260 | static inline int NCR5380_poll_politely(struct Scsi_Host *instance, |
346 | unsigned char value; | 261 | int reg, int bit, int val, int wait) |
347 | const char *name; | 262 | { |
348 | } phases[] __maybe_unused = { | 263 | return NCR5380_poll_politely2(instance, reg, bit, val, |
349 | {PHASE_DATAOUT, "DATAOUT"}, | 264 | reg, bit, val, wait); |
350 | {PHASE_DATAIN, "DATAIN"}, | 265 | } |
351 | {PHASE_CMDOUT, "CMDOUT"}, | ||
352 | {PHASE_STATIN, "STATIN"}, | ||
353 | {PHASE_MSGOUT, "MSGOUT"}, | ||
354 | {PHASE_MSGIN, "MSGIN"}, | ||
355 | {PHASE_UNKNOWN, "UNKNOWN"} | ||
356 | }; | ||
357 | 266 | ||
358 | #if NDEBUG | 267 | #if NDEBUG |
359 | static struct { | 268 | static struct { |
360 | unsigned char mask; | 269 | unsigned char mask; |
361 | const char *name; | 270 | const char *name; |
362 | } signals[] = { | 271 | } signals[] = { |
363 | {SR_DBP, "PARITY"}, | 272 | {SR_DBP, "PARITY"}, |
364 | {SR_RST, "RST"}, | 273 | {SR_RST, "RST"}, |
365 | {SR_BSY, "BSY"}, | 274 | {SR_BSY, "BSY"}, |
366 | {SR_REQ, "REQ"}, | 275 | {SR_REQ, "REQ"}, |
367 | {SR_MSG, "MSG"}, | 276 | {SR_MSG, "MSG"}, |
368 | {SR_CD, "CD"}, | 277 | {SR_CD, "CD"}, |
369 | {SR_IO, "IO"}, | 278 | {SR_IO, "IO"}, |
370 | {SR_SEL, "SEL"}, | 279 | {SR_SEL, "SEL"}, |
371 | {0, NULL} | 280 | {0, NULL} |
372 | }, | 281 | }, |
373 | basrs[] = { | 282 | basrs[] = { |
374 | {BASR_ATN, "ATN"}, | 283 | {BASR_ATN, "ATN"}, |
375 | {BASR_ACK, "ACK"}, | 284 | {BASR_ACK, "ACK"}, |
376 | {0, NULL} | 285 | {0, NULL} |
377 | }, | 286 | }, |
378 | icrs[] = { | 287 | icrs[] = { |
379 | {ICR_ASSERT_RST, "ASSERT RST"}, | 288 | {ICR_ASSERT_RST, "ASSERT RST"}, |
380 | {ICR_ASSERT_ACK, "ASSERT ACK"}, | 289 | {ICR_ASSERT_ACK, "ASSERT ACK"}, |
381 | {ICR_ASSERT_BSY, "ASSERT BSY"}, | 290 | {ICR_ASSERT_BSY, "ASSERT BSY"}, |
382 | {ICR_ASSERT_SEL, "ASSERT SEL"}, | 291 | {ICR_ASSERT_SEL, "ASSERT SEL"}, |
383 | {ICR_ASSERT_ATN, "ASSERT ATN"}, | 292 | {ICR_ASSERT_ATN, "ASSERT ATN"}, |
384 | {ICR_ASSERT_DATA, "ASSERT DATA"}, | 293 | {ICR_ASSERT_DATA, "ASSERT DATA"}, |
385 | {0, NULL} | 294 | {0, NULL} |
386 | }, | 295 | }, |
387 | mrs[] = { | 296 | mrs[] = { |
388 | {MR_BLOCK_DMA_MODE, "MODE BLOCK DMA"}, | 297 | {MR_BLOCK_DMA_MODE, "MODE BLOCK DMA"}, |
389 | {MR_TARGET, "MODE TARGET"}, | 298 | {MR_TARGET, "MODE TARGET"}, |
390 | {MR_ENABLE_PAR_CHECK, "MODE PARITY CHECK"}, | 299 | {MR_ENABLE_PAR_CHECK, "MODE PARITY CHECK"}, |
391 | {MR_ENABLE_PAR_INTR, "MODE PARITY INTR"}, | 300 | {MR_ENABLE_PAR_INTR, "MODE PARITY INTR"}, |
392 | {MR_MONITOR_BSY, "MODE MONITOR BSY"}, | 301 | {MR_ENABLE_EOP_INTR, "MODE EOP INTR"}, |
393 | {MR_DMA_MODE, "MODE DMA"}, | 302 | {MR_MONITOR_BSY, "MODE MONITOR BSY"}, |
394 | {MR_ARBITRATE, "MODE ARBITRATION"}, | 303 | {MR_DMA_MODE, "MODE DMA"}, |
304 | {MR_ARBITRATE, "MODE ARBITRATION"}, | ||
395 | {0, NULL} | 305 | {0, NULL} |
396 | }; | 306 | }; |
397 | 307 | ||
398 | /** | 308 | /** |
399 | * NCR5380_print - print scsi bus signals | 309 | * NCR5380_print - print scsi bus signals |
400 | * @instance: adapter state to dump | 310 | * @instance: adapter state to dump |
401 | * | ||
402 | * Print the SCSI bus signals for debugging purposes | ||
403 | * | 311 | * |
404 | * Locks: caller holds hostdata lock (not essential) | 312 | * Print the SCSI bus signals for debugging purposes |
405 | */ | 313 | */ |
406 | 314 | ||
407 | static void NCR5380_print(struct Scsi_Host *instance) | 315 | static void NCR5380_print(struct Scsi_Host *instance) |
408 | { | 316 | { |
409 | NCR5380_local_declare(); | ||
410 | unsigned char status, data, basr, mr, icr, i; | 317 | unsigned char status, data, basr, mr, icr, i; |
411 | NCR5380_setup(instance); | ||
412 | 318 | ||
413 | data = NCR5380_read(CURRENT_SCSI_DATA_REG); | 319 | data = NCR5380_read(CURRENT_SCSI_DATA_REG); |
414 | status = NCR5380_read(STATUS_REG); | 320 | status = NCR5380_read(STATUS_REG); |
@@ -435,117 +341,56 @@ static void NCR5380_print(struct Scsi_Host *instance) | |||
435 | printk("\n"); | 341 | printk("\n"); |
436 | } | 342 | } |
437 | 343 | ||
344 | static struct { | ||
345 | unsigned char value; | ||
346 | const char *name; | ||
347 | } phases[] = { | ||
348 | {PHASE_DATAOUT, "DATAOUT"}, | ||
349 | {PHASE_DATAIN, "DATAIN"}, | ||
350 | {PHASE_CMDOUT, "CMDOUT"}, | ||
351 | {PHASE_STATIN, "STATIN"}, | ||
352 | {PHASE_MSGOUT, "MSGOUT"}, | ||
353 | {PHASE_MSGIN, "MSGIN"}, | ||
354 | {PHASE_UNKNOWN, "UNKNOWN"} | ||
355 | }; | ||
438 | 356 | ||
439 | /* | 357 | /** |
440 | * NCR5380_print_phase - show SCSI phase | 358 | * NCR5380_print_phase - show SCSI phase |
441 | * @instance: adapter to dump | 359 | * @instance: adapter to dump |
442 | * | ||
443 | * Print the current SCSI phase for debugging purposes | ||
444 | * | 360 | * |
445 | * Locks: none | 361 | * Print the current SCSI phase for debugging purposes |
446 | */ | 362 | */ |
447 | 363 | ||
448 | static void NCR5380_print_phase(struct Scsi_Host *instance) | 364 | static void NCR5380_print_phase(struct Scsi_Host *instance) |
449 | { | 365 | { |
450 | NCR5380_local_declare(); | ||
451 | unsigned char status; | 366 | unsigned char status; |
452 | int i; | 367 | int i; |
453 | NCR5380_setup(instance); | ||
454 | 368 | ||
455 | status = NCR5380_read(STATUS_REG); | 369 | status = NCR5380_read(STATUS_REG); |
456 | if (!(status & SR_REQ)) | 370 | if (!(status & SR_REQ)) |
457 | printk("scsi%d : REQ not asserted, phase unknown.\n", instance->host_no); | 371 | shost_printk(KERN_DEBUG, instance, "REQ not asserted, phase unknown.\n"); |
458 | else { | 372 | else { |
459 | for (i = 0; (phases[i].value != PHASE_UNKNOWN) && (phases[i].value != (status & PHASE_MASK)); ++i); | 373 | for (i = 0; (phases[i].value != PHASE_UNKNOWN) && |
460 | printk("scsi%d : phase %s\n", instance->host_no, phases[i].name); | 374 | (phases[i].value != (status & PHASE_MASK)); ++i) |
375 | ; | ||
376 | shost_printk(KERN_DEBUG, instance, "phase %s\n", phases[i].name); | ||
461 | } | 377 | } |
462 | } | 378 | } |
463 | #endif | 379 | #endif |
464 | 380 | ||
465 | /* | ||
466 | * These need tweaking, and would probably work best as per-device | ||
467 | * flags initialized differently for disk, tape, cd, etc devices. | ||
468 | * People with broken devices are free to experiment as to what gives | ||
469 | * the best results for them. | ||
470 | * | ||
471 | * USLEEP_SLEEP should be a minimum seek time. | ||
472 | * | ||
473 | * USLEEP_POLL should be a maximum rotational latency. | ||
474 | */ | ||
475 | #ifndef USLEEP_SLEEP | ||
476 | /* 20 ms (reasonable hard disk speed) */ | ||
477 | #define USLEEP_SLEEP msecs_to_jiffies(20) | ||
478 | #endif | ||
479 | /* 300 RPM (floppy speed) */ | ||
480 | #ifndef USLEEP_POLL | ||
481 | #define USLEEP_POLL msecs_to_jiffies(200) | ||
482 | #endif | ||
483 | #ifndef USLEEP_WAITLONG | ||
484 | /* RvC: (reasonable time to wait on select error) */ | ||
485 | #define USLEEP_WAITLONG USLEEP_SLEEP | ||
486 | #endif | ||
487 | 381 | ||
488 | /* | 382 | static int probe_irq __initdata; |
489 | * Function : int should_disconnect (unsigned char cmd) | ||
490 | * | ||
491 | * Purpose : decide whether a command would normally disconnect or | ||
492 | * not, since if it won't disconnect we should go to sleep. | ||
493 | * | ||
494 | * Input : cmd - opcode of SCSI command | ||
495 | * | ||
496 | * Returns : DISCONNECT_LONG if we should disconnect for a really long | ||
497 | * time (ie always, sleep, look for REQ active, sleep), | ||
498 | * DISCONNECT_TIME_TO_DATA if we would only disconnect for a normal | ||
499 | * time-to-data delay, DISCONNECT_NONE if this command would return | ||
500 | * immediately. | ||
501 | * | ||
502 | * Future sleep algorithms based on time to data can exploit | ||
503 | * something like this so they can differentiate between "normal" | ||
504 | * (ie, read, write, seek) and unusual commands (ie, * format). | ||
505 | * | ||
506 | * Note : We don't deal with commands that handle an immediate disconnect, | ||
507 | * | ||
508 | */ | ||
509 | |||
510 | static int should_disconnect(unsigned char cmd) | ||
511 | { | ||
512 | switch (cmd) { | ||
513 | case READ_6: | ||
514 | case WRITE_6: | ||
515 | case SEEK_6: | ||
516 | case READ_10: | ||
517 | case WRITE_10: | ||
518 | case SEEK_10: | ||
519 | return DISCONNECT_TIME_TO_DATA; | ||
520 | case FORMAT_UNIT: | ||
521 | case SEARCH_HIGH: | ||
522 | case SEARCH_LOW: | ||
523 | case SEARCH_EQUAL: | ||
524 | return DISCONNECT_LONG; | ||
525 | default: | ||
526 | return DISCONNECT_NONE; | ||
527 | } | ||
528 | } | ||
529 | |||
530 | static void NCR5380_set_timer(struct NCR5380_hostdata *hostdata, unsigned long timeout) | ||
531 | { | ||
532 | hostdata->time_expires = jiffies + timeout; | ||
533 | schedule_delayed_work(&hostdata->coroutine, timeout); | ||
534 | } | ||
535 | |||
536 | |||
537 | static int probe_irq __initdata = 0; | ||
538 | 383 | ||
539 | /** | 384 | /** |
540 | * probe_intr - helper for IRQ autoprobe | 385 | * probe_intr - helper for IRQ autoprobe |
541 | * @irq: interrupt number | 386 | * @irq: interrupt number |
542 | * @dev_id: unused | 387 | * @dev_id: unused |
543 | * @regs: unused | 388 | * @regs: unused |
544 | * | 389 | * |
545 | * Set a flag to indicate the IRQ in question was received. This is | 390 | * Set a flag to indicate the IRQ in question was received. This is |
546 | * used by the IRQ probe code. | 391 | * used by the IRQ probe code. |
547 | */ | 392 | */ |
548 | 393 | ||
549 | static irqreturn_t __init probe_intr(int irq, void *dev_id) | 394 | static irqreturn_t __init probe_intr(int irq, void *dev_id) |
550 | { | 395 | { |
551 | probe_irq = irq; | 396 | probe_irq = irq; |
@@ -553,24 +398,20 @@ static irqreturn_t __init probe_intr(int irq, void *dev_id) | |||
553 | } | 398 | } |
554 | 399 | ||
555 | /** | 400 | /** |
556 | * NCR5380_probe_irq - find the IRQ of an NCR5380 | 401 | * NCR5380_probe_irq - find the IRQ of an NCR5380 |
557 | * @instance: NCR5380 controller | 402 | * @instance: NCR5380 controller |
558 | * @possible: bitmask of ISA IRQ lines | 403 | * @possible: bitmask of ISA IRQ lines |
559 | * | 404 | * |
560 | * Autoprobe for the IRQ line used by the NCR5380 by triggering an IRQ | 405 | * Autoprobe for the IRQ line used by the NCR5380 by triggering an IRQ |
561 | * and then looking to see what interrupt actually turned up. | 406 | * and then looking to see what interrupt actually turned up. |
562 | * | ||
563 | * Locks: none, irqs must be enabled on entry | ||
564 | */ | 407 | */ |
565 | 408 | ||
566 | static int __init __maybe_unused NCR5380_probe_irq(struct Scsi_Host *instance, | 409 | static int __init __maybe_unused NCR5380_probe_irq(struct Scsi_Host *instance, |
567 | int possible) | 410 | int possible) |
568 | { | 411 | { |
569 | NCR5380_local_declare(); | 412 | struct NCR5380_hostdata *hostdata = shost_priv(instance); |
570 | struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata; | ||
571 | unsigned long timeout; | 413 | unsigned long timeout; |
572 | int trying_irqs, i, mask; | 414 | int trying_irqs, i, mask; |
573 | NCR5380_setup(instance); | ||
574 | 415 | ||
575 | for (trying_irqs = 0, i = 1, mask = 2; i < 16; ++i, mask <<= 1) | 416 | for (trying_irqs = 0, i = 1, mask = 2; i < 16; ++i, mask <<= 1) |
576 | if ((mask & possible) && (request_irq(i, &probe_intr, 0, "NCR-probe", NULL) == 0)) | 417 | if ((mask & possible) && (request_irq(i, &probe_intr, 0, "NCR-probe", NULL) == 0)) |
@@ -581,7 +422,7 @@ static int __init __maybe_unused NCR5380_probe_irq(struct Scsi_Host *instance, | |||
581 | 422 | ||
582 | /* | 423 | /* |
583 | * A interrupt is triggered whenever BSY = false, SEL = true | 424 | * A interrupt is triggered whenever BSY = false, SEL = true |
584 | * and a bit set in the SELECT_ENABLE_REG is asserted on the | 425 | * and a bit set in the SELECT_ENABLE_REG is asserted on the |
585 | * SCSI bus. | 426 | * SCSI bus. |
586 | * | 427 | * |
587 | * Note that the bus is only driven when the phase control signals | 428 | * Note that the bus is only driven when the phase control signals |
@@ -596,7 +437,7 @@ static int __init __maybe_unused NCR5380_probe_irq(struct Scsi_Host *instance, | |||
596 | 437 | ||
597 | while (probe_irq == NO_IRQ && time_before(jiffies, timeout)) | 438 | while (probe_irq == NO_IRQ && time_before(jiffies, timeout)) |
598 | schedule_timeout_uninterruptible(1); | 439 | schedule_timeout_uninterruptible(1); |
599 | 440 | ||
600 | NCR5380_write(SELECT_ENABLE_REG, 0); | 441 | NCR5380_write(SELECT_ENABLE_REG, 0); |
601 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); | 442 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); |
602 | 443 | ||
@@ -608,12 +449,10 @@ static int __init __maybe_unused NCR5380_probe_irq(struct Scsi_Host *instance, | |||
608 | } | 449 | } |
609 | 450 | ||
610 | /** | 451 | /** |
611 | * NCR58380_info - report driver and host information | 452 | * NCR58380_info - report driver and host information |
612 | * @instance: relevant scsi host instance | 453 | * @instance: relevant scsi host instance |
613 | * | ||
614 | * For use as the host template info() handler. | ||
615 | * | 454 | * |
616 | * Locks: none | 455 | * For use as the host template info() handler. |
617 | */ | 456 | */ |
618 | 457 | ||
619 | static const char *NCR5380_info(struct Scsi_Host *instance) | 458 | static const char *NCR5380_info(struct Scsi_Host *instance) |
@@ -633,20 +472,14 @@ static void prepare_info(struct Scsi_Host *instance) | |||
633 | "can_queue %d, cmd_per_lun %d, " | 472 | "can_queue %d, cmd_per_lun %d, " |
634 | "sg_tablesize %d, this_id %d, " | 473 | "sg_tablesize %d, this_id %d, " |
635 | "flags { %s%s%s}, " | 474 | "flags { %s%s%s}, " |
636 | #if defined(USLEEP_POLL) && defined(USLEEP_WAITLONG) | ||
637 | "USLEEP_POLL %lu, USLEEP_WAITLONG %lu, " | ||
638 | #endif | ||
639 | "options { %s} ", | 475 | "options { %s} ", |
640 | instance->hostt->name, instance->io_port, instance->n_io_port, | 476 | instance->hostt->name, instance->io_port, instance->n_io_port, |
641 | instance->base, instance->irq, | 477 | instance->base, instance->irq, |
642 | instance->can_queue, instance->cmd_per_lun, | 478 | instance->can_queue, instance->cmd_per_lun, |
643 | instance->sg_tablesize, instance->this_id, | 479 | instance->sg_tablesize, instance->this_id, |
644 | hostdata->flags & FLAG_NCR53C400 ? "NCR53C400 " : "", | 480 | hostdata->flags & FLAG_NO_DMA_FIXUP ? "NO_DMA_FIXUP " : "", |
645 | hostdata->flags & FLAG_DTC3181E ? "DTC3181E " : "", | ||
646 | hostdata->flags & FLAG_NO_PSEUDO_DMA ? "NO_PSEUDO_DMA " : "", | 481 | hostdata->flags & FLAG_NO_PSEUDO_DMA ? "NO_PSEUDO_DMA " : "", |
647 | #if defined(USLEEP_POLL) && defined(USLEEP_WAITLONG) | 482 | hostdata->flags & FLAG_TOSHIBA_DELAY ? "TOSHIBA_DELAY " : "", |
648 | USLEEP_POLL, USLEEP_WAITLONG, | ||
649 | #endif | ||
650 | #ifdef AUTOPROBE_IRQ | 483 | #ifdef AUTOPROBE_IRQ |
651 | "AUTOPROBE_IRQ " | 484 | "AUTOPROBE_IRQ " |
652 | #endif | 485 | #endif |
@@ -665,46 +498,10 @@ static void prepare_info(struct Scsi_Host *instance) | |||
665 | #ifdef PSEUDO_DMA | 498 | #ifdef PSEUDO_DMA |
666 | "PSEUDO_DMA " | 499 | "PSEUDO_DMA " |
667 | #endif | 500 | #endif |
668 | #ifdef UNSAFE | ||
669 | "UNSAFE " | ||
670 | #endif | ||
671 | #ifdef NCR53C400 | ||
672 | "NCR53C400 " | ||
673 | #endif | ||
674 | ""); | 501 | ""); |
675 | } | 502 | } |
676 | 503 | ||
677 | /** | ||
678 | * NCR5380_print_status - dump controller info | ||
679 | * @instance: controller to dump | ||
680 | * | ||
681 | * Print commands in the various queues, called from NCR5380_abort | ||
682 | * and NCR5380_debug to aid debugging. | ||
683 | * | ||
684 | * Locks: called functions disable irqs | ||
685 | */ | ||
686 | |||
687 | static void NCR5380_print_status(struct Scsi_Host *instance) | ||
688 | { | ||
689 | NCR5380_dprint(NDEBUG_ANY, instance); | ||
690 | NCR5380_dprint_phase(NDEBUG_ANY, instance); | ||
691 | } | ||
692 | |||
693 | #ifdef PSEUDO_DMA | 504 | #ifdef PSEUDO_DMA |
694 | /******************************************/ | ||
695 | /* | ||
696 | * /proc/scsi/[dtc pas16 t128 generic]/[0-ASC_NUM_BOARD_SUPPORTED] | ||
697 | * | ||
698 | * *buffer: I/O buffer | ||
699 | * **start: if inout == FALSE pointer into buffer where user read should start | ||
700 | * offset: current offset | ||
701 | * length: length of buffer | ||
702 | * hostno: Scsi_Host host_no | ||
703 | * inout: TRUE - user is writing; FALSE - user is reading | ||
704 | * | ||
705 | * Return the number of bytes read from or written | ||
706 | */ | ||
707 | |||
708 | static int __maybe_unused NCR5380_write_info(struct Scsi_Host *instance, | 505 | static int __maybe_unused NCR5380_write_info(struct Scsi_Host *instance, |
709 | char *buffer, int length) | 506 | char *buffer, int length) |
710 | { | 507 | { |
@@ -714,104 +511,41 @@ static int __maybe_unused NCR5380_write_info(struct Scsi_Host *instance, | |||
714 | hostdata->spin_max_w = 0; | 511 | hostdata->spin_max_w = 0; |
715 | return 0; | 512 | return 0; |
716 | } | 513 | } |
717 | #endif | ||
718 | |||
719 | static | ||
720 | void lprint_Scsi_Cmnd(struct scsi_cmnd *cmd, struct seq_file *m); | ||
721 | static | ||
722 | void lprint_command(unsigned char *cmd, struct seq_file *m); | ||
723 | static | ||
724 | void lprint_opcode(int opcode, struct seq_file *m); | ||
725 | 514 | ||
726 | static int __maybe_unused NCR5380_show_info(struct seq_file *m, | 515 | static int __maybe_unused NCR5380_show_info(struct seq_file *m, |
727 | struct Scsi_Host *instance) | 516 | struct Scsi_Host *instance) |
728 | { | 517 | { |
729 | struct NCR5380_hostdata *hostdata; | 518 | struct NCR5380_hostdata *hostdata = shost_priv(instance); |
730 | struct scsi_cmnd *ptr; | ||
731 | |||
732 | hostdata = (struct NCR5380_hostdata *) instance->hostdata; | ||
733 | 519 | ||
734 | #ifdef PSEUDO_DMA | ||
735 | seq_printf(m, "Highwater I/O busy spin counts: write %d, read %d\n", | 520 | seq_printf(m, "Highwater I/O busy spin counts: write %d, read %d\n", |
736 | hostdata->spin_max_w, hostdata->spin_max_r); | 521 | hostdata->spin_max_w, hostdata->spin_max_r); |
737 | #endif | ||
738 | spin_lock_irq(instance->host_lock); | ||
739 | if (!hostdata->connected) | ||
740 | seq_printf(m, "scsi%d: no currently connected command\n", instance->host_no); | ||
741 | else | ||
742 | lprint_Scsi_Cmnd((struct scsi_cmnd *) hostdata->connected, m); | ||
743 | seq_printf(m, "scsi%d: issue_queue\n", instance->host_no); | ||
744 | for (ptr = (struct scsi_cmnd *) hostdata->issue_queue; ptr; ptr = (struct scsi_cmnd *) ptr->host_scribble) | ||
745 | lprint_Scsi_Cmnd(ptr, m); | ||
746 | |||
747 | seq_printf(m, "scsi%d: disconnected_queue\n", instance->host_no); | ||
748 | for (ptr = (struct scsi_cmnd *) hostdata->disconnected_queue; ptr; ptr = (struct scsi_cmnd *) ptr->host_scribble) | ||
749 | lprint_Scsi_Cmnd(ptr, m); | ||
750 | spin_unlock_irq(instance->host_lock); | ||
751 | return 0; | 522 | return 0; |
752 | } | 523 | } |
753 | 524 | #endif | |
754 | static void lprint_Scsi_Cmnd(struct scsi_cmnd *cmd, struct seq_file *m) | ||
755 | { | ||
756 | seq_printf(m, "scsi%d : destination target %d, lun %llu\n", cmd->device->host->host_no, cmd->device->id, cmd->device->lun); | ||
757 | seq_puts(m, " command = "); | ||
758 | lprint_command(cmd->cmnd, m); | ||
759 | } | ||
760 | |||
761 | static void lprint_command(unsigned char *command, struct seq_file *m) | ||
762 | { | ||
763 | int i, s; | ||
764 | lprint_opcode(command[0], m); | ||
765 | for (i = 1, s = COMMAND_SIZE(command[0]); i < s; ++i) | ||
766 | seq_printf(m, "%02x ", command[i]); | ||
767 | seq_putc(m, '\n'); | ||
768 | } | ||
769 | |||
770 | static void lprint_opcode(int opcode, struct seq_file *m) | ||
771 | { | ||
772 | seq_printf(m, "%2d (0x%02x)", opcode, opcode); | ||
773 | } | ||
774 | |||
775 | 525 | ||
776 | /** | 526 | /** |
777 | * NCR5380_init - initialise an NCR5380 | 527 | * NCR5380_init - initialise an NCR5380 |
778 | * @instance: adapter to configure | 528 | * @instance: adapter to configure |
779 | * @flags: control flags | 529 | * @flags: control flags |
780 | * | 530 | * |
781 | * Initializes *instance and corresponding 5380 chip, | 531 | * Initializes *instance and corresponding 5380 chip, |
782 | * with flags OR'd into the initial flags value. | 532 | * with flags OR'd into the initial flags value. |
783 | * | 533 | * |
784 | * Notes : I assume that the host, hostno, and id bits have been | 534 | * Notes : I assume that the host, hostno, and id bits have been |
785 | * set correctly. I don't care about the irq and other fields. | 535 | * set correctly. I don't care about the irq and other fields. |
786 | * | 536 | * |
787 | * Returns 0 for success | 537 | * Returns 0 for success |
788 | * | ||
789 | * Locks: interrupts must be enabled when we are called | ||
790 | */ | 538 | */ |
791 | 539 | ||
792 | static int NCR5380_init(struct Scsi_Host *instance, int flags) | 540 | static int NCR5380_init(struct Scsi_Host *instance, int flags) |
793 | { | 541 | { |
794 | NCR5380_local_declare(); | 542 | struct NCR5380_hostdata *hostdata = shost_priv(instance); |
795 | int i, pass; | 543 | int i; |
796 | unsigned long timeout; | 544 | unsigned long deadline; |
797 | struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata; | ||
798 | |||
799 | if(in_interrupt()) | ||
800 | printk(KERN_ERR "NCR5380_init called with interrupts off!\n"); | ||
801 | /* | ||
802 | * On NCR53C400 boards, NCR5380 registers are mapped 8 past | ||
803 | * the base address. | ||
804 | */ | ||
805 | |||
806 | #ifdef NCR53C400 | ||
807 | if (flags & FLAG_NCR53C400) | ||
808 | instance->NCR5380_instance_name += NCR53C400_address_adjust; | ||
809 | #endif | ||
810 | |||
811 | NCR5380_setup(instance); | ||
812 | 545 | ||
813 | hostdata->aborted = 0; | 546 | hostdata->host = instance; |
814 | hostdata->id_mask = 1 << instance->this_id; | 547 | hostdata->id_mask = 1 << instance->this_id; |
548 | hostdata->id_higher_mask = 0; | ||
815 | for (i = hostdata->id_mask; i <= 0x80; i <<= 1) | 549 | for (i = hostdata->id_mask; i <= 0x80; i <<= 1) |
816 | if (i > hostdata->id_mask) | 550 | if (i > hostdata->id_mask) |
817 | hostdata->id_higher_mask |= i; | 551 | hostdata->id_higher_mask |= i; |
@@ -820,21 +554,21 @@ static int NCR5380_init(struct Scsi_Host *instance, int flags) | |||
820 | #ifdef REAL_DMA | 554 | #ifdef REAL_DMA |
821 | hostdata->dmalen = 0; | 555 | hostdata->dmalen = 0; |
822 | #endif | 556 | #endif |
823 | hostdata->targets_present = 0; | 557 | spin_lock_init(&hostdata->lock); |
824 | hostdata->connected = NULL; | 558 | hostdata->connected = NULL; |
825 | hostdata->issue_queue = NULL; | 559 | hostdata->sensing = NULL; |
826 | hostdata->disconnected_queue = NULL; | 560 | INIT_LIST_HEAD(&hostdata->autosense); |
827 | 561 | INIT_LIST_HEAD(&hostdata->unissued); | |
828 | INIT_DELAYED_WORK(&hostdata->coroutine, NCR5380_main); | 562 | INIT_LIST_HEAD(&hostdata->disconnected); |
829 | |||
830 | /* The CHECK code seems to break the 53C400. Will check it later maybe */ | ||
831 | if (flags & FLAG_NCR53C400) | ||
832 | hostdata->flags = FLAG_HAS_LAST_BYTE_SENT | flags; | ||
833 | else | ||
834 | hostdata->flags = FLAG_CHECK_LAST_BYTE_SENT | flags; | ||
835 | 563 | ||
836 | hostdata->host = instance; | 564 | hostdata->flags = flags; |
837 | hostdata->time_expires = 0; | 565 | |
566 | INIT_WORK(&hostdata->main_task, NCR5380_main); | ||
567 | hostdata->work_q = alloc_workqueue("ncr5380_%d", | ||
568 | WQ_UNBOUND | WQ_MEM_RECLAIM, | ||
569 | 1, instance->host_no); | ||
570 | if (!hostdata->work_q) | ||
571 | return -ENOMEM; | ||
838 | 572 | ||
839 | prepare_info(instance); | 573 | prepare_info(instance); |
840 | 574 | ||
@@ -843,43 +577,69 @@ static int NCR5380_init(struct Scsi_Host *instance, int flags) | |||
843 | NCR5380_write(TARGET_COMMAND_REG, 0); | 577 | NCR5380_write(TARGET_COMMAND_REG, 0); |
844 | NCR5380_write(SELECT_ENABLE_REG, 0); | 578 | NCR5380_write(SELECT_ENABLE_REG, 0); |
845 | 579 | ||
846 | #ifdef NCR53C400 | 580 | /* Calibrate register polling loop */ |
847 | if (hostdata->flags & FLAG_NCR53C400) { | 581 | i = 0; |
848 | NCR5380_write(C400_CONTROL_STATUS_REG, CSR_BASE); | 582 | deadline = jiffies + 1; |
849 | } | 583 | do { |
850 | #endif | 584 | cpu_relax(); |
585 | } while (time_is_after_jiffies(deadline)); | ||
586 | deadline += msecs_to_jiffies(256); | ||
587 | do { | ||
588 | NCR5380_read(STATUS_REG); | ||
589 | ++i; | ||
590 | cpu_relax(); | ||
591 | } while (time_is_after_jiffies(deadline)); | ||
592 | hostdata->accesses_per_ms = i / 256; | ||
851 | 593 | ||
852 | /* | 594 | return 0; |
853 | * Detect and correct bus wedge problems. | 595 | } |
854 | * | 596 | |
855 | * If the system crashed, it may have crashed in a state | 597 | /** |
856 | * where a SCSI command was still executing, and the | 598 | * NCR5380_maybe_reset_bus - Detect and correct bus wedge problems. |
857 | * SCSI bus is not in a BUS FREE STATE. | 599 | * @instance: adapter to check |
858 | * | 600 | * |
859 | * If this is the case, we'll try to abort the currently | 601 | * If the system crashed, it may have crashed with a connected target and |
860 | * established nexus which we know nothing about, and that | 602 | * the SCSI bus busy. Check for BUS FREE phase. If not, try to abort the |
861 | * failing, do a hard reset of the SCSI bus | 603 | * currently established nexus, which we know nothing about. Failing that |
862 | */ | 604 | * do a bus reset. |
605 | * | ||
606 | * Note that a bus reset will cause the chip to assert IRQ. | ||
607 | * | ||
608 | * Returns 0 if successful, otherwise -ENXIO. | ||
609 | */ | ||
610 | |||
611 | static int NCR5380_maybe_reset_bus(struct Scsi_Host *instance) | ||
612 | { | ||
613 | struct NCR5380_hostdata *hostdata = shost_priv(instance); | ||
614 | int pass; | ||
863 | 615 | ||
864 | for (pass = 1; (NCR5380_read(STATUS_REG) & SR_BSY) && pass <= 6; ++pass) { | 616 | for (pass = 1; (NCR5380_read(STATUS_REG) & SR_BSY) && pass <= 6; ++pass) { |
865 | switch (pass) { | 617 | switch (pass) { |
866 | case 1: | 618 | case 1: |
867 | case 3: | 619 | case 3: |
868 | case 5: | 620 | case 5: |
869 | printk(KERN_INFO "scsi%d: SCSI bus busy, waiting up to five seconds\n", instance->host_no); | 621 | shost_printk(KERN_ERR, instance, "SCSI bus busy, waiting up to five seconds\n"); |
870 | timeout = jiffies + 5 * HZ; | 622 | NCR5380_poll_politely(instance, |
871 | NCR5380_poll_politely(instance, STATUS_REG, SR_BSY, 0, 5*HZ); | 623 | STATUS_REG, SR_BSY, 0, 5 * HZ); |
872 | break; | 624 | break; |
873 | case 2: | 625 | case 2: |
874 | printk(KERN_WARNING "scsi%d: bus busy, attempting abort\n", instance->host_no); | 626 | shost_printk(KERN_ERR, instance, "bus busy, attempting abort\n"); |
875 | do_abort(instance); | 627 | do_abort(instance); |
876 | break; | 628 | break; |
877 | case 4: | 629 | case 4: |
878 | printk(KERN_WARNING "scsi%d: bus busy, attempting reset\n", instance->host_no); | 630 | shost_printk(KERN_ERR, instance, "bus busy, attempting reset\n"); |
879 | do_reset(instance); | 631 | do_reset(instance); |
632 | /* Wait after a reset; the SCSI standard calls for | ||
633 | * 250ms, we wait 500ms to be on the safe side. | ||
634 | * But some Toshiba CD-ROMs need ten times that. | ||
635 | */ | ||
636 | if (hostdata->flags & FLAG_TOSHIBA_DELAY) | ||
637 | msleep(2500); | ||
638 | else | ||
639 | msleep(500); | ||
880 | break; | 640 | break; |
881 | case 6: | 641 | case 6: |
882 | printk(KERN_ERR "scsi%d: bus locked solid or invalid override\n", instance->host_no); | 642 | shost_printk(KERN_ERR, instance, "bus locked solid\n"); |
883 | return -ENXIO; | 643 | return -ENXIO; |
884 | } | 644 | } |
885 | } | 645 | } |
@@ -887,450 +647,513 @@ static int NCR5380_init(struct Scsi_Host *instance, int flags) | |||
887 | } | 647 | } |
888 | 648 | ||
889 | /** | 649 | /** |
890 | * NCR5380_exit - remove an NCR5380 | 650 | * NCR5380_exit - remove an NCR5380 |
891 | * @instance: adapter to remove | 651 | * @instance: adapter to remove |
652 | * | ||
653 | * Assumes that no more work can be queued (e.g. by NCR5380_intr). | ||
892 | */ | 654 | */ |
893 | 655 | ||
894 | static void NCR5380_exit(struct Scsi_Host *instance) | 656 | static void NCR5380_exit(struct Scsi_Host *instance) |
895 | { | 657 | { |
896 | struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata; | 658 | struct NCR5380_hostdata *hostdata = shost_priv(instance); |
897 | 659 | ||
898 | cancel_delayed_work_sync(&hostdata->coroutine); | 660 | cancel_work_sync(&hostdata->main_task); |
661 | destroy_workqueue(hostdata->work_q); | ||
899 | } | 662 | } |
900 | 663 | ||
901 | /** | 664 | /** |
902 | * NCR5380_queue_command - queue a command | 665 | * complete_cmd - finish processing a command and return it to the SCSI ML |
903 | * @cmd: SCSI command | 666 | * @instance: the host instance |
904 | * @done: completion handler | 667 | * @cmd: command to complete |
905 | * | 668 | */ |
906 | * cmd is added to the per instance issue_queue, with minor | 669 | |
907 | * twiddling done to the host specific fields of cmd. If the | 670 | static void complete_cmd(struct Scsi_Host *instance, |
908 | * main coroutine is not running, it is restarted. | 671 | struct scsi_cmnd *cmd) |
672 | { | ||
673 | struct NCR5380_hostdata *hostdata = shost_priv(instance); | ||
674 | |||
675 | dsprintk(NDEBUG_QUEUES, instance, "complete_cmd: cmd %p\n", cmd); | ||
676 | |||
677 | if (hostdata->sensing == cmd) { | ||
678 | /* Autosense processing ends here */ | ||
679 | if ((cmd->result & 0xff) != SAM_STAT_GOOD) { | ||
680 | scsi_eh_restore_cmnd(cmd, &hostdata->ses); | ||
681 | set_host_byte(cmd, DID_ERROR); | ||
682 | } else | ||
683 | scsi_eh_restore_cmnd(cmd, &hostdata->ses); | ||
684 | hostdata->sensing = NULL; | ||
685 | } | ||
686 | |||
687 | hostdata->busy[scmd_id(cmd)] &= ~(1 << cmd->device->lun); | ||
688 | |||
689 | cmd->scsi_done(cmd); | ||
690 | } | ||
691 | |||
692 | /** | ||
693 | * NCR5380_queue_command - queue a command | ||
694 | * @instance: the relevant SCSI adapter | ||
695 | * @cmd: SCSI command | ||
909 | * | 696 | * |
910 | * Locks: host lock taken by caller | 697 | * cmd is added to the per-instance issue queue, with minor |
698 | * twiddling done to the host specific fields of cmd. If the | ||
699 | * main coroutine is not running, it is restarted. | ||
911 | */ | 700 | */ |
912 | 701 | ||
913 | static int NCR5380_queue_command_lck(struct scsi_cmnd *cmd, void (*done) (struct scsi_cmnd *)) | 702 | static int NCR5380_queue_command(struct Scsi_Host *instance, |
703 | struct scsi_cmnd *cmd) | ||
914 | { | 704 | { |
915 | struct Scsi_Host *instance = cmd->device->host; | 705 | struct NCR5380_hostdata *hostdata = shost_priv(instance); |
916 | struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata; | 706 | struct NCR5380_cmd *ncmd = scsi_cmd_priv(cmd); |
917 | struct scsi_cmnd *tmp; | 707 | unsigned long flags; |
918 | 708 | ||
919 | #if (NDEBUG & NDEBUG_NO_WRITE) | 709 | #if (NDEBUG & NDEBUG_NO_WRITE) |
920 | switch (cmd->cmnd[0]) { | 710 | switch (cmd->cmnd[0]) { |
921 | case WRITE_6: | 711 | case WRITE_6: |
922 | case WRITE_10: | 712 | case WRITE_10: |
923 | printk("scsi%d : WRITE attempted with NO_WRITE debugging flag set\n", instance->host_no); | 713 | shost_printk(KERN_DEBUG, instance, "WRITE attempted with NDEBUG_NO_WRITE set\n"); |
924 | cmd->result = (DID_ERROR << 16); | 714 | cmd->result = (DID_ERROR << 16); |
925 | done(cmd); | 715 | cmd->scsi_done(cmd); |
926 | return 0; | 716 | return 0; |
927 | } | 717 | } |
928 | #endif /* (NDEBUG & NDEBUG_NO_WRITE) */ | 718 | #endif /* (NDEBUG & NDEBUG_NO_WRITE) */ |
929 | |||
930 | /* | ||
931 | * We use the host_scribble field as a pointer to the next command | ||
932 | * in a queue | ||
933 | */ | ||
934 | 719 | ||
935 | cmd->host_scribble = NULL; | ||
936 | cmd->scsi_done = done; | ||
937 | cmd->result = 0; | 720 | cmd->result = 0; |
938 | 721 | ||
939 | /* | 722 | spin_lock_irqsave(&hostdata->lock, flags); |
940 | * Insert the cmd into the issue queue. Note that REQUEST SENSE | 723 | |
724 | /* | ||
725 | * Insert the cmd into the issue queue. Note that REQUEST SENSE | ||
941 | * commands are added to the head of the queue since any command will | 726 | * commands are added to the head of the queue since any command will |
942 | * clear the contingent allegiance condition that exists and the | 727 | * clear the contingent allegiance condition that exists and the |
943 | * sense data is only guaranteed to be valid while the condition exists. | 728 | * sense data is only guaranteed to be valid while the condition exists. |
944 | */ | 729 | */ |
945 | 730 | ||
946 | if (!(hostdata->issue_queue) || (cmd->cmnd[0] == REQUEST_SENSE)) { | 731 | if (cmd->cmnd[0] == REQUEST_SENSE) |
947 | LIST(cmd, hostdata->issue_queue); | 732 | list_add(&ncmd->list, &hostdata->unissued); |
948 | cmd->host_scribble = (unsigned char *) hostdata->issue_queue; | 733 | else |
949 | hostdata->issue_queue = cmd; | 734 | list_add_tail(&ncmd->list, &hostdata->unissued); |
950 | } else { | 735 | |
951 | for (tmp = (struct scsi_cmnd *) hostdata->issue_queue; tmp->host_scribble; tmp = (struct scsi_cmnd *) tmp->host_scribble); | 736 | spin_unlock_irqrestore(&hostdata->lock, flags); |
952 | LIST(cmd, tmp); | 737 | |
953 | tmp->host_scribble = (unsigned char *) cmd; | 738 | dsprintk(NDEBUG_QUEUES, instance, "command %p added to %s of queue\n", |
954 | } | 739 | cmd, (cmd->cmnd[0] == REQUEST_SENSE) ? "head" : "tail"); |
955 | dprintk(NDEBUG_QUEUES, "scsi%d : command added to %s of queue\n", instance->host_no, (cmd->cmnd[0] == REQUEST_SENSE) ? "head" : "tail"); | ||
956 | 740 | ||
957 | /* Run the coroutine if it isn't already running. */ | ||
958 | /* Kick off command processing */ | 741 | /* Kick off command processing */ |
959 | schedule_delayed_work(&hostdata->coroutine, 0); | 742 | queue_work(hostdata->work_q, &hostdata->main_task); |
960 | return 0; | 743 | return 0; |
961 | } | 744 | } |
962 | 745 | ||
963 | static DEF_SCSI_QCMD(NCR5380_queue_command) | 746 | /** |
747 | * dequeue_next_cmd - dequeue a command for processing | ||
748 | * @instance: the scsi host instance | ||
749 | * | ||
750 | * Priority is given to commands on the autosense queue. These commands | ||
751 | * need autosense because of a CHECK CONDITION result. | ||
752 | * | ||
753 | * Returns a command pointer if a command is found for a target that is | ||
754 | * not already busy. Otherwise returns NULL. | ||
755 | */ | ||
756 | |||
757 | static struct scsi_cmnd *dequeue_next_cmd(struct Scsi_Host *instance) | ||
758 | { | ||
759 | struct NCR5380_hostdata *hostdata = shost_priv(instance); | ||
760 | struct NCR5380_cmd *ncmd; | ||
761 | struct scsi_cmnd *cmd; | ||
762 | |||
763 | if (list_empty(&hostdata->autosense)) { | ||
764 | list_for_each_entry(ncmd, &hostdata->unissued, list) { | ||
765 | cmd = NCR5380_to_scmd(ncmd); | ||
766 | dsprintk(NDEBUG_QUEUES, instance, "dequeue: cmd=%p target=%d busy=0x%02x lun=%llu\n", | ||
767 | cmd, scmd_id(cmd), hostdata->busy[scmd_id(cmd)], cmd->device->lun); | ||
768 | |||
769 | if (!(hostdata->busy[scmd_id(cmd)] & (1 << cmd->device->lun))) { | ||
770 | list_del(&ncmd->list); | ||
771 | dsprintk(NDEBUG_QUEUES, instance, | ||
772 | "dequeue: removed %p from issue queue\n", cmd); | ||
773 | return cmd; | ||
774 | } | ||
775 | } | ||
776 | } else { | ||
777 | /* Autosense processing begins here */ | ||
778 | ncmd = list_first_entry(&hostdata->autosense, | ||
779 | struct NCR5380_cmd, list); | ||
780 | list_del(&ncmd->list); | ||
781 | cmd = NCR5380_to_scmd(ncmd); | ||
782 | dsprintk(NDEBUG_QUEUES, instance, | ||
783 | "dequeue: removed %p from autosense queue\n", cmd); | ||
784 | scsi_eh_prep_cmnd(cmd, &hostdata->ses, NULL, 0, ~0); | ||
785 | hostdata->sensing = cmd; | ||
786 | return cmd; | ||
787 | } | ||
788 | return NULL; | ||
789 | } | ||
790 | |||
791 | static void requeue_cmd(struct Scsi_Host *instance, struct scsi_cmnd *cmd) | ||
792 | { | ||
793 | struct NCR5380_hostdata *hostdata = shost_priv(instance); | ||
794 | struct NCR5380_cmd *ncmd = scsi_cmd_priv(cmd); | ||
795 | |||
796 | if (hostdata->sensing) { | ||
797 | scsi_eh_restore_cmnd(cmd, &hostdata->ses); | ||
798 | list_add(&ncmd->list, &hostdata->autosense); | ||
799 | hostdata->sensing = NULL; | ||
800 | } else | ||
801 | list_add(&ncmd->list, &hostdata->unissued); | ||
802 | } | ||
964 | 803 | ||
965 | /** | 804 | /** |
966 | * NCR5380_main - NCR state machines | 805 | * NCR5380_main - NCR state machines |
967 | * | 806 | * |
968 | * NCR5380_main is a coroutine that runs as long as more work can | 807 | * NCR5380_main is a coroutine that runs as long as more work can |
969 | * be done on the NCR5380 host adapters in a system. Both | 808 | * be done on the NCR5380 host adapters in a system. Both |
970 | * NCR5380_queue_command() and NCR5380_intr() will try to start it | 809 | * NCR5380_queue_command() and NCR5380_intr() will try to start it |
971 | * in case it is not running. | 810 | * in case it is not running. |
972 | * | ||
973 | * Locks: called as its own thread with no locks held. Takes the | ||
974 | * host lock and called routines may take the isa dma lock. | ||
975 | */ | 811 | */ |
976 | 812 | ||
977 | static void NCR5380_main(struct work_struct *work) | 813 | static void NCR5380_main(struct work_struct *work) |
978 | { | 814 | { |
979 | struct NCR5380_hostdata *hostdata = | 815 | struct NCR5380_hostdata *hostdata = |
980 | container_of(work, struct NCR5380_hostdata, coroutine.work); | 816 | container_of(work, struct NCR5380_hostdata, main_task); |
981 | struct Scsi_Host *instance = hostdata->host; | 817 | struct Scsi_Host *instance = hostdata->host; |
982 | struct scsi_cmnd *tmp, *prev; | 818 | struct scsi_cmnd *cmd; |
983 | int done; | 819 | int done; |
984 | 820 | ||
985 | spin_lock_irq(instance->host_lock); | ||
986 | do { | 821 | do { |
987 | /* Lock held here */ | ||
988 | done = 1; | 822 | done = 1; |
989 | if (!hostdata->connected && !hostdata->selecting) { | ||
990 | dprintk(NDEBUG_MAIN, "scsi%d : not connected\n", instance->host_no); | ||
991 | /* | ||
992 | * Search through the issue_queue for a command destined | ||
993 | * for a target that's not busy. | ||
994 | */ | ||
995 | for (tmp = (struct scsi_cmnd *) hostdata->issue_queue, prev = NULL; tmp; prev = tmp, tmp = (struct scsi_cmnd *) tmp->host_scribble) | ||
996 | { | ||
997 | if (prev != tmp) | ||
998 | dprintk(NDEBUG_LISTS, "MAIN tmp=%p target=%d busy=%d lun=%llu\n", tmp, tmp->device->id, hostdata->busy[tmp->device->id], tmp->device->lun); | ||
999 | /* When we find one, remove it from the issue queue. */ | ||
1000 | if (!(hostdata->busy[tmp->device->id] & | ||
1001 | (1 << (u8)(tmp->device->lun & 0xff)))) { | ||
1002 | if (prev) { | ||
1003 | REMOVE(prev, prev->host_scribble, tmp, tmp->host_scribble); | ||
1004 | prev->host_scribble = tmp->host_scribble; | ||
1005 | } else { | ||
1006 | REMOVE(-1, hostdata->issue_queue, tmp, tmp->host_scribble); | ||
1007 | hostdata->issue_queue = (struct scsi_cmnd *) tmp->host_scribble; | ||
1008 | } | ||
1009 | tmp->host_scribble = NULL; | ||
1010 | 823 | ||
1011 | /* | 824 | spin_lock_irq(&hostdata->lock); |
1012 | * Attempt to establish an I_T_L nexus here. | 825 | while (!hostdata->connected && |
1013 | * On success, instance->hostdata->connected is set. | 826 | (cmd = dequeue_next_cmd(instance))) { |
1014 | * On failure, we must add the command back to the | ||
1015 | * issue queue so we can keep trying. | ||
1016 | */ | ||
1017 | dprintk(NDEBUG_MAIN|NDEBUG_QUEUES, "scsi%d : main() : command for target %d lun %llu removed from issue_queue\n", instance->host_no, tmp->device->id, tmp->device->lun); | ||
1018 | |||
1019 | /* | ||
1020 | * A successful selection is defined as one that | ||
1021 | * leaves us with the command connected and | ||
1022 | * in hostdata->connected, OR has terminated the | ||
1023 | * command. | ||
1024 | * | ||
1025 | * With successful commands, we fall through | ||
1026 | * and see if we can do an information transfer, | ||
1027 | * with failures we will restart. | ||
1028 | */ | ||
1029 | hostdata->selecting = NULL; | ||
1030 | /* RvC: have to preset this to indicate a new command is being performed */ | ||
1031 | 827 | ||
1032 | /* | 828 | dsprintk(NDEBUG_MAIN, instance, "main: dequeued %p\n", cmd); |
1033 | * REQUEST SENSE commands are issued without tagged | ||
1034 | * queueing, even on SCSI-II devices because the | ||
1035 | * contingent allegiance condition exists for the | ||
1036 | * entire unit. | ||
1037 | */ | ||
1038 | 829 | ||
1039 | if (!NCR5380_select(instance, tmp)) { | 830 | /* |
1040 | break; | 831 | * Attempt to establish an I_T_L nexus here. |
1041 | } else { | 832 | * On success, instance->hostdata->connected is set. |
1042 | LIST(tmp, hostdata->issue_queue); | 833 | * On failure, we must add the command back to the |
1043 | tmp->host_scribble = (unsigned char *) hostdata->issue_queue; | 834 | * issue queue so we can keep trying. |
1044 | hostdata->issue_queue = tmp; | 835 | */ |
1045 | done = 0; | 836 | /* |
1046 | dprintk(NDEBUG_MAIN|NDEBUG_QUEUES, "scsi%d : main(): select() failed, returned to issue_queue\n", instance->host_no); | 837 | * REQUEST SENSE commands are issued without tagged |
1047 | } | 838 | * queueing, even on SCSI-II devices because the |
1048 | /* lock held here still */ | 839 | * contingent allegiance condition exists for the |
1049 | } /* if target/lun is not busy */ | 840 | * entire unit. |
1050 | } /* for */ | 841 | */ |
1051 | /* exited locked */ | 842 | |
1052 | } /* if (!hostdata->connected) */ | 843 | cmd = NCR5380_select(instance, cmd); |
1053 | if (hostdata->selecting) { | 844 | if (!cmd) { |
1054 | tmp = (struct scsi_cmnd *) hostdata->selecting; | 845 | dsprintk(NDEBUG_MAIN, instance, "main: select complete\n"); |
1055 | /* Selection will drop and retake the lock */ | ||
1056 | if (!NCR5380_select(instance, tmp)) { | ||
1057 | /* Ok ?? */ | ||
1058 | } else { | 846 | } else { |
1059 | /* RvC: device failed, so we wait a long time | 847 | dsprintk(NDEBUG_MAIN | NDEBUG_QUEUES, instance, |
1060 | this is needed for Mustek scanners, that | 848 | "main: select failed, returning %p to queue\n", cmd); |
1061 | do not respond to commands immediately | 849 | requeue_cmd(instance, cmd); |
1062 | after a scan */ | ||
1063 | printk(KERN_DEBUG "scsi%d: device %d did not respond in time\n", instance->host_no, tmp->device->id); | ||
1064 | LIST(tmp, hostdata->issue_queue); | ||
1065 | tmp->host_scribble = (unsigned char *) hostdata->issue_queue; | ||
1066 | hostdata->issue_queue = tmp; | ||
1067 | NCR5380_set_timer(hostdata, USLEEP_WAITLONG); | ||
1068 | } | 850 | } |
1069 | } /* if hostdata->selecting */ | 851 | } |
1070 | if (hostdata->connected | 852 | if (hostdata->connected |
1071 | #ifdef REAL_DMA | 853 | #ifdef REAL_DMA |
1072 | && !hostdata->dmalen | 854 | && !hostdata->dmalen |
1073 | #endif | 855 | #endif |
1074 | && (!hostdata->time_expires || time_before_eq(hostdata->time_expires, jiffies)) | ||
1075 | ) { | 856 | ) { |
1076 | dprintk(NDEBUG_MAIN, "scsi%d : main() : performing information transfer\n", instance->host_no); | 857 | dsprintk(NDEBUG_MAIN, instance, "main: performing information transfer\n"); |
1077 | NCR5380_information_transfer(instance); | 858 | NCR5380_information_transfer(instance); |
1078 | dprintk(NDEBUG_MAIN, "scsi%d : main() : done set false\n", instance->host_no); | ||
1079 | done = 0; | 859 | done = 0; |
1080 | } else | 860 | } |
1081 | break; | 861 | spin_unlock_irq(&hostdata->lock); |
862 | if (!done) | ||
863 | cond_resched(); | ||
1082 | } while (!done); | 864 | } while (!done); |
1083 | |||
1084 | spin_unlock_irq(instance->host_lock); | ||
1085 | } | 865 | } |
1086 | 866 | ||
1087 | #ifndef DONT_USE_INTR | 867 | #ifndef DONT_USE_INTR |
1088 | 868 | ||
1089 | /** | 869 | /** |
1090 | * NCR5380_intr - generic NCR5380 irq handler | 870 | * NCR5380_intr - generic NCR5380 irq handler |
1091 | * @irq: interrupt number | 871 | * @irq: interrupt number |
1092 | * @dev_id: device info | 872 | * @dev_id: device info |
1093 | * | 873 | * |
1094 | * Handle interrupts, reestablishing I_T_L or I_T_L_Q nexuses | 874 | * Handle interrupts, reestablishing I_T_L or I_T_L_Q nexuses |
1095 | * from the disconnected queue, and restarting NCR5380_main() | 875 | * from the disconnected queue, and restarting NCR5380_main() |
1096 | * as required. | 876 | * as required. |
1097 | * | 877 | * |
1098 | * Locks: takes the needed instance locks | 878 | * The chip can assert IRQ in any of six different conditions. The IRQ flag |
879 | * is then cleared by reading the Reset Parity/Interrupt Register (RPIR). | ||
880 | * Three of these six conditions are latched in the Bus and Status Register: | ||
881 | * - End of DMA (cleared by ending DMA Mode) | ||
882 | * - Parity error (cleared by reading RPIR) | ||
883 | * - Loss of BSY (cleared by reading RPIR) | ||
884 | * Two conditions have flag bits that are not latched: | ||
885 | * - Bus phase mismatch (non-maskable in DMA Mode, cleared by ending DMA Mode) | ||
886 | * - Bus reset (non-maskable) | ||
887 | * The remaining condition has no flag bit at all: | ||
888 | * - Selection/reselection | ||
889 | * | ||
890 | * Hence, establishing the cause(s) of any interrupt is partly guesswork. | ||
891 | * In "The DP8490 and DP5380 Comparison Guide", National Semiconductor | ||
892 | * claimed that "the design of the [DP8490] interrupt logic ensures | ||
893 | * interrupts will not be lost (they can be on the DP5380)." | ||
894 | * The L5380/53C80 datasheet from LOGIC Devices has more details. | ||
895 | * | ||
896 | * Checking for bus reset by reading RST is futile because of interrupt | ||
897 | * latency, but a bus reset will reset chip logic. Checking for parity error | ||
898 | * is unnecessary because that interrupt is never enabled. A Loss of BSY | ||
899 | * condition will clear DMA Mode. We can tell when this occurs because the | ||
900 | * the Busy Monitor interrupt is enabled together with DMA Mode. | ||
1099 | */ | 901 | */ |
1100 | 902 | ||
1101 | static irqreturn_t NCR5380_intr(int dummy, void *dev_id) | 903 | static irqreturn_t NCR5380_intr(int irq, void *dev_id) |
1102 | { | 904 | { |
1103 | NCR5380_local_declare(); | ||
1104 | struct Scsi_Host *instance = dev_id; | 905 | struct Scsi_Host *instance = dev_id; |
1105 | struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata; | 906 | struct NCR5380_hostdata *hostdata = shost_priv(instance); |
1106 | int done; | 907 | int handled = 0; |
1107 | unsigned char basr; | 908 | unsigned char basr; |
1108 | unsigned long flags; | 909 | unsigned long flags; |
1109 | 910 | ||
1110 | dprintk(NDEBUG_INTR, "scsi : NCR5380 irq %d triggered\n", | 911 | spin_lock_irqsave(&hostdata->lock, flags); |
1111 | instance->irq); | 912 | |
913 | basr = NCR5380_read(BUS_AND_STATUS_REG); | ||
914 | if (basr & BASR_IRQ) { | ||
915 | unsigned char mr = NCR5380_read(MODE_REG); | ||
916 | unsigned char sr = NCR5380_read(STATUS_REG); | ||
917 | |||
918 | dsprintk(NDEBUG_INTR, instance, "IRQ %d, BASR 0x%02x, SR 0x%02x, MR 0x%02x\n", | ||
919 | irq, basr, sr, mr); | ||
1112 | 920 | ||
1113 | do { | ||
1114 | done = 1; | ||
1115 | spin_lock_irqsave(instance->host_lock, flags); | ||
1116 | /* Look for pending interrupts */ | ||
1117 | NCR5380_setup(instance); | ||
1118 | basr = NCR5380_read(BUS_AND_STATUS_REG); | ||
1119 | /* XXX dispatch to appropriate routine if found and done=0 */ | ||
1120 | if (basr & BASR_IRQ) { | ||
1121 | NCR5380_dprint(NDEBUG_INTR, instance); | ||
1122 | if ((NCR5380_read(STATUS_REG) & (SR_SEL | SR_IO)) == (SR_SEL | SR_IO)) { | ||
1123 | done = 0; | ||
1124 | dprintk(NDEBUG_INTR, "scsi%d : SEL interrupt\n", instance->host_no); | ||
1125 | NCR5380_reselect(instance); | ||
1126 | (void) NCR5380_read(RESET_PARITY_INTERRUPT_REG); | ||
1127 | } else if (basr & BASR_PARITY_ERROR) { | ||
1128 | dprintk(NDEBUG_INTR, "scsi%d : PARITY interrupt\n", instance->host_no); | ||
1129 | (void) NCR5380_read(RESET_PARITY_INTERRUPT_REG); | ||
1130 | } else if ((NCR5380_read(STATUS_REG) & SR_RST) == SR_RST) { | ||
1131 | dprintk(NDEBUG_INTR, "scsi%d : RESET interrupt\n", instance->host_no); | ||
1132 | (void) NCR5380_read(RESET_PARITY_INTERRUPT_REG); | ||
1133 | } else { | ||
1134 | #if defined(REAL_DMA) | 921 | #if defined(REAL_DMA) |
1135 | /* | 922 | if ((mr & MR_DMA_MODE) || (mr & MR_MONITOR_BSY)) { |
1136 | * We should only get PHASE MISMATCH and EOP interrupts | 923 | /* Probably End of DMA, Phase Mismatch or Loss of BSY. |
1137 | * if we have DMA enabled, so do a sanity check based on | 924 | * We ack IRQ after clearing Mode Register. Workarounds |
1138 | * the current setting of the MODE register. | 925 | * for End of DMA errata need to happen in DMA Mode. |
1139 | */ | 926 | */ |
1140 | 927 | ||
1141 | if ((NCR5380_read(MODE_REG) & MR_DMA) && ((basr & BASR_END_DMA_TRANSFER) || !(basr & BASR_PHASE_MATCH))) { | 928 | dsprintk(NDEBUG_INTR, instance, "interrupt in DMA mode\n"); |
1142 | int transferred; | ||
1143 | 929 | ||
1144 | if (!hostdata->connected) | 930 | int transferred; |
1145 | panic("scsi%d : received end of DMA interrupt with no connected cmd\n", instance->hostno); | ||
1146 | 931 | ||
1147 | transferred = (hostdata->dmalen - NCR5380_dma_residual(instance)); | 932 | if (!hostdata->connected) |
1148 | hostdata->connected->SCp.this_residual -= transferred; | 933 | panic("scsi%d : DMA interrupt with no connected cmd\n", |
1149 | hostdata->connected->SCp.ptr += transferred; | 934 | instance->hostno); |
1150 | hostdata->dmalen = 0; | ||
1151 | 935 | ||
1152 | (void) NCR5380_read(RESET_PARITY_INTERRUPT_REG); | 936 | transferred = hostdata->dmalen - NCR5380_dma_residual(instance); |
1153 | 937 | hostdata->connected->SCp.this_residual -= transferred; | |
1154 | /* FIXME: we need to poll briefly then defer a workqueue task ! */ | 938 | hostdata->connected->SCp.ptr += transferred; |
1155 | NCR5380_poll_politely(hostdata, BUS_AND_STATUS_REG, BASR_ACK, 0, 2*HZ); | 939 | hostdata->dmalen = 0; |
1156 | 940 | ||
1157 | NCR5380_write(MODE_REG, MR_BASE); | 941 | /* FIXME: we need to poll briefly then defer a workqueue task ! */ |
1158 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); | 942 | NCR5380_poll_politely(hostdata, BUS_AND_STATUS_REG, BASR_ACK, 0, 2 * HZ); |
1159 | } | 943 | |
1160 | #else | 944 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); |
1161 | dprintk(NDEBUG_INTR, "scsi : unknown interrupt, BASR 0x%X, MR 0x%X, SR 0x%x\n", basr, NCR5380_read(MODE_REG), NCR5380_read(STATUS_REG)); | 945 | NCR5380_write(MODE_REG, MR_BASE); |
1162 | (void) NCR5380_read(RESET_PARITY_INTERRUPT_REG); | 946 | NCR5380_read(RESET_PARITY_INTERRUPT_REG); |
1163 | #endif | 947 | } else |
948 | #endif /* REAL_DMA */ | ||
949 | if ((NCR5380_read(CURRENT_SCSI_DATA_REG) & hostdata->id_mask) && | ||
950 | (sr & (SR_SEL | SR_IO | SR_BSY | SR_RST)) == (SR_SEL | SR_IO)) { | ||
951 | /* Probably reselected */ | ||
952 | NCR5380_write(SELECT_ENABLE_REG, 0); | ||
953 | NCR5380_read(RESET_PARITY_INTERRUPT_REG); | ||
954 | |||
955 | dsprintk(NDEBUG_INTR, instance, "interrupt with SEL and IO\n"); | ||
956 | |||
957 | if (!hostdata->connected) { | ||
958 | NCR5380_reselect(instance); | ||
959 | queue_work(hostdata->work_q, &hostdata->main_task); | ||
1164 | } | 960 | } |
1165 | } /* if BASR_IRQ */ | 961 | if (!hostdata->connected) |
1166 | spin_unlock_irqrestore(instance->host_lock, flags); | 962 | NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask); |
1167 | if(!done) | 963 | } else { |
1168 | schedule_delayed_work(&hostdata->coroutine, 0); | 964 | /* Probably Bus Reset */ |
1169 | } while (!done); | 965 | NCR5380_read(RESET_PARITY_INTERRUPT_REG); |
1170 | return IRQ_HANDLED; | 966 | |
967 | dsprintk(NDEBUG_INTR, instance, "unknown interrupt\n"); | ||
968 | } | ||
969 | handled = 1; | ||
970 | } else { | ||
971 | shost_printk(KERN_NOTICE, instance, "interrupt without IRQ bit\n"); | ||
972 | } | ||
973 | |||
974 | spin_unlock_irqrestore(&hostdata->lock, flags); | ||
975 | |||
976 | return IRQ_RETVAL(handled); | ||
1171 | } | 977 | } |
1172 | 978 | ||
1173 | #endif | 979 | #endif |
1174 | 980 | ||
1175 | /* | 981 | /* |
1176 | * Function : int NCR5380_select(struct Scsi_Host *instance, | 982 | * Function : int NCR5380_select(struct Scsi_Host *instance, |
1177 | * struct scsi_cmnd *cmd) | 983 | * struct scsi_cmnd *cmd) |
1178 | * | 984 | * |
1179 | * Purpose : establishes I_T_L or I_T_L_Q nexus for new or existing command, | 985 | * Purpose : establishes I_T_L or I_T_L_Q nexus for new or existing command, |
1180 | * including ARBITRATION, SELECTION, and initial message out for | 986 | * including ARBITRATION, SELECTION, and initial message out for |
1181 | * IDENTIFY and queue messages. | 987 | * IDENTIFY and queue messages. |
1182 | * | 988 | * |
1183 | * Inputs : instance - instantiation of the 5380 driver on which this | 989 | * Inputs : instance - instantiation of the 5380 driver on which this |
1184 | * target lives, cmd - SCSI command to execute. | 990 | * target lives, cmd - SCSI command to execute. |
1185 | * | 991 | * |
1186 | * Returns : -1 if selection could not execute for some reason, | 992 | * Returns cmd if selection failed but should be retried, |
1187 | * 0 if selection succeeded or failed because the target | 993 | * NULL if selection failed and should not be retried, or |
1188 | * did not respond. | 994 | * NULL if selection succeeded (hostdata->connected == cmd). |
1189 | * | 995 | * |
1190 | * Side effects : | 996 | * Side effects : |
1191 | * If bus busy, arbitration failed, etc, NCR5380_select() will exit | 997 | * If bus busy, arbitration failed, etc, NCR5380_select() will exit |
1192 | * with registers as they should have been on entry - ie | 998 | * with registers as they should have been on entry - ie |
1193 | * SELECT_ENABLE will be set appropriately, the NCR5380 | 999 | * SELECT_ENABLE will be set appropriately, the NCR5380 |
1194 | * will cease to drive any SCSI bus signals. | 1000 | * will cease to drive any SCSI bus signals. |
1195 | * | 1001 | * |
1196 | * If successful : I_T_L or I_T_L_Q nexus will be established, | 1002 | * If successful : I_T_L or I_T_L_Q nexus will be established, |
1197 | * instance->connected will be set to cmd. | 1003 | * instance->connected will be set to cmd. |
1198 | * SELECT interrupt will be disabled. | 1004 | * SELECT interrupt will be disabled. |
1199 | * | 1005 | * |
1200 | * If failed (no target) : cmd->scsi_done() will be called, and the | 1006 | * If failed (no target) : cmd->scsi_done() will be called, and the |
1201 | * cmd->result host byte set to DID_BAD_TARGET. | 1007 | * cmd->result host byte set to DID_BAD_TARGET. |
1202 | * | ||
1203 | * Locks: caller holds hostdata lock in IRQ mode | ||
1204 | */ | 1008 | */ |
1205 | 1009 | ||
1206 | static int NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd) | 1010 | static struct scsi_cmnd *NCR5380_select(struct Scsi_Host *instance, |
1011 | struct scsi_cmnd *cmd) | ||
1207 | { | 1012 | { |
1208 | NCR5380_local_declare(); | 1013 | struct NCR5380_hostdata *hostdata = shost_priv(instance); |
1209 | struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata; | ||
1210 | unsigned char tmp[3], phase; | 1014 | unsigned char tmp[3], phase; |
1211 | unsigned char *data; | 1015 | unsigned char *data; |
1212 | int len; | 1016 | int len; |
1213 | unsigned long timeout; | ||
1214 | unsigned char value; | ||
1215 | int err; | 1017 | int err; |
1216 | NCR5380_setup(instance); | ||
1217 | |||
1218 | if (hostdata->selecting) | ||
1219 | goto part2; | ||
1220 | |||
1221 | hostdata->restart_select = 0; | ||
1222 | 1018 | ||
1223 | NCR5380_dprint(NDEBUG_ARBITRATION, instance); | 1019 | NCR5380_dprint(NDEBUG_ARBITRATION, instance); |
1224 | dprintk(NDEBUG_ARBITRATION, "scsi%d : starting arbitration, id = %d\n", instance->host_no, instance->this_id); | 1020 | dsprintk(NDEBUG_ARBITRATION, instance, "starting arbitration, id = %d\n", |
1021 | instance->this_id); | ||
1022 | |||
1023 | /* | ||
1024 | * Arbitration and selection phases are slow and involve dropping the | ||
1025 | * lock, so we have to watch out for EH. An exception handler may | ||
1026 | * change 'selecting' to NULL. This function will then return NULL | ||
1027 | * so that the caller will forget about 'cmd'. (During information | ||
1028 | * transfer phases, EH may change 'connected' to NULL.) | ||
1029 | */ | ||
1030 | hostdata->selecting = cmd; | ||
1225 | 1031 | ||
1226 | /* | 1032 | /* |
1227 | * Set the phase bits to 0, otherwise the NCR5380 won't drive the | 1033 | * Set the phase bits to 0, otherwise the NCR5380 won't drive the |
1228 | * data bus during SELECTION. | 1034 | * data bus during SELECTION. |
1229 | */ | 1035 | */ |
1230 | 1036 | ||
1231 | NCR5380_write(TARGET_COMMAND_REG, 0); | 1037 | NCR5380_write(TARGET_COMMAND_REG, 0); |
1232 | 1038 | ||
1233 | /* | 1039 | /* |
1234 | * Start arbitration. | 1040 | * Start arbitration. |
1235 | */ | 1041 | */ |
1236 | 1042 | ||
1237 | NCR5380_write(OUTPUT_DATA_REG, hostdata->id_mask); | 1043 | NCR5380_write(OUTPUT_DATA_REG, hostdata->id_mask); |
1238 | NCR5380_write(MODE_REG, MR_ARBITRATE); | 1044 | NCR5380_write(MODE_REG, MR_ARBITRATE); |
1239 | 1045 | ||
1046 | /* The chip now waits for BUS FREE phase. Then after the 800 ns | ||
1047 | * Bus Free Delay, arbitration will begin. | ||
1048 | */ | ||
1240 | 1049 | ||
1241 | /* We can be relaxed here, interrupts are on, we are | 1050 | spin_unlock_irq(&hostdata->lock); |
1242 | in workqueue context, the birds are singing in the trees */ | 1051 | err = NCR5380_poll_politely2(instance, MODE_REG, MR_ARBITRATE, 0, |
1243 | spin_unlock_irq(instance->host_lock); | 1052 | INITIATOR_COMMAND_REG, ICR_ARBITRATION_PROGRESS, |
1244 | err = NCR5380_poll_politely(instance, INITIATOR_COMMAND_REG, ICR_ARBITRATION_PROGRESS, ICR_ARBITRATION_PROGRESS, 5*HZ); | 1053 | ICR_ARBITRATION_PROGRESS, HZ); |
1245 | spin_lock_irq(instance->host_lock); | 1054 | spin_lock_irq(&hostdata->lock); |
1055 | if (!(NCR5380_read(MODE_REG) & MR_ARBITRATE)) { | ||
1056 | /* Reselection interrupt */ | ||
1057 | goto out; | ||
1058 | } | ||
1246 | if (err < 0) { | 1059 | if (err < 0) { |
1247 | printk(KERN_DEBUG "scsi: arbitration timeout at %d\n", __LINE__); | ||
1248 | NCR5380_write(MODE_REG, MR_BASE); | 1060 | NCR5380_write(MODE_REG, MR_BASE); |
1249 | NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask); | 1061 | shost_printk(KERN_ERR, instance, |
1250 | goto failed; | 1062 | "select: arbitration timeout\n"); |
1063 | goto out; | ||
1251 | } | 1064 | } |
1065 | spin_unlock_irq(&hostdata->lock); | ||
1252 | 1066 | ||
1253 | dprintk(NDEBUG_ARBITRATION, "scsi%d : arbitration complete\n", instance->host_no); | 1067 | /* The SCSI-2 arbitration delay is 2.4 us */ |
1254 | |||
1255 | /* | ||
1256 | * The arbitration delay is 2.2us, but this is a minimum and there is | ||
1257 | * no maximum so we can safely sleep for ceil(2.2) usecs to accommodate | ||
1258 | * the integral nature of udelay(). | ||
1259 | * | ||
1260 | */ | ||
1261 | |||
1262 | udelay(3); | 1068 | udelay(3); |
1263 | 1069 | ||
1264 | /* Check for lost arbitration */ | 1070 | /* Check for lost arbitration */ |
1265 | if ((NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST) || (NCR5380_read(CURRENT_SCSI_DATA_REG) & hostdata->id_higher_mask) || (NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST)) { | 1071 | if ((NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST) || |
1266 | NCR5380_write(MODE_REG, MR_BASE); | 1072 | (NCR5380_read(CURRENT_SCSI_DATA_REG) & hostdata->id_higher_mask) || |
1267 | dprintk(NDEBUG_ARBITRATION, "scsi%d : lost arbitration, deasserting MR_ARBITRATE\n", instance->host_no); | ||
1268 | goto failed; | ||
1269 | } | ||
1270 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_SEL); | ||
1271 | |||
1272 | if (!(hostdata->flags & FLAG_DTC3181E) && | ||
1273 | /* RvC: DTC3181E has some trouble with this | ||
1274 | * so we simply removed it. Seems to work with | ||
1275 | * only Mustek scanner attached | ||
1276 | */ | ||
1277 | (NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST)) { | 1073 | (NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST)) { |
1278 | NCR5380_write(MODE_REG, MR_BASE); | 1074 | NCR5380_write(MODE_REG, MR_BASE); |
1279 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); | 1075 | dsprintk(NDEBUG_ARBITRATION, instance, "lost arbitration, deasserting MR_ARBITRATE\n"); |
1280 | dprintk(NDEBUG_ARBITRATION, "scsi%d : lost arbitration, deasserting ICR_ASSERT_SEL\n", instance->host_no); | 1076 | spin_lock_irq(&hostdata->lock); |
1281 | goto failed; | 1077 | goto out; |
1282 | } | 1078 | } |
1283 | /* | 1079 | |
1284 | * Again, bus clear + bus settle time is 1.2us, however, this is | 1080 | /* After/during arbitration, BSY should be asserted. |
1081 | * IBM DPES-31080 Version S31Q works now | ||
1082 | * Tnx to Thomas_Roesch@m2.maus.de for finding this! (Roman) | ||
1083 | */ | ||
1084 | NCR5380_write(INITIATOR_COMMAND_REG, | ||
1085 | ICR_BASE | ICR_ASSERT_SEL | ICR_ASSERT_BSY); | ||
1086 | |||
1087 | /* | ||
1088 | * Again, bus clear + bus settle time is 1.2us, however, this is | ||
1285 | * a minimum so we'll udelay ceil(1.2) | 1089 | * a minimum so we'll udelay ceil(1.2) |
1286 | */ | 1090 | */ |
1287 | 1091 | ||
1288 | udelay(2); | 1092 | if (hostdata->flags & FLAG_TOSHIBA_DELAY) |
1093 | udelay(15); | ||
1094 | else | ||
1095 | udelay(2); | ||
1096 | |||
1097 | spin_lock_irq(&hostdata->lock); | ||
1098 | |||
1099 | /* NCR5380_reselect() clears MODE_REG after a reselection interrupt */ | ||
1100 | if (!(NCR5380_read(MODE_REG) & MR_ARBITRATE)) | ||
1101 | goto out; | ||
1102 | |||
1103 | if (!hostdata->selecting) { | ||
1104 | NCR5380_write(MODE_REG, MR_BASE); | ||
1105 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); | ||
1106 | goto out; | ||
1107 | } | ||
1289 | 1108 | ||
1290 | dprintk(NDEBUG_ARBITRATION, "scsi%d : won arbitration\n", instance->host_no); | 1109 | dsprintk(NDEBUG_ARBITRATION, instance, "won arbitration\n"); |
1291 | 1110 | ||
1292 | /* | 1111 | /* |
1293 | * Now that we have won arbitration, start Selection process, asserting | 1112 | * Now that we have won arbitration, start Selection process, asserting |
1294 | * the host and target ID's on the SCSI bus. | 1113 | * the host and target ID's on the SCSI bus. |
1295 | */ | 1114 | */ |
1296 | 1115 | ||
1297 | NCR5380_write(OUTPUT_DATA_REG, (hostdata->id_mask | (1 << scmd_id(cmd)))); | 1116 | NCR5380_write(OUTPUT_DATA_REG, hostdata->id_mask | (1 << scmd_id(cmd))); |
1298 | 1117 | ||
1299 | /* | 1118 | /* |
1300 | * Raise ATN while SEL is true before BSY goes false from arbitration, | 1119 | * Raise ATN while SEL is true before BSY goes false from arbitration, |
1301 | * since this is the only way to guarantee that we'll get a MESSAGE OUT | 1120 | * since this is the only way to guarantee that we'll get a MESSAGE OUT |
1302 | * phase immediately after selection. | 1121 | * phase immediately after selection. |
1303 | */ | 1122 | */ |
1304 | 1123 | ||
1305 | NCR5380_write(INITIATOR_COMMAND_REG, (ICR_BASE | ICR_ASSERT_BSY | ICR_ASSERT_DATA | ICR_ASSERT_ATN | ICR_ASSERT_SEL)); | 1124 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_BSY | |
1125 | ICR_ASSERT_DATA | ICR_ASSERT_ATN | ICR_ASSERT_SEL); | ||
1306 | NCR5380_write(MODE_REG, MR_BASE); | 1126 | NCR5380_write(MODE_REG, MR_BASE); |
1307 | 1127 | ||
1308 | /* | 1128 | /* |
1309 | * Reselect interrupts must be turned off prior to the dropping of BSY, | 1129 | * Reselect interrupts must be turned off prior to the dropping of BSY, |
1310 | * otherwise we will trigger an interrupt. | 1130 | * otherwise we will trigger an interrupt. |
1311 | */ | 1131 | */ |
1312 | NCR5380_write(SELECT_ENABLE_REG, 0); | 1132 | NCR5380_write(SELECT_ENABLE_REG, 0); |
1313 | 1133 | ||
1134 | spin_unlock_irq(&hostdata->lock); | ||
1135 | |||
1314 | /* | 1136 | /* |
1315 | * The initiator shall then wait at least two deskew delays and release | 1137 | * The initiator shall then wait at least two deskew delays and release |
1316 | * the BSY signal. | 1138 | * the BSY signal. |
1317 | */ | 1139 | */ |
1318 | udelay(1); /* wingel -- wait two bus deskew delay >2*45ns */ | 1140 | udelay(1); /* wingel -- wait two bus deskew delay >2*45ns */ |
1319 | 1141 | ||
1320 | /* Reset BSY */ | 1142 | /* Reset BSY */ |
1321 | NCR5380_write(INITIATOR_COMMAND_REG, (ICR_BASE | ICR_ASSERT_DATA | ICR_ASSERT_ATN | ICR_ASSERT_SEL)); | 1143 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_DATA | |
1144 | ICR_ASSERT_ATN | ICR_ASSERT_SEL); | ||
1322 | 1145 | ||
1323 | /* | 1146 | /* |
1324 | * Something weird happens when we cease to drive BSY - looks | 1147 | * Something weird happens when we cease to drive BSY - looks |
1325 | * like the board/chip is letting us do another read before the | 1148 | * like the board/chip is letting us do another read before the |
1326 | * appropriate propagation delay has expired, and we're confusing | 1149 | * appropriate propagation delay has expired, and we're confusing |
1327 | * a BSY signal from ourselves as the target's response to SELECTION. | 1150 | * a BSY signal from ourselves as the target's response to SELECTION. |
1328 | * | 1151 | * |
1329 | * A small delay (the 'C++' frontend breaks the pipeline with an | 1152 | * A small delay (the 'C++' frontend breaks the pipeline with an |
1330 | * unnecessary jump, making it work on my 386-33/Trantor T128, the | 1153 | * unnecessary jump, making it work on my 386-33/Trantor T128, the |
1331 | * tighter 'C' code breaks and requires this) solves the problem - | 1154 | * tighter 'C' code breaks and requires this) solves the problem - |
1332 | * the 1 us delay is arbitrary, and only used because this delay will | 1155 | * the 1 us delay is arbitrary, and only used because this delay will |
1333 | * be the same on other platforms and since it works here, it should | 1156 | * be the same on other platforms and since it works here, it should |
1334 | * work there. | 1157 | * work there. |
1335 | * | 1158 | * |
1336 | * wingel suggests that this could be due to failing to wait | 1159 | * wingel suggests that this could be due to failing to wait |
@@ -1339,50 +1162,43 @@ static int NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd) | |||
1339 | 1162 | ||
1340 | udelay(1); | 1163 | udelay(1); |
1341 | 1164 | ||
1342 | dprintk(NDEBUG_SELECTION, "scsi%d : selecting target %d\n", instance->host_no, scmd_id(cmd)); | 1165 | dsprintk(NDEBUG_SELECTION, instance, "selecting target %d\n", scmd_id(cmd)); |
1343 | 1166 | ||
1344 | /* | 1167 | /* |
1345 | * The SCSI specification calls for a 250 ms timeout for the actual | 1168 | * The SCSI specification calls for a 250 ms timeout for the actual |
1346 | * selection. | 1169 | * selection. |
1347 | */ | 1170 | */ |
1348 | 1171 | ||
1349 | timeout = jiffies + msecs_to_jiffies(250); | 1172 | err = NCR5380_poll_politely(instance, STATUS_REG, SR_BSY, SR_BSY, |
1350 | 1173 | msecs_to_jiffies(250)); | |
1351 | /* | ||
1352 | * XXX very interesting - we're seeing a bounce where the BSY we | ||
1353 | * asserted is being reflected / still asserted (propagation delay?) | ||
1354 | * and it's detecting as true. Sigh. | ||
1355 | */ | ||
1356 | |||
1357 | hostdata->select_time = 0; /* we count the clock ticks at which we polled */ | ||
1358 | hostdata->selecting = cmd; | ||
1359 | 1174 | ||
1360 | part2: | ||
1361 | /* RvC: here we enter after a sleeping period, or immediately after | ||
1362 | execution of part 1 | ||
1363 | we poll only once ech clock tick */ | ||
1364 | value = NCR5380_read(STATUS_REG) & (SR_BSY | SR_IO); | ||
1365 | |||
1366 | if (!value && (hostdata->select_time < HZ/4)) { | ||
1367 | /* RvC: we still must wait for a device response */ | ||
1368 | hostdata->select_time++; /* after 25 ticks the device has failed */ | ||
1369 | NCR5380_set_timer(hostdata, 1); | ||
1370 | return 0; /* RvC: we return here with hostdata->selecting set, | ||
1371 | to go to sleep */ | ||
1372 | } | ||
1373 | |||
1374 | hostdata->selecting = NULL;/* clear this pointer, because we passed the | ||
1375 | waiting period */ | ||
1376 | if ((NCR5380_read(STATUS_REG) & (SR_SEL | SR_IO)) == (SR_SEL | SR_IO)) { | 1175 | if ((NCR5380_read(STATUS_REG) & (SR_SEL | SR_IO)) == (SR_SEL | SR_IO)) { |
1176 | spin_lock_irq(&hostdata->lock); | ||
1377 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); | 1177 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); |
1378 | NCR5380_reselect(instance); | 1178 | NCR5380_reselect(instance); |
1379 | printk("scsi%d : reselection after won arbitration?\n", instance->host_no); | 1179 | if (!hostdata->connected) |
1180 | NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask); | ||
1181 | shost_printk(KERN_ERR, instance, "reselection after won arbitration?\n"); | ||
1182 | goto out; | ||
1183 | } | ||
1184 | |||
1185 | if (err < 0) { | ||
1186 | spin_lock_irq(&hostdata->lock); | ||
1187 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); | ||
1380 | NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask); | 1188 | NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask); |
1381 | return -1; | 1189 | /* Can't touch cmd if it has been reclaimed by the scsi ML */ |
1190 | if (hostdata->selecting) { | ||
1191 | cmd->result = DID_BAD_TARGET << 16; | ||
1192 | complete_cmd(instance, cmd); | ||
1193 | dsprintk(NDEBUG_SELECTION, instance, "target did not respond within 250ms\n"); | ||
1194 | cmd = NULL; | ||
1195 | } | ||
1196 | goto out; | ||
1382 | } | 1197 | } |
1383 | /* | 1198 | |
1384 | * No less than two deskew delays after the initiator detects the | 1199 | /* |
1385 | * BSY signal is true, it shall release the SEL signal and may | 1200 | * No less than two deskew delays after the initiator detects the |
1201 | * BSY signal is true, it shall release the SEL signal and may | ||
1386 | * change the DATA BUS. -wingel | 1202 | * change the DATA BUS. -wingel |
1387 | */ | 1203 | */ |
1388 | 1204 | ||
@@ -1390,53 +1206,38 @@ part2: | |||
1390 | 1206 | ||
1391 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN); | 1207 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN); |
1392 | 1208 | ||
1393 | if (!(NCR5380_read(STATUS_REG) & SR_BSY)) { | ||
1394 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); | ||
1395 | if (hostdata->targets_present & (1 << scmd_id(cmd))) { | ||
1396 | printk(KERN_DEBUG "scsi%d : weirdness\n", instance->host_no); | ||
1397 | if (hostdata->restart_select) | ||
1398 | printk(KERN_DEBUG "\trestart select\n"); | ||
1399 | NCR5380_dprint(NDEBUG_SELECTION, instance); | ||
1400 | NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask); | ||
1401 | return -1; | ||
1402 | } | ||
1403 | cmd->result = DID_BAD_TARGET << 16; | ||
1404 | cmd->scsi_done(cmd); | ||
1405 | NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask); | ||
1406 | dprintk(NDEBUG_SELECTION, "scsi%d : target did not respond within 250ms\n", instance->host_no); | ||
1407 | NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask); | ||
1408 | return 0; | ||
1409 | } | ||
1410 | hostdata->targets_present |= (1 << scmd_id(cmd)); | ||
1411 | |||
1412 | /* | 1209 | /* |
1413 | * Since we followed the SCSI spec, and raised ATN while SEL | 1210 | * Since we followed the SCSI spec, and raised ATN while SEL |
1414 | * was true but before BSY was false during selection, the information | 1211 | * was true but before BSY was false during selection, the information |
1415 | * transfer phase should be a MESSAGE OUT phase so that we can send the | 1212 | * transfer phase should be a MESSAGE OUT phase so that we can send the |
1416 | * IDENTIFY message. | 1213 | * IDENTIFY message. |
1417 | * | 1214 | * |
1418 | * If SCSI-II tagged queuing is enabled, we also send a SIMPLE_QUEUE_TAG | 1215 | * If SCSI-II tagged queuing is enabled, we also send a SIMPLE_QUEUE_TAG |
1419 | * message (2 bytes) with a tag ID that we increment with every command | 1216 | * message (2 bytes) with a tag ID that we increment with every command |
1420 | * until it wraps back to 0. | 1217 | * until it wraps back to 0. |
1421 | * | 1218 | * |
1422 | * XXX - it turns out that there are some broken SCSI-II devices, | 1219 | * XXX - it turns out that there are some broken SCSI-II devices, |
1423 | * which claim to support tagged queuing but fail when more than | 1220 | * which claim to support tagged queuing but fail when more than |
1424 | * some number of commands are issued at once. | 1221 | * some number of commands are issued at once. |
1425 | */ | 1222 | */ |
1426 | 1223 | ||
1427 | /* Wait for start of REQ/ACK handshake */ | 1224 | /* Wait for start of REQ/ACK handshake */ |
1428 | 1225 | ||
1429 | spin_unlock_irq(instance->host_lock); | ||
1430 | err = NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, SR_REQ, HZ); | 1226 | err = NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, SR_REQ, HZ); |
1431 | spin_lock_irq(instance->host_lock); | 1227 | spin_lock_irq(&hostdata->lock); |
1432 | 1228 | if (err < 0) { | |
1433 | if(err) { | 1229 | shost_printk(KERN_ERR, instance, "select: REQ timeout\n"); |
1434 | printk(KERN_ERR "scsi%d: timeout at NCR5380.c:%d\n", instance->host_no, __LINE__); | 1230 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); |
1435 | NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask); | 1231 | NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask); |
1436 | goto failed; | 1232 | goto out; |
1233 | } | ||
1234 | if (!hostdata->selecting) { | ||
1235 | do_abort(instance); | ||
1236 | goto out; | ||
1437 | } | 1237 | } |
1438 | 1238 | ||
1439 | dprintk(NDEBUG_SELECTION, "scsi%d : target %d selected, going into MESSAGE OUT phase.\n", instance->host_no, cmd->device->id); | 1239 | dsprintk(NDEBUG_SELECTION, instance, "target %d selected, going into MESSAGE OUT phase.\n", |
1240 | scmd_id(cmd)); | ||
1440 | tmp[0] = IDENTIFY(((instance->irq == NO_IRQ) ? 0 : 1), cmd->device->lun); | 1241 | tmp[0] = IDENTIFY(((instance->irq == NO_IRQ) ? 0 : 1), cmd->device->lun); |
1441 | 1242 | ||
1442 | len = 1; | 1243 | len = 1; |
@@ -1446,104 +1247,82 @@ part2: | |||
1446 | data = tmp; | 1247 | data = tmp; |
1447 | phase = PHASE_MSGOUT; | 1248 | phase = PHASE_MSGOUT; |
1448 | NCR5380_transfer_pio(instance, &phase, &len, &data); | 1249 | NCR5380_transfer_pio(instance, &phase, &len, &data); |
1449 | dprintk(NDEBUG_SELECTION, "scsi%d : nexus established.\n", instance->host_no); | 1250 | dsprintk(NDEBUG_SELECTION, instance, "nexus established.\n"); |
1450 | /* XXX need to handle errors here */ | 1251 | /* XXX need to handle errors here */ |
1252 | |||
1451 | hostdata->connected = cmd; | 1253 | hostdata->connected = cmd; |
1452 | hostdata->busy[cmd->device->id] |= (1 << (cmd->device->lun & 0xFF)); | 1254 | hostdata->busy[cmd->device->id] |= 1 << cmd->device->lun; |
1453 | 1255 | ||
1454 | initialize_SCp(cmd); | 1256 | initialize_SCp(cmd); |
1455 | 1257 | ||
1456 | return 0; | 1258 | cmd = NULL; |
1457 | |||
1458 | /* Selection failed */ | ||
1459 | failed: | ||
1460 | return -1; | ||
1461 | 1259 | ||
1260 | out: | ||
1261 | if (!hostdata->selecting) | ||
1262 | return NULL; | ||
1263 | hostdata->selecting = NULL; | ||
1264 | return cmd; | ||
1462 | } | 1265 | } |
1463 | 1266 | ||
1464 | /* | 1267 | /* |
1465 | * Function : int NCR5380_transfer_pio (struct Scsi_Host *instance, | 1268 | * Function : int NCR5380_transfer_pio (struct Scsi_Host *instance, |
1466 | * unsigned char *phase, int *count, unsigned char **data) | 1269 | * unsigned char *phase, int *count, unsigned char **data) |
1467 | * | 1270 | * |
1468 | * Purpose : transfers data in given phase using polled I/O | 1271 | * Purpose : transfers data in given phase using polled I/O |
1469 | * | 1272 | * |
1470 | * Inputs : instance - instance of driver, *phase - pointer to | 1273 | * Inputs : instance - instance of driver, *phase - pointer to |
1471 | * what phase is expected, *count - pointer to number of | 1274 | * what phase is expected, *count - pointer to number of |
1472 | * bytes to transfer, **data - pointer to data pointer. | 1275 | * bytes to transfer, **data - pointer to data pointer. |
1473 | * | 1276 | * |
1474 | * Returns : -1 when different phase is entered without transferring | 1277 | * Returns : -1 when different phase is entered without transferring |
1475 | * maximum number of bytes, 0 if all bytes or transferred or exit | 1278 | * maximum number of bytes, 0 if all bytes are transferred or exit |
1476 | * is in same phase. | 1279 | * is in same phase. |
1477 | * | 1280 | * |
1478 | * Also, *phase, *count, *data are modified in place. | 1281 | * Also, *phase, *count, *data are modified in place. |
1479 | * | 1282 | * |
1480 | * XXX Note : handling for bus free may be useful. | 1283 | * XXX Note : handling for bus free may be useful. |
1481 | */ | 1284 | */ |
1482 | 1285 | ||
1483 | /* | 1286 | /* |
1484 | * Note : this code is not as quick as it could be, however it | 1287 | * Note : this code is not as quick as it could be, however it |
1485 | * IS 100% reliable, and for the actual data transfer where speed | 1288 | * IS 100% reliable, and for the actual data transfer where speed |
1486 | * counts, we will always do a pseudo DMA or DMA transfer. | 1289 | * counts, we will always do a pseudo DMA or DMA transfer. |
1487 | */ | 1290 | */ |
1488 | 1291 | ||
1489 | static int NCR5380_transfer_pio(struct Scsi_Host *instance, unsigned char *phase, int *count, unsigned char **data) { | 1292 | static int NCR5380_transfer_pio(struct Scsi_Host *instance, |
1490 | NCR5380_local_declare(); | 1293 | unsigned char *phase, int *count, |
1294 | unsigned char **data) | ||
1295 | { | ||
1491 | unsigned char p = *phase, tmp; | 1296 | unsigned char p = *phase, tmp; |
1492 | int c = *count; | 1297 | int c = *count; |
1493 | unsigned char *d = *data; | 1298 | unsigned char *d = *data; |
1494 | /* | ||
1495 | * RvC: some administrative data to process polling time | ||
1496 | */ | ||
1497 | int break_allowed = 0; | ||
1498 | struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata; | ||
1499 | NCR5380_setup(instance); | ||
1500 | |||
1501 | if (!(p & SR_IO)) | ||
1502 | dprintk(NDEBUG_PIO, "scsi%d : pio write %d bytes\n", instance->host_no, c); | ||
1503 | else | ||
1504 | dprintk(NDEBUG_PIO, "scsi%d : pio read %d bytes\n", instance->host_no, c); | ||
1505 | 1299 | ||
1506 | /* | 1300 | /* |
1507 | * The NCR5380 chip will only drive the SCSI bus when the | 1301 | * The NCR5380 chip will only drive the SCSI bus when the |
1508 | * phase specified in the appropriate bits of the TARGET COMMAND | 1302 | * phase specified in the appropriate bits of the TARGET COMMAND |
1509 | * REGISTER match the STATUS REGISTER | 1303 | * REGISTER match the STATUS REGISTER |
1510 | */ | 1304 | */ |
1511 | 1305 | ||
1512 | NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(p)); | 1306 | NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(p)); |
1513 | 1307 | ||
1514 | /* RvC: don't know if this is necessary, but other SCSI I/O is short | ||
1515 | * so breaks are not necessary there | ||
1516 | */ | ||
1517 | if ((p == PHASE_DATAIN) || (p == PHASE_DATAOUT)) { | ||
1518 | break_allowed = 1; | ||
1519 | } | ||
1520 | do { | 1308 | do { |
1521 | /* | 1309 | /* |
1522 | * Wait for assertion of REQ, after which the phase bits will be | 1310 | * Wait for assertion of REQ, after which the phase bits will be |
1523 | * valid | 1311 | * valid |
1524 | */ | ||
1525 | |||
1526 | /* RvC: we simply poll once, after that we stop temporarily | ||
1527 | * and let the device buffer fill up | ||
1528 | * if breaking is not allowed, we keep polling as long as needed | ||
1529 | */ | 1312 | */ |
1530 | 1313 | ||
1531 | /* FIXME */ | 1314 | if (NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, SR_REQ, HZ) < 0) |
1532 | while (!((tmp = NCR5380_read(STATUS_REG)) & SR_REQ) && !break_allowed); | ||
1533 | if (!(tmp & SR_REQ)) { | ||
1534 | /* timeout condition */ | ||
1535 | NCR5380_set_timer(hostdata, USLEEP_SLEEP); | ||
1536 | break; | 1315 | break; |
1537 | } | ||
1538 | 1316 | ||
1539 | dprintk(NDEBUG_HANDSHAKE, "scsi%d : REQ detected\n", instance->host_no); | 1317 | dsprintk(NDEBUG_HANDSHAKE, instance, "REQ asserted\n"); |
1540 | 1318 | ||
1541 | /* Check for phase mismatch */ | 1319 | /* Check for phase mismatch */ |
1542 | if ((tmp & PHASE_MASK) != p) { | 1320 | if ((NCR5380_read(STATUS_REG) & PHASE_MASK) != p) { |
1543 | dprintk(NDEBUG_HANDSHAKE, "scsi%d : phase mismatch\n", instance->host_no); | 1321 | dsprintk(NDEBUG_PIO, instance, "phase mismatch\n"); |
1544 | NCR5380_dprint_phase(NDEBUG_HANDSHAKE, instance); | 1322 | NCR5380_dprint_phase(NDEBUG_PIO, instance); |
1545 | break; | 1323 | break; |
1546 | } | 1324 | } |
1325 | |||
1547 | /* Do actual transfer from SCSI bus to / from memory */ | 1326 | /* Do actual transfer from SCSI bus to / from memory */ |
1548 | if (!(p & SR_IO)) | 1327 | if (!(p & SR_IO)) |
1549 | NCR5380_write(OUTPUT_DATA_REG, *d); | 1328 | NCR5380_write(OUTPUT_DATA_REG, *d); |
@@ -1552,7 +1331,7 @@ static int NCR5380_transfer_pio(struct Scsi_Host *instance, unsigned char *phase | |||
1552 | 1331 | ||
1553 | ++d; | 1332 | ++d; |
1554 | 1333 | ||
1555 | /* | 1334 | /* |
1556 | * The SCSI standard suggests that in MSGOUT phase, the initiator | 1335 | * The SCSI standard suggests that in MSGOUT phase, the initiator |
1557 | * should drop ATN on the last byte of the message phase | 1336 | * should drop ATN on the last byte of the message phase |
1558 | * after REQ has been asserted for the handshake but before | 1337 | * after REQ has been asserted for the handshake but before |
@@ -1563,29 +1342,34 @@ static int NCR5380_transfer_pio(struct Scsi_Host *instance, unsigned char *phase | |||
1563 | if (!((p & SR_MSG) && c > 1)) { | 1342 | if (!((p & SR_MSG) && c > 1)) { |
1564 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_DATA); | 1343 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_DATA); |
1565 | NCR5380_dprint(NDEBUG_PIO, instance); | 1344 | NCR5380_dprint(NDEBUG_PIO, instance); |
1566 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_DATA | ICR_ASSERT_ACK); | 1345 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | |
1346 | ICR_ASSERT_DATA | ICR_ASSERT_ACK); | ||
1567 | } else { | 1347 | } else { |
1568 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_DATA | ICR_ASSERT_ATN); | 1348 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | |
1349 | ICR_ASSERT_DATA | ICR_ASSERT_ATN); | ||
1569 | NCR5380_dprint(NDEBUG_PIO, instance); | 1350 | NCR5380_dprint(NDEBUG_PIO, instance); |
1570 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_DATA | ICR_ASSERT_ATN | ICR_ASSERT_ACK); | 1351 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | |
1352 | ICR_ASSERT_DATA | ICR_ASSERT_ATN | ICR_ASSERT_ACK); | ||
1571 | } | 1353 | } |
1572 | } else { | 1354 | } else { |
1573 | NCR5380_dprint(NDEBUG_PIO, instance); | 1355 | NCR5380_dprint(NDEBUG_PIO, instance); |
1574 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ACK); | 1356 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ACK); |
1575 | } | 1357 | } |
1576 | 1358 | ||
1577 | /* FIXME - if this fails bus reset ?? */ | 1359 | if (NCR5380_poll_politely(instance, |
1578 | NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, 0, 5*HZ); | 1360 | STATUS_REG, SR_REQ, 0, 5 * HZ) < 0) |
1579 | dprintk(NDEBUG_HANDSHAKE, "scsi%d : req false, handshake complete\n", instance->host_no); | 1361 | break; |
1362 | |||
1363 | dsprintk(NDEBUG_HANDSHAKE, instance, "REQ negated, handshake complete\n"); | ||
1580 | 1364 | ||
1581 | /* | 1365 | /* |
1582 | * We have several special cases to consider during REQ/ACK handshaking : | 1366 | * We have several special cases to consider during REQ/ACK handshaking : |
1583 | * 1. We were in MSGOUT phase, and we are on the last byte of the | 1367 | * 1. We were in MSGOUT phase, and we are on the last byte of the |
1584 | * message. ATN must be dropped as ACK is dropped. | 1368 | * message. ATN must be dropped as ACK is dropped. |
1585 | * | 1369 | * |
1586 | * 2. We are in a MSGIN phase, and we are on the last byte of the | 1370 | * 2. We are in a MSGIN phase, and we are on the last byte of the |
1587 | * message. We must exit with ACK asserted, so that the calling | 1371 | * message. We must exit with ACK asserted, so that the calling |
1588 | * code may raise ATN before dropping ACK to reject the message. | 1372 | * code may raise ATN before dropping ACK to reject the message. |
1589 | * | 1373 | * |
1590 | * 3. ACK and ATN are clear and the target may proceed as normal. | 1374 | * 3. ACK and ATN are clear and the target may proceed as normal. |
1591 | */ | 1375 | */ |
@@ -1597,12 +1381,16 @@ static int NCR5380_transfer_pio(struct Scsi_Host *instance, unsigned char *phase | |||
1597 | } | 1381 | } |
1598 | } while (--c); | 1382 | } while (--c); |
1599 | 1383 | ||
1600 | dprintk(NDEBUG_PIO, "scsi%d : residual %d\n", instance->host_no, c); | 1384 | dsprintk(NDEBUG_PIO, instance, "residual %d\n", c); |
1601 | 1385 | ||
1602 | *count = c; | 1386 | *count = c; |
1603 | *data = d; | 1387 | *data = d; |
1604 | tmp = NCR5380_read(STATUS_REG); | 1388 | tmp = NCR5380_read(STATUS_REG); |
1605 | if (tmp & SR_REQ) | 1389 | /* The phase read from the bus is valid if either REQ is (already) |
1390 | * asserted or if ACK hasn't been released yet. The latter applies if | ||
1391 | * we're in MSG IN, DATA IN or STATUS and all bytes have been received. | ||
1392 | */ | ||
1393 | if ((tmp & SR_REQ) || ((tmp & SR_IO) && c == 0)) | ||
1606 | *phase = tmp & PHASE_MASK; | 1394 | *phase = tmp & PHASE_MASK; |
1607 | else | 1395 | else |
1608 | *phase = PHASE_UNKNOWN; | 1396 | *phase = PHASE_UNKNOWN; |
@@ -1614,79 +1402,80 @@ static int NCR5380_transfer_pio(struct Scsi_Host *instance, unsigned char *phase | |||
1614 | } | 1402 | } |
1615 | 1403 | ||
1616 | /** | 1404 | /** |
1617 | * do_reset - issue a reset command | 1405 | * do_reset - issue a reset command |
1618 | * @host: adapter to reset | 1406 | * @instance: adapter to reset |
1619 | * | 1407 | * |
1620 | * Issue a reset sequence to the NCR5380 and try and get the bus | 1408 | * Issue a reset sequence to the NCR5380 and try and get the bus |
1621 | * back into sane shape. | 1409 | * back into sane shape. |
1622 | * | 1410 | * |
1623 | * Locks: caller holds queue lock | 1411 | * This clears the reset interrupt flag because there may be no handler for |
1412 | * it. When the driver is initialized, the NCR5380_intr() handler has not yet | ||
1413 | * been installed. And when in EH we may have released the ST DMA interrupt. | ||
1624 | */ | 1414 | */ |
1625 | |||
1626 | static void do_reset(struct Scsi_Host *host) { | ||
1627 | NCR5380_local_declare(); | ||
1628 | NCR5380_setup(host); | ||
1629 | 1415 | ||
1630 | NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(NCR5380_read(STATUS_REG) & PHASE_MASK)); | 1416 | static void do_reset(struct Scsi_Host *instance) |
1417 | { | ||
1418 | unsigned long flags; | ||
1419 | |||
1420 | local_irq_save(flags); | ||
1421 | NCR5380_write(TARGET_COMMAND_REG, | ||
1422 | PHASE_SR_TO_TCR(NCR5380_read(STATUS_REG) & PHASE_MASK)); | ||
1631 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_RST); | 1423 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_RST); |
1632 | udelay(25); | 1424 | udelay(50); |
1633 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); | 1425 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); |
1426 | (void)NCR5380_read(RESET_PARITY_INTERRUPT_REG); | ||
1427 | local_irq_restore(flags); | ||
1634 | } | 1428 | } |
1635 | 1429 | ||
1636 | /* | 1430 | /** |
1637 | * Function : do_abort (Scsi_Host *host) | 1431 | * do_abort - abort the currently established nexus by going to |
1638 | * | 1432 | * MESSAGE OUT phase and sending an ABORT message. |
1639 | * Purpose : abort the currently established nexus. Should only be | 1433 | * @instance: relevant scsi host instance |
1640 | * called from a routine which can drop into a | 1434 | * |
1641 | * | 1435 | * Returns 0 on success, -1 on failure. |
1642 | * Returns : 0 on success, -1 on failure. | ||
1643 | * | ||
1644 | * Locks: queue lock held by caller | ||
1645 | * FIXME: sort this out and get new_eh running | ||
1646 | */ | 1436 | */ |
1647 | 1437 | ||
1648 | static int do_abort(struct Scsi_Host *host) { | 1438 | static int do_abort(struct Scsi_Host *instance) |
1649 | NCR5380_local_declare(); | 1439 | { |
1650 | unsigned char *msgptr, phase, tmp; | 1440 | unsigned char *msgptr, phase, tmp; |
1651 | int len; | 1441 | int len; |
1652 | int rc; | 1442 | int rc; |
1653 | NCR5380_setup(host); | ||
1654 | |||
1655 | 1443 | ||
1656 | /* Request message out phase */ | 1444 | /* Request message out phase */ |
1657 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN); | 1445 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN); |
1658 | 1446 | ||
1659 | /* | 1447 | /* |
1660 | * Wait for the target to indicate a valid phase by asserting | 1448 | * Wait for the target to indicate a valid phase by asserting |
1661 | * REQ. Once this happens, we'll have either a MSGOUT phase | 1449 | * REQ. Once this happens, we'll have either a MSGOUT phase |
1662 | * and can immediately send the ABORT message, or we'll have some | 1450 | * and can immediately send the ABORT message, or we'll have some |
1663 | * other phase and will have to source/sink data. | 1451 | * other phase and will have to source/sink data. |
1664 | * | 1452 | * |
1665 | * We really don't care what value was on the bus or what value | 1453 | * We really don't care what value was on the bus or what value |
1666 | * the target sees, so we just handshake. | 1454 | * the target sees, so we just handshake. |
1667 | */ | 1455 | */ |
1668 | 1456 | ||
1669 | rc = NCR5380_poll_politely(host, STATUS_REG, SR_REQ, SR_REQ, 60 * HZ); | 1457 | rc = NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, SR_REQ, 10 * HZ); |
1670 | 1458 | if (rc < 0) | |
1671 | if(rc < 0) | 1459 | goto timeout; |
1672 | return -1; | 1460 | |
1461 | tmp = NCR5380_read(STATUS_REG) & PHASE_MASK; | ||
1673 | 1462 | ||
1674 | tmp = (unsigned char)rc; | ||
1675 | |||
1676 | NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(tmp)); | 1463 | NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(tmp)); |
1677 | 1464 | ||
1678 | if ((tmp & PHASE_MASK) != PHASE_MSGOUT) { | 1465 | if (tmp != PHASE_MSGOUT) { |
1679 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN | ICR_ASSERT_ACK); | 1466 | NCR5380_write(INITIATOR_COMMAND_REG, |
1680 | rc = NCR5380_poll_politely(host, STATUS_REG, SR_REQ, 0, 3*HZ); | 1467 | ICR_BASE | ICR_ASSERT_ATN | ICR_ASSERT_ACK); |
1468 | rc = NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, 0, 3 * HZ); | ||
1469 | if (rc < 0) | ||
1470 | goto timeout; | ||
1681 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN); | 1471 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN); |
1682 | if(rc == -1) | ||
1683 | return -1; | ||
1684 | } | 1472 | } |
1473 | |||
1685 | tmp = ABORT; | 1474 | tmp = ABORT; |
1686 | msgptr = &tmp; | 1475 | msgptr = &tmp; |
1687 | len = 1; | 1476 | len = 1; |
1688 | phase = PHASE_MSGOUT; | 1477 | phase = PHASE_MSGOUT; |
1689 | NCR5380_transfer_pio(host, &phase, &len, &msgptr); | 1478 | NCR5380_transfer_pio(instance, &phase, &len, &msgptr); |
1690 | 1479 | ||
1691 | /* | 1480 | /* |
1692 | * If we got here, and the command completed successfully, | 1481 | * If we got here, and the command completed successfully, |
@@ -1694,32 +1483,37 @@ static int do_abort(struct Scsi_Host *host) { | |||
1694 | */ | 1483 | */ |
1695 | 1484 | ||
1696 | return len ? -1 : 0; | 1485 | return len ? -1 : 0; |
1486 | |||
1487 | timeout: | ||
1488 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); | ||
1489 | return -1; | ||
1697 | } | 1490 | } |
1698 | 1491 | ||
1699 | #if defined(REAL_DMA) || defined(PSEUDO_DMA) || defined (REAL_DMA_POLL) | 1492 | #if defined(REAL_DMA) || defined(PSEUDO_DMA) || defined (REAL_DMA_POLL) |
1700 | /* | 1493 | /* |
1701 | * Function : int NCR5380_transfer_dma (struct Scsi_Host *instance, | 1494 | * Function : int NCR5380_transfer_dma (struct Scsi_Host *instance, |
1702 | * unsigned char *phase, int *count, unsigned char **data) | 1495 | * unsigned char *phase, int *count, unsigned char **data) |
1703 | * | 1496 | * |
1704 | * Purpose : transfers data in given phase using either real | 1497 | * Purpose : transfers data in given phase using either real |
1705 | * or pseudo DMA. | 1498 | * or pseudo DMA. |
1706 | * | 1499 | * |
1707 | * Inputs : instance - instance of driver, *phase - pointer to | 1500 | * Inputs : instance - instance of driver, *phase - pointer to |
1708 | * what phase is expected, *count - pointer to number of | 1501 | * what phase is expected, *count - pointer to number of |
1709 | * bytes to transfer, **data - pointer to data pointer. | 1502 | * bytes to transfer, **data - pointer to data pointer. |
1710 | * | ||
1711 | * Returns : -1 when different phase is entered without transferring | ||
1712 | * maximum number of bytes, 0 if all bytes or transferred or exit | ||
1713 | * is in same phase. | ||
1714 | * | 1503 | * |
1715 | * Also, *phase, *count, *data are modified in place. | 1504 | * Returns : -1 when different phase is entered without transferring |
1505 | * maximum number of bytes, 0 if all bytes or transferred or exit | ||
1506 | * is in same phase. | ||
1716 | * | 1507 | * |
1717 | * Locks: io_request lock held by caller | 1508 | * Also, *phase, *count, *data are modified in place. |
1718 | */ | 1509 | */ |
1719 | 1510 | ||
1720 | 1511 | ||
1721 | static int NCR5380_transfer_dma(struct Scsi_Host *instance, unsigned char *phase, int *count, unsigned char **data) { | 1512 | static int NCR5380_transfer_dma(struct Scsi_Host *instance, |
1722 | NCR5380_local_declare(); | 1513 | unsigned char *phase, int *count, |
1514 | unsigned char **data) | ||
1515 | { | ||
1516 | struct NCR5380_hostdata *hostdata = shost_priv(instance); | ||
1723 | register int c = *count; | 1517 | register int c = *count; |
1724 | register unsigned char p = *phase; | 1518 | register unsigned char p = *phase; |
1725 | register unsigned char *d = *data; | 1519 | register unsigned char *d = *data; |
@@ -1730,54 +1524,47 @@ static int NCR5380_transfer_dma(struct Scsi_Host *instance, unsigned char *phase | |||
1730 | unsigned char saved_data = 0, overrun = 0, residue; | 1524 | unsigned char saved_data = 0, overrun = 0, residue; |
1731 | #endif | 1525 | #endif |
1732 | 1526 | ||
1733 | struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata; | ||
1734 | |||
1735 | NCR5380_setup(instance); | ||
1736 | |||
1737 | if ((tmp = (NCR5380_read(STATUS_REG) & PHASE_MASK)) != p) { | 1527 | if ((tmp = (NCR5380_read(STATUS_REG) & PHASE_MASK)) != p) { |
1738 | *phase = tmp; | 1528 | *phase = tmp; |
1739 | return -1; | 1529 | return -1; |
1740 | } | 1530 | } |
1741 | #if defined(REAL_DMA) || defined(REAL_DMA_POLL) | 1531 | #if defined(REAL_DMA) || defined(REAL_DMA_POLL) |
1742 | #ifdef READ_OVERRUNS | ||
1743 | if (p & SR_IO) { | 1532 | if (p & SR_IO) { |
1744 | c -= 2; | 1533 | if (!(hostdata->flags & FLAG_NO_DMA_FIXUPS)) |
1534 | c -= 2; | ||
1745 | } | 1535 | } |
1746 | #endif | ||
1747 | dprintk(NDEBUG_DMA, "scsi%d : initializing DMA channel %d for %s, %d bytes %s %0x\n", instance->host_no, instance->dma_channel, (p & SR_IO) ? "reading" : "writing", c, (p & SR_IO) ? "to" : "from", (unsigned) d); | ||
1748 | hostdata->dma_len = (p & SR_IO) ? NCR5380_dma_read_setup(instance, d, c) : NCR5380_dma_write_setup(instance, d, c); | 1536 | hostdata->dma_len = (p & SR_IO) ? NCR5380_dma_read_setup(instance, d, c) : NCR5380_dma_write_setup(instance, d, c); |
1537 | |||
1538 | dsprintk(NDEBUG_DMA, instance, "initializing DMA %s: length %d, address %p\n", | ||
1539 | (p & SR_IO) ? "receive" : "send", c, *data); | ||
1749 | #endif | 1540 | #endif |
1750 | 1541 | ||
1751 | NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(p)); | 1542 | NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(p)); |
1752 | 1543 | ||
1753 | #ifdef REAL_DMA | 1544 | #ifdef REAL_DMA |
1754 | NCR5380_write(MODE_REG, MR_BASE | MR_DMA_MODE | MR_ENABLE_EOP_INTR | MR_MONITOR_BSY); | 1545 | NCR5380_write(MODE_REG, MR_BASE | MR_DMA_MODE | MR_MONITOR_BSY | |
1546 | MR_ENABLE_EOP_INTR); | ||
1755 | #elif defined(REAL_DMA_POLL) | 1547 | #elif defined(REAL_DMA_POLL) |
1756 | NCR5380_write(MODE_REG, MR_BASE | MR_DMA_MODE); | 1548 | NCR5380_write(MODE_REG, MR_BASE | MR_DMA_MODE | MR_MONITOR_BSY); |
1757 | #else | 1549 | #else |
1758 | /* | 1550 | /* |
1759 | * Note : on my sample board, watch-dog timeouts occurred when interrupts | 1551 | * Note : on my sample board, watch-dog timeouts occurred when interrupts |
1760 | * were not disabled for the duration of a single DMA transfer, from | 1552 | * were not disabled for the duration of a single DMA transfer, from |
1761 | * before the setting of DMA mode to after transfer of the last byte. | 1553 | * before the setting of DMA mode to after transfer of the last byte. |
1762 | */ | 1554 | */ |
1763 | 1555 | ||
1764 | #if defined(PSEUDO_DMA) && defined(UNSAFE) | 1556 | if (hostdata->flags & FLAG_NO_DMA_FIXUP) |
1765 | spin_unlock_irq(instance->host_lock); | 1557 | NCR5380_write(MODE_REG, MR_BASE | MR_DMA_MODE | MR_MONITOR_BSY | |
1766 | #endif | 1558 | MR_ENABLE_EOP_INTR); |
1767 | /* KLL May need eop and parity in 53c400 */ | ||
1768 | if (hostdata->flags & FLAG_NCR53C400) | ||
1769 | NCR5380_write(MODE_REG, MR_BASE | MR_DMA_MODE | | ||
1770 | MR_ENABLE_PAR_CHECK | MR_ENABLE_PAR_INTR | | ||
1771 | MR_ENABLE_EOP_INTR | MR_MONITOR_BSY); | ||
1772 | else | 1559 | else |
1773 | NCR5380_write(MODE_REG, MR_BASE | MR_DMA_MODE); | 1560 | NCR5380_write(MODE_REG, MR_BASE | MR_DMA_MODE | MR_MONITOR_BSY); |
1774 | #endif /* def REAL_DMA */ | 1561 | #endif /* def REAL_DMA */ |
1775 | 1562 | ||
1776 | dprintk(NDEBUG_DMA, "scsi%d : mode reg = 0x%X\n", instance->host_no, NCR5380_read(MODE_REG)); | 1563 | dprintk(NDEBUG_DMA, "scsi%d : mode reg = 0x%X\n", instance->host_no, NCR5380_read(MODE_REG)); |
1777 | 1564 | ||
1778 | /* | 1565 | /* |
1779 | * On the PAS16 at least I/O recovery delays are not needed here. | 1566 | * On the PAS16 at least I/O recovery delays are not needed here. |
1780 | * Everyone else seems to want them. | 1567 | * Everyone else seems to want them. |
1781 | */ | 1568 | */ |
1782 | 1569 | ||
1783 | if (p & SR_IO) { | 1570 | if (p & SR_IO) { |
@@ -1797,49 +1584,49 @@ static int NCR5380_transfer_dma(struct Scsi_Host *instance, unsigned char *phase | |||
1797 | } while ((tmp & BASR_PHASE_MATCH) && !(tmp & (BASR_BUSY_ERROR | BASR_END_DMA_TRANSFER))); | 1584 | } while ((tmp & BASR_PHASE_MATCH) && !(tmp & (BASR_BUSY_ERROR | BASR_END_DMA_TRANSFER))); |
1798 | 1585 | ||
1799 | /* | 1586 | /* |
1800 | At this point, either we've completed DMA, or we have a phase mismatch, | 1587 | * At this point, either we've completed DMA, or we have a phase mismatch, |
1801 | or we've unexpectedly lost BUSY (which is a real error). | 1588 | * or we've unexpectedly lost BUSY (which is a real error). |
1802 | 1589 | * | |
1803 | For write DMAs, we want to wait until the last byte has been | 1590 | * For DMA sends, we want to wait until the last byte has been |
1804 | transferred out over the bus before we turn off DMA mode. Alas, there | 1591 | * transferred out over the bus before we turn off DMA mode. Alas, there |
1805 | seems to be no terribly good way of doing this on a 5380 under all | 1592 | * seems to be no terribly good way of doing this on a 5380 under all |
1806 | conditions. For non-scatter-gather operations, we can wait until REQ | 1593 | * conditions. For non-scatter-gather operations, we can wait until REQ |
1807 | and ACK both go false, or until a phase mismatch occurs. Gather-writes | 1594 | * and ACK both go false, or until a phase mismatch occurs. Gather-sends |
1808 | are nastier, since the device will be expecting more data than we | 1595 | * are nastier, since the device will be expecting more data than we |
1809 | are prepared to send it, and REQ will remain asserted. On a 53C8[01] we | 1596 | * are prepared to send it, and REQ will remain asserted. On a 53C8[01] we |
1810 | could test LAST BIT SENT to assure transfer (I imagine this is precisely | 1597 | * could test Last Byte Sent to assure transfer (I imagine this is precisely |
1811 | why this signal was added to the newer chips) but on the older 538[01] | 1598 | * why this signal was added to the newer chips) but on the older 538[01] |
1812 | this signal does not exist. The workaround for this lack is a watchdog; | 1599 | * this signal does not exist. The workaround for this lack is a watchdog; |
1813 | we bail out of the wait-loop after a modest amount of wait-time if | 1600 | * we bail out of the wait-loop after a modest amount of wait-time if |
1814 | the usual exit conditions are not met. Not a terribly clean or | 1601 | * the usual exit conditions are not met. Not a terribly clean or |
1815 | correct solution :-% | 1602 | * correct solution :-% |
1816 | 1603 | * | |
1817 | Reads are equally tricky due to a nasty characteristic of the NCR5380. | 1604 | * DMA receive is equally tricky due to a nasty characteristic of the NCR5380. |
1818 | If the chip is in DMA mode for an READ, it will respond to a target's | 1605 | * If the chip is in DMA receive mode, it will respond to a target's |
1819 | REQ by latching the SCSI data into the INPUT DATA register and asserting | 1606 | * REQ by latching the SCSI data into the INPUT DATA register and asserting |
1820 | ACK, even if it has _already_ been notified by the DMA controller that | 1607 | * ACK, even if it has _already_ been notified by the DMA controller that |
1821 | the current DMA transfer has completed! If the NCR5380 is then taken | 1608 | * the current DMA transfer has completed! If the NCR5380 is then taken |
1822 | out of DMA mode, this already-acknowledged byte is lost. | 1609 | * out of DMA mode, this already-acknowledged byte is lost. This is |
1823 | 1610 | * not a problem for "one DMA transfer per READ command", because | |
1824 | This is not a problem for "one DMA transfer per command" reads, because | 1611 | * the situation will never arise... either all of the data is DMA'ed |
1825 | the situation will never arise... either all of the data is DMA'ed | 1612 | * properly, or the target switches to MESSAGE IN phase to signal a |
1826 | properly, or the target switches to MESSAGE IN phase to signal a | 1613 | * disconnection (either operation bringing the DMA to a clean halt). |
1827 | disconnection (either operation bringing the DMA to a clean halt). | 1614 | * However, in order to handle scatter-receive, we must work around the |
1828 | However, in order to handle scatter-reads, we must work around the | 1615 | * problem. The chosen fix is to DMA N-2 bytes, then check for the |
1829 | problem. The chosen fix is to DMA N-2 bytes, then check for the | 1616 | * condition before taking the NCR5380 out of DMA mode. One or two extra |
1830 | condition before taking the NCR5380 out of DMA mode. One or two extra | 1617 | * bytes are transferred via PIO as necessary to fill out the original |
1831 | bytes are transferred via PIO as necessary to fill out the original | 1618 | * request. |
1832 | request. | ||
1833 | */ | 1619 | */ |
1834 | 1620 | ||
1835 | if (p & SR_IO) { | 1621 | if (p & SR_IO) { |
1836 | #ifdef READ_OVERRUNS | 1622 | if (!(hostdata->flags & FLAG_NO_DMA_FIXUPS)) { |
1837 | udelay(10); | 1623 | udelay(10); |
1838 | if (((NCR5380_read(BUS_AND_STATUS_REG) & (BASR_PHASE_MATCH | BASR_ACK)) == (BASR_PHASE_MATCH | BASR_ACK))) { | 1624 | if ((NCR5380_read(BUS_AND_STATUS_REG) & (BASR_PHASE_MATCH | BASR_ACK)) == |
1839 | saved_data = NCR5380_read(INPUT_DATA_REGISTER); | 1625 | (BASR_PHASE_MATCH | BASR_ACK)) { |
1840 | overrun = 1; | 1626 | saved_data = NCR5380_read(INPUT_DATA_REGISTER); |
1627 | overrun = 1; | ||
1628 | } | ||
1841 | } | 1629 | } |
1842 | #endif | ||
1843 | } else { | 1630 | } else { |
1844 | int limit = 100; | 1631 | int limit = 100; |
1845 | while (((tmp = NCR5380_read(BUS_AND_STATUS_REG)) & BASR_ACK) || (NCR5380_read(STATUS_REG) & SR_REQ)) { | 1632 | while (((tmp = NCR5380_read(BUS_AND_STATUS_REG)) & BASR_ACK) || (NCR5380_read(STATUS_REG) & SR_REQ)) { |
@@ -1850,7 +1637,8 @@ static int NCR5380_transfer_dma(struct Scsi_Host *instance, unsigned char *phase | |||
1850 | } | 1637 | } |
1851 | } | 1638 | } |
1852 | 1639 | ||
1853 | dprintk(NDEBUG_DMA, "scsi%d : polled DMA transfer complete, basr 0x%X, sr 0x%X\n", instance->host_no, tmp, NCR5380_read(STATUS_REG)); | 1640 | dsprintk(NDEBUG_DMA, "polled DMA transfer complete, basr 0x%02x, sr 0x%02x\n", |
1641 | tmp, NCR5380_read(STATUS_REG)); | ||
1854 | 1642 | ||
1855 | NCR5380_write(MODE_REG, MR_BASE); | 1643 | NCR5380_write(MODE_REG, MR_BASE); |
1856 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); | 1644 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); |
@@ -1861,8 +1649,8 @@ static int NCR5380_transfer_dma(struct Scsi_Host *instance, unsigned char *phase | |||
1861 | *data += c; | 1649 | *data += c; |
1862 | *phase = NCR5380_read(STATUS_REG) & PHASE_MASK; | 1650 | *phase = NCR5380_read(STATUS_REG) & PHASE_MASK; |
1863 | 1651 | ||
1864 | #ifdef READ_OVERRUNS | 1652 | if (!(hostdata->flags & FLAG_NO_DMA_FIXUPS) && |
1865 | if (*phase == p && (p & SR_IO) && residue == 0) { | 1653 | *phase == p && (p & SR_IO) && residue == 0) { |
1866 | if (overrun) { | 1654 | if (overrun) { |
1867 | dprintk(NDEBUG_DMA, "Got an input overrun, using saved byte\n"); | 1655 | dprintk(NDEBUG_DMA, "Got an input overrun, using saved byte\n"); |
1868 | **data = saved_data; | 1656 | **data = saved_data; |
@@ -1877,7 +1665,6 @@ static int NCR5380_transfer_dma(struct Scsi_Host *instance, unsigned char *phase | |||
1877 | NCR5380_transfer_pio(instance, phase, &cnt, data); | 1665 | NCR5380_transfer_pio(instance, phase, &cnt, data); |
1878 | *count -= toPIO - cnt; | 1666 | *count -= toPIO - cnt; |
1879 | } | 1667 | } |
1880 | #endif | ||
1881 | 1668 | ||
1882 | dprintk(NDEBUG_DMA, "Return with data ptr = 0x%X, count %d, last 0x%X, next 0x%X\n", *data, *count, *(*data + *count - 1), *(*data + *count)); | 1669 | dprintk(NDEBUG_DMA, "Return with data ptr = 0x%X, count %d, last 0x%X, next 0x%X\n", *data, *count, *(*data + *count - 1), *(*data + *count)); |
1883 | return 0; | 1670 | return 0; |
@@ -1886,95 +1673,64 @@ static int NCR5380_transfer_dma(struct Scsi_Host *instance, unsigned char *phase | |||
1886 | return 0; | 1673 | return 0; |
1887 | #else /* defined(REAL_DMA_POLL) */ | 1674 | #else /* defined(REAL_DMA_POLL) */ |
1888 | if (p & SR_IO) { | 1675 | if (p & SR_IO) { |
1889 | #ifdef DMA_WORKS_RIGHT | 1676 | foo = NCR5380_pread(instance, d, |
1890 | foo = NCR5380_pread(instance, d, c); | 1677 | hostdata->flags & FLAG_NO_DMA_FIXUP ? c : c - 1); |
1891 | #else | 1678 | if (!foo && !(hostdata->flags & FLAG_NO_DMA_FIXUP)) { |
1892 | int diff = 1; | ||
1893 | if (hostdata->flags & FLAG_NCR53C400) { | ||
1894 | diff = 0; | ||
1895 | } | ||
1896 | if (!(foo = NCR5380_pread(instance, d, c - diff))) { | ||
1897 | /* | 1679 | /* |
1898 | * We can't disable DMA mode after successfully transferring | 1680 | * We can't disable DMA mode after successfully transferring |
1899 | * what we plan to be the last byte, since that would open up | 1681 | * what we plan to be the last byte, since that would open up |
1900 | * a race condition where if the target asserted REQ before | 1682 | * a race condition where if the target asserted REQ before |
1901 | * we got the DMA mode reset, the NCR5380 would have latched | 1683 | * we got the DMA mode reset, the NCR5380 would have latched |
1902 | * an additional byte into the INPUT DATA register and we'd | 1684 | * an additional byte into the INPUT DATA register and we'd |
1903 | * have dropped it. | 1685 | * have dropped it. |
1904 | * | 1686 | * |
1905 | * The workaround was to transfer one fewer bytes than we | 1687 | * The workaround was to transfer one fewer bytes than we |
1906 | * intended to with the pseudo-DMA read function, wait for | 1688 | * intended to with the pseudo-DMA read function, wait for |
1907 | * the chip to latch the last byte, read it, and then disable | 1689 | * the chip to latch the last byte, read it, and then disable |
1908 | * pseudo-DMA mode. | 1690 | * pseudo-DMA mode. |
1909 | * | 1691 | * |
1910 | * After REQ is asserted, the NCR5380 asserts DRQ and ACK. | 1692 | * After REQ is asserted, the NCR5380 asserts DRQ and ACK. |
1911 | * REQ is deasserted when ACK is asserted, and not reasserted | 1693 | * REQ is deasserted when ACK is asserted, and not reasserted |
1912 | * until ACK goes false. Since the NCR5380 won't lower ACK | 1694 | * until ACK goes false. Since the NCR5380 won't lower ACK |
1913 | * until DACK is asserted, which won't happen unless we twiddle | 1695 | * until DACK is asserted, which won't happen unless we twiddle |
1914 | * the DMA port or we take the NCR5380 out of DMA mode, we | 1696 | * the DMA port or we take the NCR5380 out of DMA mode, we |
1915 | * can guarantee that we won't handshake another extra | 1697 | * can guarantee that we won't handshake another extra |
1916 | * byte. | 1698 | * byte. |
1917 | */ | 1699 | */ |
1918 | 1700 | ||
1919 | if (!(hostdata->flags & FLAG_NCR53C400)) { | 1701 | if (NCR5380_poll_politely(instance, BUS_AND_STATUS_REG, |
1920 | while (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_DRQ)); | 1702 | BASR_DRQ, BASR_DRQ, HZ) < 0) { |
1921 | /* Wait for clean handshake */ | 1703 | foo = -1; |
1922 | while (NCR5380_read(STATUS_REG) & SR_REQ); | 1704 | shost_printk(KERN_ERR, instance, "PDMA read: DRQ timeout\n"); |
1923 | d[c - 1] = NCR5380_read(INPUT_DATA_REG); | 1705 | } |
1706 | if (NCR5380_poll_politely(instance, STATUS_REG, | ||
1707 | SR_REQ, 0, HZ) < 0) { | ||
1708 | foo = -1; | ||
1709 | shost_printk(KERN_ERR, instance, "PDMA read: !REQ timeout\n"); | ||
1924 | } | 1710 | } |
1711 | d[c - 1] = NCR5380_read(INPUT_DATA_REG); | ||
1925 | } | 1712 | } |
1926 | #endif | ||
1927 | } else { | 1713 | } else { |
1928 | #ifdef DMA_WORKS_RIGHT | ||
1929 | foo = NCR5380_pwrite(instance, d, c); | 1714 | foo = NCR5380_pwrite(instance, d, c); |
1930 | #else | 1715 | if (!foo && !(hostdata->flags & FLAG_NO_DMA_FIXUP)) { |
1931 | int timeout; | ||
1932 | dprintk(NDEBUG_C400_PWRITE, "About to pwrite %d bytes\n", c); | ||
1933 | if (!(foo = NCR5380_pwrite(instance, d, c))) { | ||
1934 | /* | 1716 | /* |
1935 | * Wait for the last byte to be sent. If REQ is being asserted for | 1717 | * Wait for the last byte to be sent. If REQ is being asserted for |
1936 | * the byte we're interested, we'll ACK it and it will go false. | 1718 | * the byte we're interested, we'll ACK it and it will go false. |
1937 | */ | 1719 | */ |
1938 | if (!(hostdata->flags & FLAG_HAS_LAST_BYTE_SENT)) { | 1720 | if (NCR5380_poll_politely2(instance, |
1939 | timeout = 20000; | 1721 | BUS_AND_STATUS_REG, BASR_DRQ, BASR_DRQ, |
1940 | while (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_DRQ) && (NCR5380_read(BUS_AND_STATUS_REG) & BASR_PHASE_MATCH)); | 1722 | BUS_AND_STATUS_REG, BASR_PHASE_MATCH, 0, HZ) < 0) { |
1941 | 1723 | foo = -1; | |
1942 | if (!timeout) | 1724 | shost_printk(KERN_ERR, instance, "PDMA write: DRQ and phase timeout\n"); |
1943 | dprintk(NDEBUG_LAST_BYTE_SENT, "scsi%d : timed out on last byte\n", instance->host_no); | ||
1944 | |||
1945 | if (hostdata->flags & FLAG_CHECK_LAST_BYTE_SENT) { | ||
1946 | hostdata->flags &= ~FLAG_CHECK_LAST_BYTE_SENT; | ||
1947 | if (NCR5380_read(TARGET_COMMAND_REG) & TCR_LAST_BYTE_SENT) { | ||
1948 | hostdata->flags |= FLAG_HAS_LAST_BYTE_SENT; | ||
1949 | dprintk(NDEBUG_LAST_BYTE_SENT, "scsi%d : last byte sent works\n", instance->host_no); | ||
1950 | } | ||
1951 | } | ||
1952 | } else { | ||
1953 | dprintk(NDEBUG_C400_PWRITE, "Waiting for LASTBYTE\n"); | ||
1954 | while (!(NCR5380_read(TARGET_COMMAND_REG) & TCR_LAST_BYTE_SENT)); | ||
1955 | dprintk(NDEBUG_C400_PWRITE, "Got LASTBYTE\n"); | ||
1956 | } | 1725 | } |
1957 | } | 1726 | } |
1958 | #endif | ||
1959 | } | 1727 | } |
1960 | NCR5380_write(MODE_REG, MR_BASE); | 1728 | NCR5380_write(MODE_REG, MR_BASE); |
1961 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); | 1729 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); |
1962 | 1730 | NCR5380_read(RESET_PARITY_INTERRUPT_REG); | |
1963 | if ((!(p & SR_IO)) && (hostdata->flags & FLAG_NCR53C400)) { | ||
1964 | dprintk(NDEBUG_C400_PWRITE, "53C400w: Checking for IRQ\n"); | ||
1965 | if (NCR5380_read(BUS_AND_STATUS_REG) & BASR_IRQ) { | ||
1966 | dprintk(NDEBUG_C400_PWRITE, "53C400w: got it, reading reset interrupt reg\n"); | ||
1967 | NCR5380_read(RESET_PARITY_INTERRUPT_REG); | ||
1968 | } else { | ||
1969 | printk("53C400w: IRQ NOT THERE!\n"); | ||
1970 | } | ||
1971 | } | ||
1972 | *data = d + c; | 1731 | *data = d + c; |
1973 | *count = 0; | 1732 | *count = 0; |
1974 | *phase = NCR5380_read(STATUS_REG) & PHASE_MASK; | 1733 | *phase = NCR5380_read(STATUS_REG) & PHASE_MASK; |
1975 | #if defined(PSEUDO_DMA) && defined(UNSAFE) | ||
1976 | spin_lock_irq(instance->host_lock); | ||
1977 | #endif /* defined(REAL_DMA_POLL) */ | ||
1978 | return foo; | 1734 | return foo; |
1979 | #endif /* def REAL_DMA */ | 1735 | #endif /* def REAL_DMA */ |
1980 | } | 1736 | } |
@@ -1983,25 +1739,23 @@ static int NCR5380_transfer_dma(struct Scsi_Host *instance, unsigned char *phase | |||
1983 | /* | 1739 | /* |
1984 | * Function : NCR5380_information_transfer (struct Scsi_Host *instance) | 1740 | * Function : NCR5380_information_transfer (struct Scsi_Host *instance) |
1985 | * | 1741 | * |
1986 | * Purpose : run through the various SCSI phases and do as the target | 1742 | * Purpose : run through the various SCSI phases and do as the target |
1987 | * directs us to. Operates on the currently connected command, | 1743 | * directs us to. Operates on the currently connected command, |
1988 | * instance->connected. | 1744 | * instance->connected. |
1989 | * | 1745 | * |
1990 | * Inputs : instance, instance for which we are doing commands | 1746 | * Inputs : instance, instance for which we are doing commands |
1991 | * | 1747 | * |
1992 | * Side effects : SCSI things happen, the disconnected queue will be | 1748 | * Side effects : SCSI things happen, the disconnected queue will be |
1993 | * modified if a command disconnects, *instance->connected will | 1749 | * modified if a command disconnects, *instance->connected will |
1994 | * change. | 1750 | * change. |
1995 | * | ||
1996 | * XXX Note : we need to watch for bus free or a reset condition here | ||
1997 | * to recover from an unexpected bus free condition. | ||
1998 | * | 1751 | * |
1999 | * Locks: io_request_lock held by caller in IRQ mode | 1752 | * XXX Note : we need to watch for bus free or a reset condition here |
1753 | * to recover from an unexpected bus free condition. | ||
2000 | */ | 1754 | */ |
2001 | 1755 | ||
2002 | static void NCR5380_information_transfer(struct Scsi_Host *instance) { | 1756 | static void NCR5380_information_transfer(struct Scsi_Host *instance) |
2003 | NCR5380_local_declare(); | 1757 | { |
2004 | struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *)instance->hostdata; | 1758 | struct NCR5380_hostdata *hostdata = shost_priv(instance); |
2005 | unsigned char msgout = NOP; | 1759 | unsigned char msgout = NOP; |
2006 | int sink = 0; | 1760 | int sink = 0; |
2007 | int len; | 1761 | int len; |
@@ -2010,13 +1764,11 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) { | |||
2010 | #endif | 1764 | #endif |
2011 | unsigned char *data; | 1765 | unsigned char *data; |
2012 | unsigned char phase, tmp, extended_msg[10], old_phase = 0xff; | 1766 | unsigned char phase, tmp, extended_msg[10], old_phase = 0xff; |
2013 | struct scsi_cmnd *cmd = (struct scsi_cmnd *) hostdata->connected; | 1767 | struct scsi_cmnd *cmd; |
2014 | /* RvC: we need to set the end of the polling time */ | ||
2015 | unsigned long poll_time = jiffies + USLEEP_POLL; | ||
2016 | 1768 | ||
2017 | NCR5380_setup(instance); | 1769 | while ((cmd = hostdata->connected)) { |
1770 | struct NCR5380_cmd *ncmd = scsi_cmd_priv(cmd); | ||
2018 | 1771 | ||
2019 | while (1) { | ||
2020 | tmp = NCR5380_read(STATUS_REG); | 1772 | tmp = NCR5380_read(STATUS_REG); |
2021 | /* We only have a valid SCSI phase when REQ is asserted */ | 1773 | /* We only have a valid SCSI phase when REQ is asserted */ |
2022 | if (tmp & SR_REQ) { | 1774 | if (tmp & SR_REQ) { |
@@ -2028,24 +1780,28 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) { | |||
2028 | if (sink && (phase != PHASE_MSGOUT)) { | 1780 | if (sink && (phase != PHASE_MSGOUT)) { |
2029 | NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(tmp)); | 1781 | NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(tmp)); |
2030 | 1782 | ||
2031 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN | ICR_ASSERT_ACK); | 1783 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN | |
2032 | while (NCR5380_read(STATUS_REG) & SR_REQ); | 1784 | ICR_ASSERT_ACK); |
2033 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN); | 1785 | while (NCR5380_read(STATUS_REG) & SR_REQ) |
1786 | ; | ||
1787 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | | ||
1788 | ICR_ASSERT_ATN); | ||
2034 | sink = 0; | 1789 | sink = 0; |
2035 | continue; | 1790 | continue; |
2036 | } | 1791 | } |
1792 | |||
2037 | switch (phase) { | 1793 | switch (phase) { |
2038 | case PHASE_DATAIN: | ||
2039 | case PHASE_DATAOUT: | 1794 | case PHASE_DATAOUT: |
2040 | #if (NDEBUG & NDEBUG_NO_DATAOUT) | 1795 | #if (NDEBUG & NDEBUG_NO_DATAOUT) |
2041 | printk("scsi%d : NDEBUG_NO_DATAOUT set, attempted DATAOUT aborted\n", instance->host_no); | 1796 | shost_printk(KERN_DEBUG, instance, "NDEBUG_NO_DATAOUT set, attempted DATAOUT aborted\n"); |
2042 | sink = 1; | 1797 | sink = 1; |
2043 | do_abort(instance); | 1798 | do_abort(instance); |
2044 | cmd->result = DID_ERROR << 16; | 1799 | cmd->result = DID_ERROR << 16; |
2045 | cmd->scsi_done(cmd); | 1800 | complete_cmd(instance, cmd); |
2046 | return; | 1801 | return; |
2047 | #endif | 1802 | #endif |
2048 | /* | 1803 | case PHASE_DATAIN: |
1804 | /* | ||
2049 | * If there is no room left in the current buffer in the | 1805 | * If there is no room left in the current buffer in the |
2050 | * scatter-gather list, move onto the next one. | 1806 | * scatter-gather list, move onto the next one. |
2051 | */ | 1807 | */ |
@@ -2055,10 +1811,13 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) { | |||
2055 | --cmd->SCp.buffers_residual; | 1811 | --cmd->SCp.buffers_residual; |
2056 | cmd->SCp.this_residual = cmd->SCp.buffer->length; | 1812 | cmd->SCp.this_residual = cmd->SCp.buffer->length; |
2057 | cmd->SCp.ptr = sg_virt(cmd->SCp.buffer); | 1813 | cmd->SCp.ptr = sg_virt(cmd->SCp.buffer); |
2058 | dprintk(NDEBUG_INFORMATION, "scsi%d : %d bytes and %d buffers left\n", instance->host_no, cmd->SCp.this_residual, cmd->SCp.buffers_residual); | 1814 | dsprintk(NDEBUG_INFORMATION, instance, "%d bytes and %d buffers left\n", |
1815 | cmd->SCp.this_residual, | ||
1816 | cmd->SCp.buffers_residual); | ||
2059 | } | 1817 | } |
1818 | |||
2060 | /* | 1819 | /* |
2061 | * The preferred transfer method is going to be | 1820 | * The preferred transfer method is going to be |
2062 | * PSEUDO-DMA for systems that are strictly PIO, | 1821 | * PSEUDO-DMA for systems that are strictly PIO, |
2063 | * since we can let the hardware do the handshaking. | 1822 | * since we can let the hardware do the handshaking. |
2064 | * | 1823 | * |
@@ -2068,50 +1827,39 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) { | |||
2068 | */ | 1827 | */ |
2069 | 1828 | ||
2070 | #if defined(PSEUDO_DMA) || defined(REAL_DMA_POLL) | 1829 | #if defined(PSEUDO_DMA) || defined(REAL_DMA_POLL) |
2071 | /* KLL | 1830 | transfersize = 0; |
2072 | * PSEUDO_DMA is defined here. If this is the g_NCR5380 | 1831 | if (!cmd->device->borken && |
2073 | * driver then it will always be defined, so the | 1832 | !(hostdata->flags & FLAG_NO_PSEUDO_DMA)) |
2074 | * FLAG_NO_PSEUDO_DMA is used to inhibit PDMA in the base | 1833 | transfersize = NCR5380_dma_xfer_len(instance, cmd, phase); |
2075 | * NCR5380 case. I think this is a fairly clean solution. | 1834 | |
2076 | * We supplement these 2 if's with the flag. | 1835 | if (transfersize) { |
2077 | */ | ||
2078 | #ifdef NCR5380_dma_xfer_len | ||
2079 | if (!cmd->device->borken && !(hostdata->flags & FLAG_NO_PSEUDO_DMA) && (transfersize = NCR5380_dma_xfer_len(instance, cmd)) != 0) { | ||
2080 | #else | ||
2081 | transfersize = cmd->transfersize; | ||
2082 | |||
2083 | #ifdef LIMIT_TRANSFERSIZE /* If we have problems with interrupt service */ | ||
2084 | if (transfersize > 512) | ||
2085 | transfersize = 512; | ||
2086 | #endif /* LIMIT_TRANSFERSIZE */ | ||
2087 | |||
2088 | if (!cmd->device->borken && transfersize && !(hostdata->flags & FLAG_NO_PSEUDO_DMA) && cmd->SCp.this_residual && !(cmd->SCp.this_residual % transfersize)) { | ||
2089 | /* Limit transfers to 32K, for xx400 & xx406 | ||
2090 | * pseudoDMA that transfers in 128 bytes blocks. */ | ||
2091 | if (transfersize > 32 * 1024) | ||
2092 | transfersize = 32 * 1024; | ||
2093 | #endif | ||
2094 | len = transfersize; | 1836 | len = transfersize; |
2095 | if (NCR5380_transfer_dma(instance, &phase, &len, (unsigned char **) &cmd->SCp.ptr)) { | 1837 | if (NCR5380_transfer_dma(instance, &phase, |
1838 | &len, (unsigned char **)&cmd->SCp.ptr)) { | ||
2096 | /* | 1839 | /* |
2097 | * If the watchdog timer fires, all future accesses to this | 1840 | * If the watchdog timer fires, all future |
2098 | * device will use the polled-IO. | 1841 | * accesses to this device will use the |
1842 | * polled-IO. | ||
2099 | */ | 1843 | */ |
2100 | scmd_printk(KERN_INFO, cmd, | 1844 | scmd_printk(KERN_INFO, cmd, |
2101 | "switching to slow handshake\n"); | 1845 | "switching to slow handshake\n"); |
2102 | cmd->device->borken = 1; | 1846 | cmd->device->borken = 1; |
2103 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN); | ||
2104 | sink = 1; | 1847 | sink = 1; |
2105 | do_abort(instance); | 1848 | do_abort(instance); |
2106 | cmd->result = DID_ERROR << 16; | 1849 | cmd->result = DID_ERROR << 16; |
2107 | cmd->scsi_done(cmd); | 1850 | complete_cmd(instance, cmd); |
2108 | /* XXX - need to source or sink data here, as appropriate */ | 1851 | /* XXX - need to source or sink data here, as appropriate */ |
2109 | } else | 1852 | } else |
2110 | cmd->SCp.this_residual -= transfersize - len; | 1853 | cmd->SCp.this_residual -= transfersize - len; |
2111 | } else | 1854 | } else |
2112 | #endif /* defined(PSEUDO_DMA) || defined(REAL_DMA_POLL) */ | 1855 | #endif /* defined(PSEUDO_DMA) || defined(REAL_DMA_POLL) */ |
2113 | NCR5380_transfer_pio(instance, &phase, (int *) &cmd->SCp.this_residual, (unsigned char **) | 1856 | { |
2114 | &cmd->SCp.ptr); | 1857 | spin_unlock_irq(&hostdata->lock); |
1858 | NCR5380_transfer_pio(instance, &phase, | ||
1859 | (int *)&cmd->SCp.this_residual, | ||
1860 | (unsigned char **)&cmd->SCp.ptr); | ||
1861 | spin_lock_irq(&hostdata->lock); | ||
1862 | } | ||
2115 | break; | 1863 | break; |
2116 | case PHASE_MSGIN: | 1864 | case PHASE_MSGIN: |
2117 | len = 1; | 1865 | len = 1; |
@@ -2120,101 +1868,42 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) { | |||
2120 | cmd->SCp.Message = tmp; | 1868 | cmd->SCp.Message = tmp; |
2121 | 1869 | ||
2122 | switch (tmp) { | 1870 | switch (tmp) { |
2123 | /* | ||
2124 | * Linking lets us reduce the time required to get the | ||
2125 | * next command out to the device, hopefully this will | ||
2126 | * mean we don't waste another revolution due to the delays | ||
2127 | * required by ARBITRATION and another SELECTION. | ||
2128 | * | ||
2129 | * In the current implementation proposal, low level drivers | ||
2130 | * merely have to start the next command, pointed to by | ||
2131 | * next_link, done() is called as with unlinked commands. | ||
2132 | */ | ||
2133 | #ifdef LINKED | ||
2134 | case LINKED_CMD_COMPLETE: | ||
2135 | case LINKED_FLG_CMD_COMPLETE: | ||
2136 | /* Accept message by clearing ACK */ | ||
2137 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); | ||
2138 | dprintk(NDEBUG_LINKED, "scsi%d : target %d lun %llu linked command complete.\n", instance->host_no, cmd->device->id, cmd->device->lun); | ||
2139 | /* | ||
2140 | * Sanity check : A linked command should only terminate with | ||
2141 | * one of these messages if there are more linked commands | ||
2142 | * available. | ||
2143 | */ | ||
2144 | if (!cmd->next_link) { | ||
2145 | printk("scsi%d : target %d lun %llu linked command complete, no next_link\n" instance->host_no, cmd->device->id, cmd->device->lun); | ||
2146 | sink = 1; | ||
2147 | do_abort(instance); | ||
2148 | return; | ||
2149 | } | ||
2150 | initialize_SCp(cmd->next_link); | ||
2151 | /* The next command is still part of this process */ | ||
2152 | cmd->next_link->tag = cmd->tag; | ||
2153 | cmd->result = cmd->SCp.Status | (cmd->SCp.Message << 8); | ||
2154 | dprintk(NDEBUG_LINKED, "scsi%d : target %d lun %llu linked request done, calling scsi_done().\n", instance->host_no, cmd->device->id, cmd->device->lun); | ||
2155 | cmd->scsi_done(cmd); | ||
2156 | cmd = hostdata->connected; | ||
2157 | break; | ||
2158 | #endif /* def LINKED */ | ||
2159 | case ABORT: | 1871 | case ABORT: |
2160 | case COMMAND_COMPLETE: | 1872 | case COMMAND_COMPLETE: |
2161 | /* Accept message by clearing ACK */ | 1873 | /* Accept message by clearing ACK */ |
2162 | sink = 1; | 1874 | sink = 1; |
2163 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); | 1875 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); |
2164 | hostdata->connected = NULL; | 1876 | dsprintk(NDEBUG_QUEUES, instance, |
2165 | dprintk(NDEBUG_QUEUES, "scsi%d : command for target %d, lun %llu completed\n", instance->host_no, cmd->device->id, cmd->device->lun); | 1877 | "COMMAND COMPLETE %p target %d lun %llu\n", |
2166 | hostdata->busy[cmd->device->id] &= ~(1 << (cmd->device->lun & 0xFF)); | 1878 | cmd, scmd_id(cmd), cmd->device->lun); |
2167 | |||
2168 | /* | ||
2169 | * I'm not sure what the correct thing to do here is : | ||
2170 | * | ||
2171 | * If the command that just executed is NOT a request | ||
2172 | * sense, the obvious thing to do is to set the result | ||
2173 | * code to the values of the stored parameters. | ||
2174 | * | ||
2175 | * If it was a REQUEST SENSE command, we need some way | ||
2176 | * to differentiate between the failure code of the original | ||
2177 | * and the failure code of the REQUEST sense - the obvious | ||
2178 | * case is success, where we fall through and leave the result | ||
2179 | * code unchanged. | ||
2180 | * | ||
2181 | * The non-obvious place is where the REQUEST SENSE failed | ||
2182 | */ | ||
2183 | |||
2184 | if (cmd->cmnd[0] != REQUEST_SENSE) | ||
2185 | cmd->result = cmd->SCp.Status | (cmd->SCp.Message << 8); | ||
2186 | else if (status_byte(cmd->SCp.Status) != GOOD) | ||
2187 | cmd->result = (cmd->result & 0x00ffff) | (DID_ERROR << 16); | ||
2188 | 1879 | ||
2189 | if ((cmd->cmnd[0] == REQUEST_SENSE) && | 1880 | hostdata->connected = NULL; |
2190 | hostdata->ses.cmd_len) { | ||
2191 | scsi_eh_restore_cmnd(cmd, &hostdata->ses); | ||
2192 | hostdata->ses.cmd_len = 0 ; | ||
2193 | } | ||
2194 | |||
2195 | if ((cmd->cmnd[0] != REQUEST_SENSE) && (status_byte(cmd->SCp.Status) == CHECK_CONDITION)) { | ||
2196 | scsi_eh_prep_cmnd(cmd, &hostdata->ses, NULL, 0, ~0); | ||
2197 | |||
2198 | dprintk(NDEBUG_AUTOSENSE, "scsi%d : performing request sense\n", instance->host_no); | ||
2199 | 1881 | ||
2200 | LIST(cmd, hostdata->issue_queue); | 1882 | cmd->result &= ~0xffff; |
2201 | cmd->host_scribble = (unsigned char *) | 1883 | cmd->result |= cmd->SCp.Status; |
2202 | hostdata->issue_queue; | 1884 | cmd->result |= cmd->SCp.Message << 8; |
2203 | hostdata->issue_queue = (struct scsi_cmnd *) cmd; | 1885 | |
2204 | dprintk(NDEBUG_QUEUES, "scsi%d : REQUEST SENSE added to head of issue queue\n", instance->host_no); | 1886 | if (cmd->cmnd[0] == REQUEST_SENSE) |
2205 | } else { | 1887 | complete_cmd(instance, cmd); |
2206 | cmd->scsi_done(cmd); | 1888 | else { |
1889 | if (cmd->SCp.Status == SAM_STAT_CHECK_CONDITION || | ||
1890 | cmd->SCp.Status == SAM_STAT_COMMAND_TERMINATED) { | ||
1891 | dsprintk(NDEBUG_QUEUES, instance, "autosense: adding cmd %p to tail of autosense queue\n", | ||
1892 | cmd); | ||
1893 | list_add_tail(&ncmd->list, | ||
1894 | &hostdata->autosense); | ||
1895 | } else | ||
1896 | complete_cmd(instance, cmd); | ||
2207 | } | 1897 | } |
2208 | 1898 | ||
2209 | NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask); | 1899 | /* |
2210 | /* | 1900 | * Restore phase bits to 0 so an interrupted selection, |
2211 | * Restore phase bits to 0 so an interrupted selection, | ||
2212 | * arbitration can resume. | 1901 | * arbitration can resume. |
2213 | */ | 1902 | */ |
2214 | NCR5380_write(TARGET_COMMAND_REG, 0); | 1903 | NCR5380_write(TARGET_COMMAND_REG, 0); |
2215 | 1904 | ||
2216 | while ((NCR5380_read(STATUS_REG) & SR_BSY) && !hostdata->connected) | 1905 | /* Enable reselect interrupts */ |
2217 | barrier(); | 1906 | NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask); |
2218 | return; | 1907 | return; |
2219 | case MESSAGE_REJECT: | 1908 | case MESSAGE_REJECT: |
2220 | /* Accept message by clearing ACK */ | 1909 | /* Accept message by clearing ACK */ |
@@ -2229,38 +1918,33 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) { | |||
2229 | default: | 1918 | default: |
2230 | break; | 1919 | break; |
2231 | } | 1920 | } |
2232 | case DISCONNECT:{ | 1921 | break; |
2233 | /* Accept message by clearing ACK */ | 1922 | case DISCONNECT: |
2234 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); | 1923 | /* Accept message by clearing ACK */ |
2235 | cmd->device->disconnect = 1; | 1924 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); |
2236 | LIST(cmd, hostdata->disconnected_queue); | 1925 | hostdata->connected = NULL; |
2237 | cmd->host_scribble = (unsigned char *) | 1926 | list_add(&ncmd->list, &hostdata->disconnected); |
2238 | hostdata->disconnected_queue; | 1927 | dsprintk(NDEBUG_INFORMATION | NDEBUG_QUEUES, |
2239 | hostdata->connected = NULL; | 1928 | instance, "connected command %p for target %d lun %llu moved to disconnected queue\n", |
2240 | hostdata->disconnected_queue = cmd; | 1929 | cmd, scmd_id(cmd), cmd->device->lun); |
2241 | dprintk(NDEBUG_QUEUES, "scsi%d : command for target %d lun %llu was moved from connected to" " the disconnected_queue\n", instance->host_no, cmd->device->id, cmd->device->lun); | 1930 | |
2242 | /* | 1931 | /* |
2243 | * Restore phase bits to 0 so an interrupted selection, | 1932 | * Restore phase bits to 0 so an interrupted selection, |
2244 | * arbitration can resume. | 1933 | * arbitration can resume. |
2245 | */ | 1934 | */ |
2246 | NCR5380_write(TARGET_COMMAND_REG, 0); | 1935 | NCR5380_write(TARGET_COMMAND_REG, 0); |
2247 | 1936 | ||
2248 | /* Enable reselect interrupts */ | 1937 | /* Enable reselect interrupts */ |
2249 | NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask); | 1938 | NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask); |
2250 | /* Wait for bus free to avoid nasty timeouts - FIXME timeout !*/ | 1939 | return; |
2251 | /* NCR538_poll_politely(instance, STATUS_REG, SR_BSY, 0, 30 * HZ); */ | 1940 | /* |
2252 | while ((NCR5380_read(STATUS_REG) & SR_BSY) && !hostdata->connected) | ||
2253 | barrier(); | ||
2254 | return; | ||
2255 | } | ||
2256 | /* | ||
2257 | * The SCSI data pointer is *IMPLICITLY* saved on a disconnect | 1941 | * The SCSI data pointer is *IMPLICITLY* saved on a disconnect |
2258 | * operation, in violation of the SCSI spec so we can safely | 1942 | * operation, in violation of the SCSI spec so we can safely |
2259 | * ignore SAVE/RESTORE pointers calls. | 1943 | * ignore SAVE/RESTORE pointers calls. |
2260 | * | 1944 | * |
2261 | * Unfortunately, some disks violate the SCSI spec and | 1945 | * Unfortunately, some disks violate the SCSI spec and |
2262 | * don't issue the required SAVE_POINTERS message before | 1946 | * don't issue the required SAVE_POINTERS message before |
2263 | * disconnecting, and we have to break spec to remain | 1947 | * disconnecting, and we have to break spec to remain |
2264 | * compatible. | 1948 | * compatible. |
2265 | */ | 1949 | */ |
2266 | case SAVE_POINTERS: | 1950 | case SAVE_POINTERS: |
@@ -2269,31 +1953,28 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) { | |||
2269 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); | 1953 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); |
2270 | break; | 1954 | break; |
2271 | case EXTENDED_MESSAGE: | 1955 | case EXTENDED_MESSAGE: |
2272 | /* | 1956 | /* |
2273 | * Extended messages are sent in the following format : | 1957 | * Start the message buffer with the EXTENDED_MESSAGE |
2274 | * Byte | 1958 | * byte, since spi_print_msg() wants the whole thing. |
2275 | * 0 EXTENDED_MESSAGE == 1 | 1959 | */ |
2276 | * 1 length (includes one byte for code, doesn't | ||
2277 | * include first two bytes) | ||
2278 | * 2 code | ||
2279 | * 3..length+1 arguments | ||
2280 | * | ||
2281 | * Start the extended message buffer with the EXTENDED_MESSAGE | ||
2282 | * byte, since spi_print_msg() wants the whole thing. | ||
2283 | */ | ||
2284 | extended_msg[0] = EXTENDED_MESSAGE; | 1960 | extended_msg[0] = EXTENDED_MESSAGE; |
2285 | /* Accept first byte by clearing ACK */ | 1961 | /* Accept first byte by clearing ACK */ |
2286 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); | 1962 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); |
2287 | dprintk(NDEBUG_EXTENDED, "scsi%d : receiving extended message\n", instance->host_no); | 1963 | |
1964 | spin_unlock_irq(&hostdata->lock); | ||
1965 | |||
1966 | dsprintk(NDEBUG_EXTENDED, instance, "receiving extended message\n"); | ||
2288 | 1967 | ||
2289 | len = 2; | 1968 | len = 2; |
2290 | data = extended_msg + 1; | 1969 | data = extended_msg + 1; |
2291 | phase = PHASE_MSGIN; | 1970 | phase = PHASE_MSGIN; |
2292 | NCR5380_transfer_pio(instance, &phase, &len, &data); | 1971 | NCR5380_transfer_pio(instance, &phase, &len, &data); |
1972 | dsprintk(NDEBUG_EXTENDED, instance, "length %d, code 0x%02x\n", | ||
1973 | (int)extended_msg[1], | ||
1974 | (int)extended_msg[2]); | ||
2293 | 1975 | ||
2294 | dprintk(NDEBUG_EXTENDED, "scsi%d : length=%d, code=0x%02x\n", instance->host_no, (int) extended_msg[1], (int) extended_msg[2]); | 1976 | if (!len && extended_msg[1] > 0 && |
2295 | 1977 | extended_msg[1] <= sizeof(extended_msg) - 2) { | |
2296 | if (!len && extended_msg[1] <= (sizeof(extended_msg) - 1)) { | ||
2297 | /* Accept third byte by clearing ACK */ | 1978 | /* Accept third byte by clearing ACK */ |
2298 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); | 1979 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); |
2299 | len = extended_msg[1] - 1; | 1980 | len = extended_msg[1] - 1; |
@@ -2301,7 +1982,8 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) { | |||
2301 | phase = PHASE_MSGIN; | 1982 | phase = PHASE_MSGIN; |
2302 | 1983 | ||
2303 | NCR5380_transfer_pio(instance, &phase, &len, &data); | 1984 | NCR5380_transfer_pio(instance, &phase, &len, &data); |
2304 | dprintk(NDEBUG_EXTENDED, "scsi%d : message received, residual %d\n", instance->host_no, len); | 1985 | dsprintk(NDEBUG_EXTENDED, instance, "message received, residual %d\n", |
1986 | len); | ||
2305 | 1987 | ||
2306 | switch (extended_msg[2]) { | 1988 | switch (extended_msg[2]) { |
2307 | case EXTENDED_SDTR: | 1989 | case EXTENDED_SDTR: |
@@ -2311,34 +1993,42 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) { | |||
2311 | tmp = 0; | 1993 | tmp = 0; |
2312 | } | 1994 | } |
2313 | } else if (len) { | 1995 | } else if (len) { |
2314 | printk("scsi%d: error receiving extended message\n", instance->host_no); | 1996 | shost_printk(KERN_ERR, instance, "error receiving extended message\n"); |
2315 | tmp = 0; | 1997 | tmp = 0; |
2316 | } else { | 1998 | } else { |
2317 | printk("scsi%d: extended message code %02x length %d is too long\n", instance->host_no, extended_msg[2], extended_msg[1]); | 1999 | shost_printk(KERN_NOTICE, instance, "extended message code %02x length %d is too long\n", |
2000 | extended_msg[2], extended_msg[1]); | ||
2318 | tmp = 0; | 2001 | tmp = 0; |
2319 | } | 2002 | } |
2003 | |||
2004 | spin_lock_irq(&hostdata->lock); | ||
2005 | if (!hostdata->connected) | ||
2006 | return; | ||
2007 | |||
2320 | /* Fall through to reject message */ | 2008 | /* Fall through to reject message */ |
2321 | 2009 | ||
2322 | /* | 2010 | /* |
2323 | * If we get something weird that we aren't expecting, | 2011 | * If we get something weird that we aren't expecting, |
2324 | * reject it. | 2012 | * reject it. |
2325 | */ | 2013 | */ |
2326 | default: | 2014 | default: |
2327 | if (!tmp) { | 2015 | if (!tmp) { |
2328 | printk("scsi%d: rejecting message ", instance->host_no); | 2016 | shost_printk(KERN_ERR, instance, "rejecting message "); |
2329 | spi_print_msg(extended_msg); | 2017 | spi_print_msg(extended_msg); |
2330 | printk("\n"); | 2018 | printk("\n"); |
2331 | } else if (tmp != EXTENDED_MESSAGE) | 2019 | } else if (tmp != EXTENDED_MESSAGE) |
2332 | scmd_printk(KERN_INFO, cmd, | 2020 | scmd_printk(KERN_INFO, cmd, |
2333 | "rejecting unknown message %02x\n",tmp); | 2021 | "rejecting unknown message %02x\n", |
2022 | tmp); | ||
2334 | else | 2023 | else |
2335 | scmd_printk(KERN_INFO, cmd, | 2024 | scmd_printk(KERN_INFO, cmd, |
2336 | "rejecting unknown extended message code %02x, length %d\n", extended_msg[1], extended_msg[0]); | 2025 | "rejecting unknown extended message code %02x, length %d\n", |
2026 | extended_msg[1], extended_msg[0]); | ||
2337 | 2027 | ||
2338 | msgout = MESSAGE_REJECT; | 2028 | msgout = MESSAGE_REJECT; |
2339 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN); | 2029 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN); |
2340 | break; | 2030 | break; |
2341 | } /* switch (tmp) */ | 2031 | } /* switch (tmp) */ |
2342 | break; | 2032 | break; |
2343 | case PHASE_MSGOUT: | 2033 | case PHASE_MSGOUT: |
2344 | len = 1; | 2034 | len = 1; |
@@ -2346,10 +2036,9 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) { | |||
2346 | hostdata->last_message = msgout; | 2036 | hostdata->last_message = msgout; |
2347 | NCR5380_transfer_pio(instance, &phase, &len, &data); | 2037 | NCR5380_transfer_pio(instance, &phase, &len, &data); |
2348 | if (msgout == ABORT) { | 2038 | if (msgout == ABORT) { |
2349 | hostdata->busy[cmd->device->id] &= ~(1 << (cmd->device->lun & 0xFF)); | ||
2350 | hostdata->connected = NULL; | 2039 | hostdata->connected = NULL; |
2351 | cmd->result = DID_ERROR << 16; | 2040 | cmd->result = DID_ERROR << 16; |
2352 | cmd->scsi_done(cmd); | 2041 | complete_cmd(instance, cmd); |
2353 | NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask); | 2042 | NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask); |
2354 | return; | 2043 | return; |
2355 | } | 2044 | } |
@@ -2358,17 +2047,12 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) { | |||
2358 | case PHASE_CMDOUT: | 2047 | case PHASE_CMDOUT: |
2359 | len = cmd->cmd_len; | 2048 | len = cmd->cmd_len; |
2360 | data = cmd->cmnd; | 2049 | data = cmd->cmnd; |
2361 | /* | 2050 | /* |
2362 | * XXX for performance reasons, on machines with a | 2051 | * XXX for performance reasons, on machines with a |
2363 | * PSEUDO-DMA architecture we should probably | 2052 | * PSEUDO-DMA architecture we should probably |
2364 | * use the dma transfer function. | 2053 | * use the dma transfer function. |
2365 | */ | 2054 | */ |
2366 | NCR5380_transfer_pio(instance, &phase, &len, &data); | 2055 | NCR5380_transfer_pio(instance, &phase, &len, &data); |
2367 | if (!cmd->device->disconnect && should_disconnect(cmd->cmnd[0])) { | ||
2368 | NCR5380_set_timer(hostdata, USLEEP_SLEEP); | ||
2369 | dprintk(NDEBUG_USLEEP, "scsi%d : issued command, sleeping until %lu\n", instance->host_no, hostdata->time_expires); | ||
2370 | return; | ||
2371 | } | ||
2372 | break; | 2056 | break; |
2373 | case PHASE_STATIN: | 2057 | case PHASE_STATIN: |
2374 | len = 1; | 2058 | len = 1; |
@@ -2377,46 +2061,37 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) { | |||
2377 | cmd->SCp.Status = tmp; | 2061 | cmd->SCp.Status = tmp; |
2378 | break; | 2062 | break; |
2379 | default: | 2063 | default: |
2380 | printk("scsi%d : unknown phase\n", instance->host_no); | 2064 | shost_printk(KERN_ERR, instance, "unknown phase\n"); |
2381 | NCR5380_dprint(NDEBUG_ANY, instance); | 2065 | NCR5380_dprint(NDEBUG_ANY, instance); |
2382 | } /* switch(phase) */ | 2066 | } /* switch(phase) */ |
2383 | } /* if (tmp * SR_REQ) */ | 2067 | } else { |
2384 | else { | 2068 | spin_unlock_irq(&hostdata->lock); |
2385 | /* RvC: go to sleep if polling time expired | 2069 | NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, SR_REQ, HZ); |
2386 | */ | 2070 | spin_lock_irq(&hostdata->lock); |
2387 | if (!cmd->device->disconnect && time_after_eq(jiffies, poll_time)) { | ||
2388 | NCR5380_set_timer(hostdata, USLEEP_SLEEP); | ||
2389 | dprintk(NDEBUG_USLEEP, "scsi%d : poll timed out, sleeping until %lu\n", instance->host_no, hostdata->time_expires); | ||
2390 | return; | ||
2391 | } | ||
2392 | } | 2071 | } |
2393 | } /* while (1) */ | 2072 | } |
2394 | } | 2073 | } |
2395 | 2074 | ||
2396 | /* | 2075 | /* |
2397 | * Function : void NCR5380_reselect (struct Scsi_Host *instance) | 2076 | * Function : void NCR5380_reselect (struct Scsi_Host *instance) |
2398 | * | 2077 | * |
2399 | * Purpose : does reselection, initializing the instance->connected | 2078 | * Purpose : does reselection, initializing the instance->connected |
2400 | * field to point to the scsi_cmnd for which the I_T_L or I_T_L_Q | 2079 | * field to point to the scsi_cmnd for which the I_T_L or I_T_L_Q |
2401 | * nexus has been reestablished, | 2080 | * nexus has been reestablished, |
2402 | * | ||
2403 | * Inputs : instance - this instance of the NCR5380. | ||
2404 | * | 2081 | * |
2405 | * Locks: io_request_lock held by caller if IRQ driven | 2082 | * Inputs : instance - this instance of the NCR5380. |
2406 | */ | 2083 | */ |
2407 | 2084 | ||
2408 | static void NCR5380_reselect(struct Scsi_Host *instance) { | 2085 | static void NCR5380_reselect(struct Scsi_Host *instance) |
2409 | NCR5380_local_declare(); | 2086 | { |
2410 | struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) | 2087 | struct NCR5380_hostdata *hostdata = shost_priv(instance); |
2411 | instance->hostdata; | ||
2412 | unsigned char target_mask; | 2088 | unsigned char target_mask; |
2413 | unsigned char lun, phase; | 2089 | unsigned char lun, phase; |
2414 | int len; | 2090 | int len; |
2415 | unsigned char msg[3]; | 2091 | unsigned char msg[3]; |
2416 | unsigned char *data; | 2092 | unsigned char *data; |
2417 | struct scsi_cmnd *tmp = NULL, *prev; | 2093 | struct NCR5380_cmd *ncmd; |
2418 | int abort = 0; | 2094 | struct scsi_cmnd *tmp; |
2419 | NCR5380_setup(instance); | ||
2420 | 2095 | ||
2421 | /* | 2096 | /* |
2422 | * Disable arbitration, etc. since the host adapter obviously | 2097 | * Disable arbitration, etc. since the host adapter obviously |
@@ -2424,12 +2099,12 @@ static void NCR5380_reselect(struct Scsi_Host *instance) { | |||
2424 | */ | 2099 | */ |
2425 | 2100 | ||
2426 | NCR5380_write(MODE_REG, MR_BASE); | 2101 | NCR5380_write(MODE_REG, MR_BASE); |
2427 | hostdata->restart_select = 1; | ||
2428 | 2102 | ||
2429 | target_mask = NCR5380_read(CURRENT_SCSI_DATA_REG) & ~(hostdata->id_mask); | 2103 | target_mask = NCR5380_read(CURRENT_SCSI_DATA_REG) & ~(hostdata->id_mask); |
2430 | dprintk(NDEBUG_SELECTION, "scsi%d : reselect\n", instance->host_no); | ||
2431 | 2104 | ||
2432 | /* | 2105 | dsprintk(NDEBUG_RESELECTION, instance, "reselect\n"); |
2106 | |||
2107 | /* | ||
2433 | * At this point, we have detected that our SCSI ID is on the bus, | 2108 | * At this point, we have detected that our SCSI ID is on the bus, |
2434 | * SEL is true and BSY was false for at least one bus settle delay | 2109 | * SEL is true and BSY was false for at least one bus settle delay |
2435 | * (400 ns). | 2110 | * (400 ns). |
@@ -2439,103 +2114,110 @@ static void NCR5380_reselect(struct Scsi_Host *instance) { | |||
2439 | */ | 2114 | */ |
2440 | 2115 | ||
2441 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_BSY); | 2116 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_BSY); |
2442 | 2117 | if (NCR5380_poll_politely(instance, | |
2443 | /* FIXME: timeout too long, must fail to workqueue */ | 2118 | STATUS_REG, SR_SEL, 0, 2 * HZ) < 0) { |
2444 | if(NCR5380_poll_politely(instance, STATUS_REG, SR_SEL, 0, 2*HZ)<0) | 2119 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); |
2445 | abort = 1; | 2120 | return; |
2446 | 2121 | } | |
2447 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); | 2122 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); |
2448 | 2123 | ||
2449 | /* | 2124 | /* |
2450 | * Wait for target to go into MSGIN. | 2125 | * Wait for target to go into MSGIN. |
2451 | * FIXME: timeout needed and fail to work queeu | ||
2452 | */ | 2126 | */ |
2453 | 2127 | ||
2454 | if(NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, SR_REQ, 2*HZ)) | 2128 | if (NCR5380_poll_politely(instance, |
2455 | abort = 1; | 2129 | STATUS_REG, SR_REQ, SR_REQ, 2 * HZ) < 0) { |
2130 | do_abort(instance); | ||
2131 | return; | ||
2132 | } | ||
2456 | 2133 | ||
2457 | len = 1; | 2134 | len = 1; |
2458 | data = msg; | 2135 | data = msg; |
2459 | phase = PHASE_MSGIN; | 2136 | phase = PHASE_MSGIN; |
2460 | NCR5380_transfer_pio(instance, &phase, &len, &data); | 2137 | NCR5380_transfer_pio(instance, &phase, &len, &data); |
2461 | 2138 | ||
2139 | if (len) { | ||
2140 | do_abort(instance); | ||
2141 | return; | ||
2142 | } | ||
2143 | |||
2462 | if (!(msg[0] & 0x80)) { | 2144 | if (!(msg[0] & 0x80)) { |
2463 | printk(KERN_ERR "scsi%d : expecting IDENTIFY message, got ", instance->host_no); | 2145 | shost_printk(KERN_ERR, instance, "expecting IDENTIFY message, got "); |
2464 | spi_print_msg(msg); | 2146 | spi_print_msg(msg); |
2465 | abort = 1; | 2147 | printk("\n"); |
2466 | } else { | 2148 | do_abort(instance); |
2467 | /* Accept message by clearing ACK */ | 2149 | return; |
2468 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); | 2150 | } |
2469 | lun = (msg[0] & 0x07); | 2151 | lun = msg[0] & 0x07; |
2470 | 2152 | ||
2471 | /* | 2153 | /* |
2472 | * We need to add code for SCSI-II to track which devices have | 2154 | * We need to add code for SCSI-II to track which devices have |
2473 | * I_T_L_Q nexuses established, and which have simple I_T_L | 2155 | * I_T_L_Q nexuses established, and which have simple I_T_L |
2474 | * nexuses so we can chose to do additional data transfer. | 2156 | * nexuses so we can chose to do additional data transfer. |
2475 | */ | 2157 | */ |
2476 | 2158 | ||
2477 | /* | 2159 | /* |
2478 | * Find the command corresponding to the I_T_L or I_T_L_Q nexus we | 2160 | * Find the command corresponding to the I_T_L or I_T_L_Q nexus we |
2479 | * just reestablished, and remove it from the disconnected queue. | 2161 | * just reestablished, and remove it from the disconnected queue. |
2480 | */ | 2162 | */ |
2481 | 2163 | ||
2164 | tmp = NULL; | ||
2165 | list_for_each_entry(ncmd, &hostdata->disconnected, list) { | ||
2166 | struct scsi_cmnd *cmd = NCR5380_to_scmd(ncmd); | ||
2482 | 2167 | ||
2483 | for (tmp = (struct scsi_cmnd *) hostdata->disconnected_queue, prev = NULL; tmp; prev = tmp, tmp = (struct scsi_cmnd *) tmp->host_scribble) | 2168 | if (target_mask == (1 << scmd_id(cmd)) && |
2484 | if ((target_mask == (1 << tmp->device->id)) && (lun == (u8)tmp->device->lun) | 2169 | lun == (u8)cmd->device->lun) { |
2485 | ) { | 2170 | list_del(&ncmd->list); |
2486 | if (prev) { | 2171 | tmp = cmd; |
2487 | REMOVE(prev, prev->host_scribble, tmp, tmp->host_scribble); | 2172 | break; |
2488 | prev->host_scribble = tmp->host_scribble; | ||
2489 | } else { | ||
2490 | REMOVE(-1, hostdata->disconnected_queue, tmp, tmp->host_scribble); | ||
2491 | hostdata->disconnected_queue = (struct scsi_cmnd *) tmp->host_scribble; | ||
2492 | } | ||
2493 | tmp->host_scribble = NULL; | ||
2494 | break; | ||
2495 | } | ||
2496 | if (!tmp) { | ||
2497 | printk(KERN_ERR "scsi%d : warning : target bitmask %02x lun %d not in disconnect_queue.\n", instance->host_no, target_mask, lun); | ||
2498 | /* | ||
2499 | * Since we have an established nexus that we can't do anything with, | ||
2500 | * we must abort it. | ||
2501 | */ | ||
2502 | abort = 1; | ||
2503 | } | 2173 | } |
2504 | } | 2174 | } |
2505 | 2175 | ||
2506 | if (abort) { | 2176 | if (tmp) { |
2507 | do_abort(instance); | 2177 | dsprintk(NDEBUG_RESELECTION | NDEBUG_QUEUES, instance, |
2178 | "reselect: removed %p from disconnected queue\n", tmp); | ||
2508 | } else { | 2179 | } else { |
2509 | hostdata->connected = tmp; | 2180 | shost_printk(KERN_ERR, instance, "target bitmask 0x%02x lun %d not in disconnected queue.\n", |
2510 | dprintk(NDEBUG_RESELECTION, "scsi%d : nexus established, target = %d, lun = %llu, tag = %d\n", instance->host_no, tmp->device->id, tmp->device->lun, tmp->tag); | 2181 | target_mask, lun); |
2182 | /* | ||
2183 | * Since we have an established nexus that we can't do anything | ||
2184 | * with, we must abort it. | ||
2185 | */ | ||
2186 | do_abort(instance); | ||
2187 | return; | ||
2511 | } | 2188 | } |
2189 | |||
2190 | /* Accept message by clearing ACK */ | ||
2191 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); | ||
2192 | |||
2193 | hostdata->connected = tmp; | ||
2194 | dsprintk(NDEBUG_RESELECTION, instance, "nexus established, target %d, lun %llu, tag %d\n", | ||
2195 | scmd_id(tmp), tmp->device->lun, tmp->tag); | ||
2512 | } | 2196 | } |
2513 | 2197 | ||
2514 | /* | 2198 | /* |
2515 | * Function : void NCR5380_dma_complete (struct Scsi_Host *instance) | 2199 | * Function : void NCR5380_dma_complete (struct Scsi_Host *instance) |
2516 | * | 2200 | * |
2517 | * Purpose : called by interrupt handler when DMA finishes or a phase | 2201 | * Purpose : called by interrupt handler when DMA finishes or a phase |
2518 | * mismatch occurs (which would finish the DMA transfer). | 2202 | * mismatch occurs (which would finish the DMA transfer). |
2519 | * | 2203 | * |
2520 | * Inputs : instance - this instance of the NCR5380. | 2204 | * Inputs : instance - this instance of the NCR5380. |
2521 | * | 2205 | * |
2522 | * Returns : pointer to the scsi_cmnd structure for which the I_T_L | 2206 | * Returns : pointer to the scsi_cmnd structure for which the I_T_L |
2523 | * nexus has been reestablished, on failure NULL is returned. | 2207 | * nexus has been reestablished, on failure NULL is returned. |
2524 | */ | 2208 | */ |
2525 | 2209 | ||
2526 | #ifdef REAL_DMA | 2210 | #ifdef REAL_DMA |
2527 | static void NCR5380_dma_complete(NCR5380_instance * instance) { | 2211 | static void NCR5380_dma_complete(NCR5380_instance * instance) { |
2528 | NCR5380_local_declare(); | 2212 | struct NCR5380_hostdata *hostdata = shost_priv(instance); |
2529 | struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata; | ||
2530 | int transferred; | 2213 | int transferred; |
2531 | NCR5380_setup(instance); | ||
2532 | 2214 | ||
2533 | /* | 2215 | /* |
2534 | * XXX this might not be right. | 2216 | * XXX this might not be right. |
2535 | * | 2217 | * |
2536 | * Wait for final byte to transfer, ie wait for ACK to go false. | 2218 | * Wait for final byte to transfer, ie wait for ACK to go false. |
2537 | * | 2219 | * |
2538 | * We should use the Last Byte Sent bit, unfortunately this is | 2220 | * We should use the Last Byte Sent bit, unfortunately this is |
2539 | * not available on the 5380/5381 (only the various CMOS chips) | 2221 | * not available on the 5380/5381 (only the various CMOS chips) |
2540 | * | 2222 | * |
2541 | * FIXME: timeout, and need to handle long timeout/irq case | 2223 | * FIXME: timeout, and need to handle long timeout/irq case |
@@ -2543,7 +2225,6 @@ static void NCR5380_dma_complete(NCR5380_instance * instance) { | |||
2543 | 2225 | ||
2544 | NCR5380_poll_politely(instance, BUS_AND_STATUS_REG, BASR_ACK, 0, 5*HZ); | 2226 | NCR5380_poll_politely(instance, BUS_AND_STATUS_REG, BASR_ACK, 0, 5*HZ); |
2545 | 2227 | ||
2546 | NCR5380_write(MODE_REG, MR_BASE); | ||
2547 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); | 2228 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); |
2548 | 2229 | ||
2549 | /* | 2230 | /* |
@@ -2560,190 +2241,251 @@ static void NCR5380_dma_complete(NCR5380_instance * instance) { | |||
2560 | } | 2241 | } |
2561 | #endif /* def REAL_DMA */ | 2242 | #endif /* def REAL_DMA */ |
2562 | 2243 | ||
2563 | /* | 2244 | /** |
2564 | * Function : int NCR5380_abort (struct scsi_cmnd *cmd) | 2245 | * list_find_cmd - test for presence of a command in a linked list |
2565 | * | 2246 | * @haystack: list of commands |
2566 | * Purpose : abort a command | 2247 | * @needle: command to search for |
2567 | * | ||
2568 | * Inputs : cmd - the scsi_cmnd to abort, code - code to set the | ||
2569 | * host byte of the result field to, if zero DID_ABORTED is | ||
2570 | * used. | ||
2571 | * | ||
2572 | * Returns : SUCCESS - success, FAILED on failure. | ||
2573 | * | ||
2574 | * XXX - there is no way to abort the command that is currently | ||
2575 | * connected, you have to wait for it to complete. If this is | ||
2576 | * a problem, we could implement longjmp() / setjmp(), setjmp() | ||
2577 | * called where the loop started in NCR5380_main(). | ||
2578 | * | ||
2579 | * Locks: host lock taken by caller | ||
2580 | */ | 2248 | */ |
2581 | 2249 | ||
2582 | static int NCR5380_abort(struct scsi_cmnd *cmd) | 2250 | static bool list_find_cmd(struct list_head *haystack, |
2251 | struct scsi_cmnd *needle) | ||
2583 | { | 2252 | { |
2584 | NCR5380_local_declare(); | 2253 | struct NCR5380_cmd *ncmd; |
2585 | struct Scsi_Host *instance = cmd->device->host; | ||
2586 | struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata; | ||
2587 | struct scsi_cmnd *tmp, **prev; | ||
2588 | 2254 | ||
2589 | scmd_printk(KERN_WARNING, cmd, "aborting command\n"); | 2255 | list_for_each_entry(ncmd, haystack, list) |
2256 | if (NCR5380_to_scmd(ncmd) == needle) | ||
2257 | return true; | ||
2258 | return false; | ||
2259 | } | ||
2590 | 2260 | ||
2591 | NCR5380_print_status(instance); | 2261 | /** |
2262 | * list_remove_cmd - remove a command from linked list | ||
2263 | * @haystack: list of commands | ||
2264 | * @needle: command to remove | ||
2265 | */ | ||
2592 | 2266 | ||
2593 | NCR5380_setup(instance); | 2267 | static bool list_del_cmd(struct list_head *haystack, |
2268 | struct scsi_cmnd *needle) | ||
2269 | { | ||
2270 | if (list_find_cmd(haystack, needle)) { | ||
2271 | struct NCR5380_cmd *ncmd = scsi_cmd_priv(needle); | ||
2594 | 2272 | ||
2595 | dprintk(NDEBUG_ABORT, "scsi%d : abort called\n", instance->host_no); | 2273 | list_del(&ncmd->list); |
2596 | dprintk(NDEBUG_ABORT, " basr 0x%X, sr 0x%X\n", NCR5380_read(BUS_AND_STATUS_REG), NCR5380_read(STATUS_REG)); | 2274 | return true; |
2275 | } | ||
2276 | return false; | ||
2277 | } | ||
2597 | 2278 | ||
2598 | #if 0 | 2279 | /** |
2599 | /* | 2280 | * NCR5380_abort - scsi host eh_abort_handler() method |
2600 | * Case 1 : If the command is the currently executing command, | 2281 | * @cmd: the command to be aborted |
2601 | * we'll set the aborted flag and return control so that | 2282 | * |
2602 | * information transfer routine can exit cleanly. | 2283 | * Try to abort a given command by removing it from queues and/or sending |
2284 | * the target an abort message. This may not succeed in causing a target | ||
2285 | * to abort the command. Nonetheless, the low-level driver must forget about | ||
2286 | * the command because the mid-layer reclaims it and it may be re-issued. | ||
2287 | * | ||
2288 | * The normal path taken by a command is as follows. For EH we trace this | ||
2289 | * same path to locate and abort the command. | ||
2290 | * | ||
2291 | * unissued -> selecting -> [unissued -> selecting ->]... connected -> | ||
2292 | * [disconnected -> connected ->]... | ||
2293 | * [autosense -> connected ->] done | ||
2294 | * | ||
2295 | * If cmd is unissued then just remove it. | ||
2296 | * If cmd is disconnected, try to select the target. | ||
2297 | * If cmd is connected, try to send an abort message. | ||
2298 | * If cmd is waiting for autosense, give it a chance to complete but check | ||
2299 | * that it isn't left connected. | ||
2300 | * If cmd was not found at all then presumably it has already been completed, | ||
2301 | * in which case return SUCCESS to try to avoid further EH measures. | ||
2302 | * If the command has not completed yet, we must not fail to find it. | ||
2603 | */ | 2303 | */ |
2604 | 2304 | ||
2605 | if (hostdata->connected == cmd) { | 2305 | static int NCR5380_abort(struct scsi_cmnd *cmd) |
2606 | dprintk(NDEBUG_ABORT, "scsi%d : aborting connected command\n", instance->host_no); | 2306 | { |
2607 | hostdata->aborted = 1; | 2307 | struct Scsi_Host *instance = cmd->device->host; |
2608 | /* | 2308 | struct NCR5380_hostdata *hostdata = shost_priv(instance); |
2609 | * We should perform BSY checking, and make sure we haven't slipped | 2309 | unsigned long flags; |
2610 | * into BUS FREE. | 2310 | int result = SUCCESS; |
2611 | */ | ||
2612 | 2311 | ||
2613 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_ASSERT_ATN); | 2312 | spin_lock_irqsave(&hostdata->lock, flags); |
2614 | /* | ||
2615 | * Since we can't change phases until we've completed the current | ||
2616 | * handshake, we have to source or sink a byte of data if the current | ||
2617 | * phase is not MSGOUT. | ||
2618 | */ | ||
2619 | 2313 | ||
2620 | /* | 2314 | #if (NDEBUG & NDEBUG_ANY) |
2621 | * Return control to the executing NCR drive so we can clear the | 2315 | scmd_printk(KERN_INFO, cmd, __func__); |
2622 | * aborted flag and get back into our main loop. | 2316 | #endif |
2623 | */ | 2317 | NCR5380_dprint(NDEBUG_ANY, instance); |
2318 | NCR5380_dprint_phase(NDEBUG_ANY, instance); | ||
2624 | 2319 | ||
2625 | return SUCCESS; | 2320 | if (list_del_cmd(&hostdata->unissued, cmd)) { |
2321 | dsprintk(NDEBUG_ABORT, instance, | ||
2322 | "abort: removed %p from issue queue\n", cmd); | ||
2323 | cmd->result = DID_ABORT << 16; | ||
2324 | cmd->scsi_done(cmd); /* No tag or busy flag to worry about */ | ||
2626 | } | 2325 | } |
2627 | #endif | ||
2628 | 2326 | ||
2629 | /* | 2327 | if (hostdata->selecting == cmd) { |
2630 | * Case 2 : If the command hasn't been issued yet, we simply remove it | 2328 | dsprintk(NDEBUG_ABORT, instance, |
2631 | * from the issue queue. | 2329 | "abort: cmd %p == selecting\n", cmd); |
2632 | */ | 2330 | hostdata->selecting = NULL; |
2633 | 2331 | cmd->result = DID_ABORT << 16; | |
2634 | dprintk(NDEBUG_ABORT, "scsi%d : abort going into loop.\n", instance->host_no); | 2332 | complete_cmd(instance, cmd); |
2635 | 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) | 2333 | goto out; |
2636 | if (cmd == tmp) { | 2334 | } |
2637 | REMOVE(5, *prev, tmp, tmp->host_scribble); | 2335 | |
2638 | (*prev) = (struct scsi_cmnd *) tmp->host_scribble; | 2336 | if (list_del_cmd(&hostdata->disconnected, cmd)) { |
2639 | tmp->host_scribble = NULL; | 2337 | dsprintk(NDEBUG_ABORT, instance, |
2640 | tmp->result = DID_ABORT << 16; | 2338 | "abort: removed %p from disconnected list\n", cmd); |
2641 | dprintk(NDEBUG_ABORT, "scsi%d : abort removed command from issue queue.\n", instance->host_no); | 2339 | cmd->result = DID_ERROR << 16; |
2642 | tmp->scsi_done(tmp); | 2340 | if (!hostdata->connected) |
2643 | return SUCCESS; | 2341 | NCR5380_select(instance, cmd); |
2342 | if (hostdata->connected != cmd) { | ||
2343 | complete_cmd(instance, cmd); | ||
2344 | result = FAILED; | ||
2345 | goto out; | ||
2346 | } | ||
2347 | } | ||
2348 | |||
2349 | if (hostdata->connected == cmd) { | ||
2350 | dsprintk(NDEBUG_ABORT, instance, "abort: cmd %p is connected\n", cmd); | ||
2351 | hostdata->connected = NULL; | ||
2352 | if (do_abort(instance)) { | ||
2353 | set_host_byte(cmd, DID_ERROR); | ||
2354 | complete_cmd(instance, cmd); | ||
2355 | result = FAILED; | ||
2356 | goto out; | ||
2644 | } | 2357 | } |
2645 | #if (NDEBUG & NDEBUG_ABORT) | 2358 | set_host_byte(cmd, DID_ABORT); |
2646 | /* KLL */ | 2359 | #ifdef REAL_DMA |
2647 | else if (prev == tmp) | 2360 | hostdata->dma_len = 0; |
2648 | printk(KERN_ERR "scsi%d : LOOP\n", instance->host_no); | ||
2649 | #endif | 2361 | #endif |
2362 | if (cmd->cmnd[0] == REQUEST_SENSE) | ||
2363 | complete_cmd(instance, cmd); | ||
2364 | else { | ||
2365 | struct NCR5380_cmd *ncmd = scsi_cmd_priv(cmd); | ||
2650 | 2366 | ||
2651 | /* | 2367 | /* Perform autosense for this command */ |
2652 | * Case 3 : If any commands are connected, we're going to fail the abort | 2368 | list_add(&ncmd->list, &hostdata->autosense); |
2653 | * and let the high level SCSI driver retry at a later time or | 2369 | } |
2654 | * issue a reset. | 2370 | } |
2655 | * | ||
2656 | * Timeouts, and therefore aborted commands, will be highly unlikely | ||
2657 | * and handling them cleanly in this situation would make the common | ||
2658 | * case of noresets less efficient, and would pollute our code. So, | ||
2659 | * we fail. | ||
2660 | */ | ||
2661 | 2371 | ||
2662 | if (hostdata->connected) { | 2372 | if (list_find_cmd(&hostdata->autosense, cmd)) { |
2663 | dprintk(NDEBUG_ABORT, "scsi%d : abort failed, command connected.\n", instance->host_no); | 2373 | dsprintk(NDEBUG_ABORT, instance, |
2664 | return FAILED; | 2374 | "abort: found %p on sense queue\n", cmd); |
2375 | spin_unlock_irqrestore(&hostdata->lock, flags); | ||
2376 | queue_work(hostdata->work_q, &hostdata->main_task); | ||
2377 | msleep(1000); | ||
2378 | spin_lock_irqsave(&hostdata->lock, flags); | ||
2379 | if (list_del_cmd(&hostdata->autosense, cmd)) { | ||
2380 | dsprintk(NDEBUG_ABORT, instance, | ||
2381 | "abort: removed %p from sense queue\n", cmd); | ||
2382 | set_host_byte(cmd, DID_ABORT); | ||
2383 | complete_cmd(instance, cmd); | ||
2384 | goto out; | ||
2385 | } | ||
2665 | } | 2386 | } |
2666 | /* | ||
2667 | * Case 4: If the command is currently disconnected from the bus, and | ||
2668 | * there are no connected commands, we reconnect the I_T_L or | ||
2669 | * I_T_L_Q nexus associated with it, go into message out, and send | ||
2670 | * an abort message. | ||
2671 | * | ||
2672 | * This case is especially ugly. In order to reestablish the nexus, we | ||
2673 | * need to call NCR5380_select(). The easiest way to implement this | ||
2674 | * function was to abort if the bus was busy, and let the interrupt | ||
2675 | * handler triggered on the SEL for reselect take care of lost arbitrations | ||
2676 | * where necessary, meaning interrupts need to be enabled. | ||
2677 | * | ||
2678 | * When interrupts are enabled, the queues may change - so we | ||
2679 | * can't remove it from the disconnected queue before selecting it | ||
2680 | * because that could cause a failure in hashing the nexus if that | ||
2681 | * device reselected. | ||
2682 | * | ||
2683 | * Since the queues may change, we can't use the pointers from when we | ||
2684 | * first locate it. | ||
2685 | * | ||
2686 | * So, we must first locate the command, and if NCR5380_select() | ||
2687 | * succeeds, then issue the abort, relocate the command and remove | ||
2688 | * it from the disconnected queue. | ||
2689 | */ | ||
2690 | 2387 | ||
2691 | for (tmp = (struct scsi_cmnd *) hostdata->disconnected_queue; tmp; tmp = (struct scsi_cmnd *) tmp->host_scribble) | 2388 | if (hostdata->connected == cmd) { |
2692 | if (cmd == tmp) { | 2389 | dsprintk(NDEBUG_ABORT, instance, "abort: cmd %p is connected\n", cmd); |
2693 | dprintk(NDEBUG_ABORT, "scsi%d : aborting disconnected command.\n", instance->host_no); | 2390 | hostdata->connected = NULL; |
2391 | if (do_abort(instance)) { | ||
2392 | set_host_byte(cmd, DID_ERROR); | ||
2393 | complete_cmd(instance, cmd); | ||
2394 | result = FAILED; | ||
2395 | goto out; | ||
2396 | } | ||
2397 | set_host_byte(cmd, DID_ABORT); | ||
2398 | #ifdef REAL_DMA | ||
2399 | hostdata->dma_len = 0; | ||
2400 | #endif | ||
2401 | complete_cmd(instance, cmd); | ||
2402 | } | ||
2694 | 2403 | ||
2695 | if (NCR5380_select(instance, cmd)) | 2404 | out: |
2696 | return FAILED; | 2405 | if (result == FAILED) |
2697 | dprintk(NDEBUG_ABORT, "scsi%d : nexus reestablished.\n", instance->host_no); | 2406 | dsprintk(NDEBUG_ABORT, instance, "abort: failed to abort %p\n", cmd); |
2407 | else | ||
2408 | dsprintk(NDEBUG_ABORT, instance, "abort: successfully aborted %p\n", cmd); | ||
2698 | 2409 | ||
2699 | do_abort(instance); | 2410 | queue_work(hostdata->work_q, &hostdata->main_task); |
2411 | spin_unlock_irqrestore(&hostdata->lock, flags); | ||
2700 | 2412 | ||
2701 | 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) | 2413 | return result; |
2702 | if (cmd == tmp) { | ||
2703 | REMOVE(5, *prev, tmp, tmp->host_scribble); | ||
2704 | *prev = (struct scsi_cmnd *) tmp->host_scribble; | ||
2705 | tmp->host_scribble = NULL; | ||
2706 | tmp->result = DID_ABORT << 16; | ||
2707 | tmp->scsi_done(tmp); | ||
2708 | return SUCCESS; | ||
2709 | } | ||
2710 | } | ||
2711 | /* | ||
2712 | * Case 5 : If we reached this point, the command was not found in any of | ||
2713 | * the queues. | ||
2714 | * | ||
2715 | * We probably reached this point because of an unlikely race condition | ||
2716 | * between the command completing successfully and the abortion code, | ||
2717 | * so we won't panic, but we will notify the user in case something really | ||
2718 | * broke. | ||
2719 | */ | ||
2720 | printk(KERN_WARNING "scsi%d : warning : SCSI command probably completed successfully\n" | ||
2721 | " before abortion\n", instance->host_no); | ||
2722 | return FAILED; | ||
2723 | } | 2414 | } |
2724 | 2415 | ||
2725 | 2416 | ||
2726 | /* | 2417 | /** |
2727 | * Function : int NCR5380_bus_reset (struct scsi_cmnd *cmd) | 2418 | * NCR5380_bus_reset - reset the SCSI bus |
2728 | * | 2419 | * @cmd: SCSI command undergoing EH |
2729 | * Purpose : reset the SCSI bus. | ||
2730 | * | ||
2731 | * Returns : SUCCESS | ||
2732 | * | 2420 | * |
2733 | * Locks: host lock taken by caller | 2421 | * Returns SUCCESS |
2734 | */ | 2422 | */ |
2735 | 2423 | ||
2736 | static int NCR5380_bus_reset(struct scsi_cmnd *cmd) | 2424 | static int NCR5380_bus_reset(struct scsi_cmnd *cmd) |
2737 | { | 2425 | { |
2738 | struct Scsi_Host *instance = cmd->device->host; | 2426 | struct Scsi_Host *instance = cmd->device->host; |
2427 | struct NCR5380_hostdata *hostdata = shost_priv(instance); | ||
2428 | int i; | ||
2429 | unsigned long flags; | ||
2430 | struct NCR5380_cmd *ncmd; | ||
2739 | 2431 | ||
2740 | NCR5380_local_declare(); | 2432 | spin_lock_irqsave(&hostdata->lock, flags); |
2741 | NCR5380_setup(instance); | 2433 | |
2742 | NCR5380_print_status(instance); | 2434 | #if (NDEBUG & NDEBUG_ANY) |
2435 | scmd_printk(KERN_INFO, cmd, __func__); | ||
2436 | #endif | ||
2437 | NCR5380_dprint(NDEBUG_ANY, instance); | ||
2438 | NCR5380_dprint_phase(NDEBUG_ANY, instance); | ||
2743 | 2439 | ||
2744 | spin_lock_irq(instance->host_lock); | ||
2745 | do_reset(instance); | 2440 | do_reset(instance); |
2746 | spin_unlock_irq(instance->host_lock); | 2441 | |
2442 | /* reset NCR registers */ | ||
2443 | NCR5380_write(MODE_REG, MR_BASE); | ||
2444 | NCR5380_write(TARGET_COMMAND_REG, 0); | ||
2445 | NCR5380_write(SELECT_ENABLE_REG, 0); | ||
2446 | |||
2447 | /* After the reset, there are no more connected or disconnected commands | ||
2448 | * and no busy units; so clear the low-level status here to avoid | ||
2449 | * conflicts when the mid-level code tries to wake up the affected | ||
2450 | * commands! | ||
2451 | */ | ||
2452 | |||
2453 | hostdata->selecting = NULL; | ||
2454 | |||
2455 | list_for_each_entry(ncmd, &hostdata->disconnected, list) { | ||
2456 | struct scsi_cmnd *cmd = NCR5380_to_scmd(ncmd); | ||
2457 | |||
2458 | set_host_byte(cmd, DID_RESET); | ||
2459 | cmd->scsi_done(cmd); | ||
2460 | } | ||
2461 | |||
2462 | list_for_each_entry(ncmd, &hostdata->autosense, list) { | ||
2463 | struct scsi_cmnd *cmd = NCR5380_to_scmd(ncmd); | ||
2464 | |||
2465 | set_host_byte(cmd, DID_RESET); | ||
2466 | cmd->scsi_done(cmd); | ||
2467 | } | ||
2468 | |||
2469 | if (hostdata->connected) { | ||
2470 | set_host_byte(hostdata->connected, DID_RESET); | ||
2471 | complete_cmd(instance, hostdata->connected); | ||
2472 | hostdata->connected = NULL; | ||
2473 | } | ||
2474 | |||
2475 | if (hostdata->sensing) { | ||
2476 | set_host_byte(hostdata->connected, DID_RESET); | ||
2477 | complete_cmd(instance, hostdata->sensing); | ||
2478 | hostdata->sensing = NULL; | ||
2479 | } | ||
2480 | |||
2481 | for (i = 0; i < 8; ++i) | ||
2482 | hostdata->busy[i] = 0; | ||
2483 | #ifdef REAL_DMA | ||
2484 | hostdata->dma_len = 0; | ||
2485 | #endif | ||
2486 | |||
2487 | queue_work(hostdata->work_q, &hostdata->main_task); | ||
2488 | spin_unlock_irqrestore(&hostdata->lock, flags); | ||
2747 | 2489 | ||
2748 | return SUCCESS; | 2490 | return SUCCESS; |
2749 | } | 2491 | } |
diff --git a/drivers/scsi/NCR5380.h b/drivers/scsi/NCR5380.h index 162112dd1bf8..a79288682a74 100644 --- a/drivers/scsi/NCR5380.h +++ b/drivers/scsi/NCR5380.h | |||
@@ -22,8 +22,13 @@ | |||
22 | #ifndef NCR5380_H | 22 | #ifndef NCR5380_H |
23 | #define NCR5380_H | 23 | #define NCR5380_H |
24 | 24 | ||
25 | #include <linux/delay.h> | ||
25 | #include <linux/interrupt.h> | 26 | #include <linux/interrupt.h> |
27 | #include <linux/list.h> | ||
28 | #include <linux/workqueue.h> | ||
29 | #include <scsi/scsi_dbg.h> | ||
26 | #include <scsi/scsi_eh.h> | 30 | #include <scsi/scsi_eh.h> |
31 | #include <scsi/scsi_transport_spi.h> | ||
27 | 32 | ||
28 | #define NDEBUG_ARBITRATION 0x1 | 33 | #define NDEBUG_ARBITRATION 0x1 |
29 | #define NDEBUG_AUTOSENSE 0x2 | 34 | #define NDEBUG_AUTOSENSE 0x2 |
@@ -158,8 +163,7 @@ | |||
158 | /* Write any value to this register to start an ini mode DMA receive */ | 163 | /* Write any value to this register to start an ini mode DMA receive */ |
159 | #define START_DMA_INITIATOR_RECEIVE_REG 7 /* wo */ | 164 | #define START_DMA_INITIATOR_RECEIVE_REG 7 /* wo */ |
160 | 165 | ||
161 | #define C400_CONTROL_STATUS_REG NCR53C400_register_offset-8 /* rw */ | 166 | /* NCR 53C400(A) Control Status Register bits: */ |
162 | |||
163 | #define CSR_RESET 0x80 /* wo Resets 53c400 */ | 167 | #define CSR_RESET 0x80 /* wo Resets 53c400 */ |
164 | #define CSR_53C80_REG 0x80 /* ro 5380 registers busy */ | 168 | #define CSR_53C80_REG 0x80 /* ro 5380 registers busy */ |
165 | #define CSR_TRANS_DIR 0x40 /* rw Data transfer direction */ | 169 | #define CSR_TRANS_DIR 0x40 /* rw Data transfer direction */ |
@@ -176,16 +180,6 @@ | |||
176 | #define CSR_BASE CSR_53C80_INTR | 180 | #define CSR_BASE CSR_53C80_INTR |
177 | #endif | 181 | #endif |
178 | 182 | ||
179 | /* Number of 128-byte blocks to be transferred */ | ||
180 | #define C400_BLOCK_COUNTER_REG NCR53C400_register_offset-7 /* rw */ | ||
181 | |||
182 | /* Resume transfer after disconnect */ | ||
183 | #define C400_RESUME_TRANSFER_REG NCR53C400_register_offset-6 /* wo */ | ||
184 | |||
185 | /* Access to host buffer stack */ | ||
186 | #define C400_HOST_BUFFER NCR53C400_register_offset-4 /* rw */ | ||
187 | |||
188 | |||
189 | /* Note : PHASE_* macros are based on the values of the STATUS register */ | 183 | /* Note : PHASE_* macros are based on the values of the STATUS register */ |
190 | #define PHASE_MASK (SR_MSG | SR_CD | SR_IO) | 184 | #define PHASE_MASK (SR_MSG | SR_CD | SR_IO) |
191 | 185 | ||
@@ -205,16 +199,6 @@ | |||
205 | 199 | ||
206 | #define PHASE_SR_TO_TCR(phase) ((phase) >> 2) | 200 | #define PHASE_SR_TO_TCR(phase) ((phase) >> 2) |
207 | 201 | ||
208 | /* | ||
209 | * The internal should_disconnect() function returns these based on the | ||
210 | * expected length of a disconnect if a device supports disconnect/ | ||
211 | * reconnect. | ||
212 | */ | ||
213 | |||
214 | #define DISCONNECT_NONE 0 | ||
215 | #define DISCONNECT_TIME_TO_DATA 1 | ||
216 | #define DISCONNECT_LONG 2 | ||
217 | |||
218 | /* | 202 | /* |
219 | * "Special" value for the (unsigned char) command tag, to indicate | 203 | * "Special" value for the (unsigned char) command tag, to indicate |
220 | * I_T_L nexus instead of I_T_L_Q. | 204 | * I_T_L nexus instead of I_T_L_Q. |
@@ -236,15 +220,11 @@ | |||
236 | #define NO_IRQ 0 | 220 | #define NO_IRQ 0 |
237 | #endif | 221 | #endif |
238 | 222 | ||
239 | #define FLAG_HAS_LAST_BYTE_SENT 1 /* NCR53c81 or better */ | 223 | #define FLAG_NO_DMA_FIXUP 1 /* No DMA errata workarounds */ |
240 | #define FLAG_CHECK_LAST_BYTE_SENT 2 /* Only test once */ | ||
241 | #define FLAG_NCR53C400 4 /* NCR53c400 */ | ||
242 | #define FLAG_NO_PSEUDO_DMA 8 /* Inhibit DMA */ | 224 | #define FLAG_NO_PSEUDO_DMA 8 /* Inhibit DMA */ |
243 | #define FLAG_DTC3181E 16 /* DTC3181E */ | ||
244 | #define FLAG_LATE_DMA_SETUP 32 /* Setup NCR before DMA H/W */ | 225 | #define FLAG_LATE_DMA_SETUP 32 /* Setup NCR before DMA H/W */ |
245 | #define FLAG_TAGGED_QUEUING 64 /* as X3T9.2 spelled it */ | 226 | #define FLAG_TAGGED_QUEUING 64 /* as X3T9.2 spelled it */ |
246 | 227 | #define FLAG_TOSHIBA_DELAY 128 /* Allow for borken CD-ROMs */ | |
247 | #ifndef ASM | ||
248 | 228 | ||
249 | #ifdef SUPPORT_TAGS | 229 | #ifdef SUPPORT_TAGS |
250 | struct tag_alloc { | 230 | struct tag_alloc { |
@@ -258,33 +238,24 @@ struct NCR5380_hostdata { | |||
258 | NCR5380_implementation_fields; /* implementation specific */ | 238 | NCR5380_implementation_fields; /* implementation specific */ |
259 | struct Scsi_Host *host; /* Host backpointer */ | 239 | struct Scsi_Host *host; /* Host backpointer */ |
260 | unsigned char id_mask, id_higher_mask; /* 1 << id, all bits greater */ | 240 | unsigned char id_mask, id_higher_mask; /* 1 << id, all bits greater */ |
261 | unsigned char targets_present; /* targets we have connected | 241 | unsigned char busy[8]; /* index = target, bit = lun */ |
262 | to, so we can call a select | ||
263 | failure a retryable condition */ | ||
264 | volatile unsigned char busy[8]; /* index = target, bit = lun */ | ||
265 | #if defined(REAL_DMA) || defined(REAL_DMA_POLL) | 242 | #if defined(REAL_DMA) || defined(REAL_DMA_POLL) |
266 | volatile int dma_len; /* requested length of DMA */ | 243 | int dma_len; /* requested length of DMA */ |
267 | #endif | 244 | #endif |
268 | volatile unsigned char last_message; /* last message OUT */ | 245 | unsigned char last_message; /* last message OUT */ |
269 | volatile struct scsi_cmnd *connected; /* currently connected command */ | 246 | struct scsi_cmnd *connected; /* currently connected cmnd */ |
270 | volatile struct scsi_cmnd *issue_queue; /* waiting to be issued */ | 247 | struct scsi_cmnd *selecting; /* cmnd to be connected */ |
271 | volatile struct scsi_cmnd *disconnected_queue; /* waiting for reconnect */ | 248 | struct list_head unissued; /* waiting to be issued */ |
272 | volatile int restart_select; /* we have disconnected, | 249 | struct list_head autosense; /* priority issue queue */ |
273 | used to restart | 250 | struct list_head disconnected; /* waiting for reconnect */ |
274 | NCR5380_select() */ | 251 | spinlock_t lock; /* protects this struct */ |
275 | volatile unsigned aborted:1; /* flag, says aborted */ | ||
276 | int flags; | 252 | int flags; |
277 | unsigned long time_expires; /* in jiffies, set prior to sleeping */ | ||
278 | int select_time; /* timer in select for target response */ | ||
279 | volatile struct scsi_cmnd *selecting; | ||
280 | struct delayed_work coroutine; /* our co-routine */ | ||
281 | struct scsi_eh_save ses; | 253 | struct scsi_eh_save ses; |
254 | struct scsi_cmnd *sensing; | ||
282 | char info[256]; | 255 | char info[256]; |
283 | int read_overruns; /* number of bytes to cut from a | 256 | int read_overruns; /* number of bytes to cut from a |
284 | * transfer to handle chip overruns */ | 257 | * transfer to handle chip overruns */ |
285 | int retain_dma_intr; | ||
286 | struct work_struct main_task; | 258 | struct work_struct main_task; |
287 | volatile int main_running; | ||
288 | #ifdef SUPPORT_TAGS | 259 | #ifdef SUPPORT_TAGS |
289 | struct tag_alloc TagAlloc[8][8]; /* 8 targets and 8 LUNs */ | 260 | struct tag_alloc TagAlloc[8][8]; /* 8 targets and 8 LUNs */ |
290 | #endif | 261 | #endif |
@@ -292,10 +263,23 @@ struct NCR5380_hostdata { | |||
292 | unsigned spin_max_r; | 263 | unsigned spin_max_r; |
293 | unsigned spin_max_w; | 264 | unsigned spin_max_w; |
294 | #endif | 265 | #endif |
266 | struct workqueue_struct *work_q; | ||
267 | unsigned long accesses_per_ms; /* chip register accesses per ms */ | ||
295 | }; | 268 | }; |
296 | 269 | ||
297 | #ifdef __KERNEL__ | 270 | #ifdef __KERNEL__ |
298 | 271 | ||
272 | struct NCR5380_cmd { | ||
273 | struct list_head list; | ||
274 | }; | ||
275 | |||
276 | #define NCR5380_CMD_SIZE (sizeof(struct NCR5380_cmd)) | ||
277 | |||
278 | static inline struct scsi_cmnd *NCR5380_to_scmd(struct NCR5380_cmd *ncmd_ptr) | ||
279 | { | ||
280 | return ((struct scsi_cmnd *)ncmd_ptr) - 1; | ||
281 | } | ||
282 | |||
299 | #ifndef NDEBUG | 283 | #ifndef NDEBUG |
300 | #define NDEBUG (0) | 284 | #define NDEBUG (0) |
301 | #endif | 285 | #endif |
@@ -304,6 +288,11 @@ struct NCR5380_hostdata { | |||
304 | do { if ((NDEBUG) & (flg)) \ | 288 | do { if ((NDEBUG) & (flg)) \ |
305 | printk(KERN_DEBUG fmt, ## __VA_ARGS__); } while (0) | 289 | printk(KERN_DEBUG fmt, ## __VA_ARGS__); } while (0) |
306 | 290 | ||
291 | #define dsprintk(flg, host, fmt, ...) \ | ||
292 | do { if ((NDEBUG) & (flg)) \ | ||
293 | shost_printk(KERN_DEBUG, host, fmt, ## __VA_ARGS__); \ | ||
294 | } while (0) | ||
295 | |||
307 | #if NDEBUG | 296 | #if NDEBUG |
308 | #define NCR5380_dprint(flg, arg) \ | 297 | #define NCR5380_dprint(flg, arg) \ |
309 | do { if ((NDEBUG) & (flg)) NCR5380_print(arg); } while (0) | 298 | do { if ((NDEBUG) & (flg)) NCR5380_print(arg); } while (0) |
@@ -320,6 +309,7 @@ static void NCR5380_print(struct Scsi_Host *instance); | |||
320 | static int NCR5380_probe_irq(struct Scsi_Host *instance, int possible); | 309 | static int NCR5380_probe_irq(struct Scsi_Host *instance, int possible); |
321 | #endif | 310 | #endif |
322 | static int NCR5380_init(struct Scsi_Host *instance, int flags); | 311 | static int NCR5380_init(struct Scsi_Host *instance, int flags); |
312 | static int NCR5380_maybe_reset_bus(struct Scsi_Host *); | ||
323 | static void NCR5380_exit(struct Scsi_Host *instance); | 313 | static void NCR5380_exit(struct Scsi_Host *instance); |
324 | static void NCR5380_information_transfer(struct Scsi_Host *instance); | 314 | static void NCR5380_information_transfer(struct Scsi_Host *instance); |
325 | #ifndef DONT_USE_INTR | 315 | #ifndef DONT_USE_INTR |
@@ -328,7 +318,7 @@ static irqreturn_t NCR5380_intr(int irq, void *dev_id); | |||
328 | static void NCR5380_main(struct work_struct *work); | 318 | static void NCR5380_main(struct work_struct *work); |
329 | static const char *NCR5380_info(struct Scsi_Host *instance); | 319 | static const char *NCR5380_info(struct Scsi_Host *instance); |
330 | static void NCR5380_reselect(struct Scsi_Host *instance); | 320 | static void NCR5380_reselect(struct Scsi_Host *instance); |
331 | static int NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd); | 321 | static struct scsi_cmnd *NCR5380_select(struct Scsi_Host *, struct scsi_cmnd *); |
332 | #if defined(PSEUDO_DMA) || defined(REAL_DMA) || defined(REAL_DMA_POLL) | 322 | #if defined(PSEUDO_DMA) || defined(REAL_DMA) || defined(REAL_DMA_POLL) |
333 | static int NCR5380_transfer_dma(struct Scsi_Host *instance, unsigned char *phase, int *count, unsigned char **data); | 323 | static int NCR5380_transfer_dma(struct Scsi_Host *instance, unsigned char *phase, int *count, unsigned char **data); |
334 | #endif | 324 | #endif |
@@ -443,5 +433,4 @@ static __inline__ int NCR5380_pc_dma_residual(struct Scsi_Host *instance) | |||
443 | #endif /* defined(i386) || defined(__alpha__) */ | 433 | #endif /* defined(i386) || defined(__alpha__) */ |
444 | #endif /* defined(REAL_DMA) */ | 434 | #endif /* defined(REAL_DMA) */ |
445 | #endif /* __KERNEL__ */ | 435 | #endif /* __KERNEL__ */ |
446 | #endif /* ndef ASM */ | ||
447 | #endif /* NCR5380_H */ | 436 | #endif /* NCR5380_H */ |
diff --git a/drivers/scsi/arm/cumana_1.c b/drivers/scsi/arm/cumana_1.c index d28d6c0f18c0..221f18c5df93 100644 --- a/drivers/scsi/arm/cumana_1.c +++ b/drivers/scsi/arm/cumana_1.c | |||
@@ -4,9 +4,7 @@ | |||
4 | * Copyright 1995-2002, Russell King | 4 | * Copyright 1995-2002, Russell King |
5 | */ | 5 | */ |
6 | #include <linux/module.h> | 6 | #include <linux/module.h> |
7 | #include <linux/signal.h> | ||
8 | #include <linux/ioport.h> | 7 | #include <linux/ioport.h> |
9 | #include <linux/delay.h> | ||
10 | #include <linux/blkdev.h> | 8 | #include <linux/blkdev.h> |
11 | #include <linux/init.h> | 9 | #include <linux/init.h> |
12 | 10 | ||
@@ -15,15 +13,14 @@ | |||
15 | 13 | ||
16 | #include <scsi/scsi_host.h> | 14 | #include <scsi/scsi_host.h> |
17 | 15 | ||
18 | #include <scsi/scsicam.h> | ||
19 | |||
20 | #define PSEUDO_DMA | 16 | #define PSEUDO_DMA |
21 | 17 | ||
22 | #define priv(host) ((struct NCR5380_hostdata *)(host)->hostdata) | 18 | #define priv(host) ((struct NCR5380_hostdata *)(host)->hostdata) |
23 | #define NCR5380_local_declare() struct Scsi_Host *_instance | 19 | #define NCR5380_read(reg) cumanascsi_read(instance, reg) |
24 | #define NCR5380_setup(instance) _instance = instance | 20 | #define NCR5380_write(reg, value) cumanascsi_write(instance, reg, value) |
25 | #define NCR5380_read(reg) cumanascsi_read(_instance, reg) | 21 | |
26 | #define NCR5380_write(reg, value) cumanascsi_write(_instance, reg, value) | 22 | #define NCR5380_dma_xfer_len(instance, cmd, phase) (cmd->transfersize) |
23 | |||
27 | #define NCR5380_intr cumanascsi_intr | 24 | #define NCR5380_intr cumanascsi_intr |
28 | #define NCR5380_queue_command cumanascsi_queue_command | 25 | #define NCR5380_queue_command cumanascsi_queue_command |
29 | #define NCR5380_info cumanascsi_info | 26 | #define NCR5380_info cumanascsi_info |
@@ -211,6 +208,8 @@ static struct scsi_host_template cumanascsi_template = { | |||
211 | .cmd_per_lun = 2, | 208 | .cmd_per_lun = 2, |
212 | .use_clustering = DISABLE_CLUSTERING, | 209 | .use_clustering = DISABLE_CLUSTERING, |
213 | .proc_name = "CumanaSCSI-1", | 210 | .proc_name = "CumanaSCSI-1", |
211 | .cmd_size = NCR5380_CMD_SIZE, | ||
212 | .max_sectors = 128, | ||
214 | }; | 213 | }; |
215 | 214 | ||
216 | static int cumanascsi1_probe(struct expansion_card *ec, | 215 | static int cumanascsi1_probe(struct expansion_card *ec, |
@@ -240,23 +239,21 @@ static int cumanascsi1_probe(struct expansion_card *ec, | |||
240 | 239 | ||
241 | host->irq = ec->irq; | 240 | host->irq = ec->irq; |
242 | 241 | ||
243 | NCR5380_init(host, 0); | 242 | ret = NCR5380_init(host, 0); |
243 | if (ret) | ||
244 | goto out_unmap; | ||
245 | |||
246 | NCR5380_maybe_reset_bus(host); | ||
244 | 247 | ||
245 | priv(host)->ctrl = 0; | 248 | priv(host)->ctrl = 0; |
246 | writeb(0, priv(host)->base + CTRL); | 249 | writeb(0, priv(host)->base + CTRL); |
247 | 250 | ||
248 | host->n_io_port = 255; | ||
249 | if (!(request_region(host->io_port, host->n_io_port, "CumanaSCSI-1"))) { | ||
250 | ret = -EBUSY; | ||
251 | goto out_unmap; | ||
252 | } | ||
253 | |||
254 | ret = request_irq(host->irq, cumanascsi_intr, 0, | 251 | ret = request_irq(host->irq, cumanascsi_intr, 0, |
255 | "CumanaSCSI-1", host); | 252 | "CumanaSCSI-1", host); |
256 | if (ret) { | 253 | if (ret) { |
257 | printk("scsi%d: IRQ%d not free: %d\n", | 254 | printk("scsi%d: IRQ%d not free: %d\n", |
258 | host->host_no, host->irq, ret); | 255 | host->host_no, host->irq, ret); |
259 | goto out_unmap; | 256 | goto out_exit; |
260 | } | 257 | } |
261 | 258 | ||
262 | ret = scsi_add_host(host, &ec->dev); | 259 | ret = scsi_add_host(host, &ec->dev); |
@@ -268,6 +265,8 @@ static int cumanascsi1_probe(struct expansion_card *ec, | |||
268 | 265 | ||
269 | out_free_irq: | 266 | out_free_irq: |
270 | free_irq(host->irq, host); | 267 | free_irq(host->irq, host); |
268 | out_exit: | ||
269 | NCR5380_exit(host); | ||
271 | out_unmap: | 270 | out_unmap: |
272 | iounmap(priv(host)->base); | 271 | iounmap(priv(host)->base); |
273 | iounmap(priv(host)->dma); | 272 | iounmap(priv(host)->dma); |
diff --git a/drivers/scsi/arm/oak.c b/drivers/scsi/arm/oak.c index 7c6fa1479c9c..1fab1d1896b1 100644 --- a/drivers/scsi/arm/oak.c +++ b/drivers/scsi/arm/oak.c | |||
@@ -5,9 +5,7 @@ | |||
5 | */ | 5 | */ |
6 | 6 | ||
7 | #include <linux/module.h> | 7 | #include <linux/module.h> |
8 | #include <linux/signal.h> | ||
9 | #include <linux/ioport.h> | 8 | #include <linux/ioport.h> |
10 | #include <linux/delay.h> | ||
11 | #include <linux/blkdev.h> | 9 | #include <linux/blkdev.h> |
12 | #include <linux/init.h> | 10 | #include <linux/init.h> |
13 | 11 | ||
@@ -20,14 +18,16 @@ | |||
20 | #define DONT_USE_INTR | 18 | #define DONT_USE_INTR |
21 | 19 | ||
22 | #define priv(host) ((struct NCR5380_hostdata *)(host)->hostdata) | 20 | #define priv(host) ((struct NCR5380_hostdata *)(host)->hostdata) |
23 | #define NCR5380_local_declare() void __iomem *_base | ||
24 | #define NCR5380_setup(host) _base = priv(host)->base | ||
25 | 21 | ||
26 | #define NCR5380_read(reg) readb(_base + ((reg) << 2)) | 22 | #define NCR5380_read(reg) \ |
27 | #define NCR5380_write(reg, value) writeb(value, _base + ((reg) << 2)) | 23 | readb(priv(instance)->base + ((reg) << 2)) |
24 | #define NCR5380_write(reg, value) \ | ||
25 | writeb(value, priv(instance)->base + ((reg) << 2)) | ||
26 | |||
27 | #define NCR5380_dma_xfer_len(instance, cmd, phase) (cmd->transfersize) | ||
28 | |||
28 | #define NCR5380_queue_command oakscsi_queue_command | 29 | #define NCR5380_queue_command oakscsi_queue_command |
29 | #define NCR5380_info oakscsi_info | 30 | #define NCR5380_info oakscsi_info |
30 | #define NCR5380_show_info oakscsi_show_info | ||
31 | 31 | ||
32 | #define NCR5380_implementation_fields \ | 32 | #define NCR5380_implementation_fields \ |
33 | void __iomem *base | 33 | void __iomem *base |
@@ -103,7 +103,6 @@ printk("reading %p len %d\n", addr, len); | |||
103 | 103 | ||
104 | static struct scsi_host_template oakscsi_template = { | 104 | static struct scsi_host_template oakscsi_template = { |
105 | .module = THIS_MODULE, | 105 | .module = THIS_MODULE, |
106 | .show_info = oakscsi_show_info, | ||
107 | .name = "Oak 16-bit SCSI", | 106 | .name = "Oak 16-bit SCSI", |
108 | .info = oakscsi_info, | 107 | .info = oakscsi_info, |
109 | .queuecommand = oakscsi_queue_command, | 108 | .queuecommand = oakscsi_queue_command, |
@@ -115,6 +114,8 @@ static struct scsi_host_template oakscsi_template = { | |||
115 | .cmd_per_lun = 2, | 114 | .cmd_per_lun = 2, |
116 | .use_clustering = DISABLE_CLUSTERING, | 115 | .use_clustering = DISABLE_CLUSTERING, |
117 | .proc_name = "oakscsi", | 116 | .proc_name = "oakscsi", |
117 | .cmd_size = NCR5380_CMD_SIZE, | ||
118 | .max_sectors = 128, | ||
118 | }; | 119 | }; |
119 | 120 | ||
120 | static int oakscsi_probe(struct expansion_card *ec, const struct ecard_id *id) | 121 | static int oakscsi_probe(struct expansion_card *ec, const struct ecard_id *id) |
@@ -142,15 +143,21 @@ static int oakscsi_probe(struct expansion_card *ec, const struct ecard_id *id) | |||
142 | host->irq = NO_IRQ; | 143 | host->irq = NO_IRQ; |
143 | host->n_io_port = 255; | 144 | host->n_io_port = 255; |
144 | 145 | ||
145 | NCR5380_init(host, 0); | 146 | ret = NCR5380_init(host, 0); |
147 | if (ret) | ||
148 | goto out_unmap; | ||
149 | |||
150 | NCR5380_maybe_reset_bus(host); | ||
146 | 151 | ||
147 | ret = scsi_add_host(host, &ec->dev); | 152 | ret = scsi_add_host(host, &ec->dev); |
148 | if (ret) | 153 | if (ret) |
149 | goto out_unmap; | 154 | goto out_exit; |
150 | 155 | ||
151 | scsi_scan_host(host); | 156 | scsi_scan_host(host); |
152 | goto out; | 157 | goto out; |
153 | 158 | ||
159 | out_exit: | ||
160 | NCR5380_exit(host); | ||
154 | out_unmap: | 161 | out_unmap: |
155 | iounmap(priv(host)->base); | 162 | iounmap(priv(host)->base); |
156 | unreg: | 163 | unreg: |
diff --git a/drivers/scsi/atari_NCR5380.c b/drivers/scsi/atari_NCR5380.c index db87ece6edb2..e65478651ca9 100644 --- a/drivers/scsi/atari_NCR5380.c +++ b/drivers/scsi/atari_NCR5380.c | |||
@@ -1,15 +1,15 @@ | |||
1 | /* | 1 | /* |
2 | * NCR 5380 generic driver routines. These should make it *trivial* | 2 | * NCR 5380 generic driver routines. These should make it *trivial* |
3 | * to implement 5380 SCSI drivers under Linux with a non-trantor | 3 | * to implement 5380 SCSI drivers under Linux with a non-trantor |
4 | * architecture. | 4 | * architecture. |
5 | * | 5 | * |
6 | * Note that these routines also work with NR53c400 family chips. | 6 | * Note that these routines also work with NR53c400 family chips. |
7 | * | 7 | * |
8 | * Copyright 1993, Drew Eckhardt | 8 | * Copyright 1993, Drew Eckhardt |
9 | * Visionary Computing | 9 | * Visionary Computing |
10 | * (Unix and Linux consulting and custom programming) | 10 | * (Unix and Linux consulting and custom programming) |
11 | * drew@colorado.edu | 11 | * drew@colorado.edu |
12 | * +1 (303) 666-5836 | 12 | * +1 (303) 666-5836 |
13 | * | 13 | * |
14 | * For more information, please consult | 14 | * For more information, please consult |
15 | * | 15 | * |
@@ -24,84 +24,10 @@ | |||
24 | * 1+ (800) 334-5454 | 24 | * 1+ (800) 334-5454 |
25 | */ | 25 | */ |
26 | 26 | ||
27 | /* | 27 | /* Ported to Atari by Roman Hodek and others. */ |
28 | * ++roman: To port the 5380 driver to the Atari, I had to do some changes in | ||
29 | * this file, too: | ||
30 | * | ||
31 | * - Some of the debug statements were incorrect (undefined variables and the | ||
32 | * like). I fixed that. | ||
33 | * | ||
34 | * - In information_transfer(), I think a #ifdef was wrong. Looking at the | ||
35 | * possible DMA transfer size should also happen for REAL_DMA. I added this | ||
36 | * in the #if statement. | ||
37 | * | ||
38 | * - When using real DMA, information_transfer() should return in a DATAOUT | ||
39 | * phase after starting the DMA. It has nothing more to do. | ||
40 | * | ||
41 | * - The interrupt service routine should run main after end of DMA, too (not | ||
42 | * only after RESELECTION interrupts). Additionally, it should _not_ test | ||
43 | * for more interrupts after running main, since a DMA process may have | ||
44 | * been started and interrupts are turned on now. The new int could happen | ||
45 | * inside the execution of NCR5380_intr(), leading to recursive | ||
46 | * calls. | ||
47 | * | ||
48 | * - I've added a function merge_contiguous_buffers() that tries to | ||
49 | * merge scatter-gather buffers that are located at contiguous | ||
50 | * physical addresses and can be processed with the same DMA setup. | ||
51 | * Since most scatter-gather operations work on a page (4K) of | ||
52 | * 4 buffers (1K), in more than 90% of all cases three interrupts and | ||
53 | * DMA setup actions are saved. | ||
54 | * | ||
55 | * - I've deleted all the stuff for AUTOPROBE_IRQ, REAL_DMA_POLL, PSEUDO_DMA | ||
56 | * and USLEEP, because these were messing up readability and will never be | ||
57 | * needed for Atari SCSI. | ||
58 | * | ||
59 | * - I've revised the NCR5380_main() calling scheme (relax the 'main_running' | ||
60 | * stuff), and 'main' is executed in a bottom half if awoken by an | ||
61 | * interrupt. | ||
62 | * | ||
63 | * - The code was quite cluttered up by "#if (NDEBUG & NDEBUG_*) printk..." | ||
64 | * constructs. In my eyes, this made the source rather unreadable, so I | ||
65 | * finally replaced that by the *_PRINTK() macros. | ||
66 | * | ||
67 | */ | ||
68 | |||
69 | /* | ||
70 | * Further development / testing that should be done : | ||
71 | * 1. Test linked command handling code after Eric is ready with | ||
72 | * the high level code. | ||
73 | */ | ||
74 | 28 | ||
75 | /* Adapted for the sun3 by Sam Creasey. */ | 29 | /* Adapted for the sun3 by Sam Creasey. */ |
76 | 30 | ||
77 | #include <scsi/scsi_dbg.h> | ||
78 | #include <scsi/scsi_transport_spi.h> | ||
79 | |||
80 | #if (NDEBUG & NDEBUG_LISTS) | ||
81 | #define LIST(x, y) \ | ||
82 | do { \ | ||
83 | printk("LINE:%d Adding %p to %p\n", \ | ||
84 | __LINE__, (void*)(x), (void*)(y)); \ | ||
85 | if ((x) == (y)) \ | ||
86 | udelay(5); \ | ||
87 | } while (0) | ||
88 | #define REMOVE(w, x, y, z) \ | ||
89 | do { \ | ||
90 | printk("LINE:%d Removing: %p->%p %p->%p \n", \ | ||
91 | __LINE__, (void*)(w), (void*)(x), \ | ||
92 | (void*)(y), (void*)(z)); \ | ||
93 | if ((x) == (y)) \ | ||
94 | udelay(5); \ | ||
95 | } while (0) | ||
96 | #else | ||
97 | #define LIST(x,y) | ||
98 | #define REMOVE(w,x,y,z) | ||
99 | #endif | ||
100 | |||
101 | #ifndef notyet | ||
102 | #undef LINKED | ||
103 | #endif | ||
104 | |||
105 | /* | 31 | /* |
106 | * Design | 32 | * Design |
107 | * | 33 | * |
@@ -126,17 +52,7 @@ | |||
126 | * piece of hardware that requires you to sit in a loop polling for | 52 | * piece of hardware that requires you to sit in a loop polling for |
127 | * the REQ signal as long as you are connected. Some devices are | 53 | * the REQ signal as long as you are connected. Some devices are |
128 | * brain dead (ie, many TEXEL CD ROM drives) and won't disconnect | 54 | * brain dead (ie, many TEXEL CD ROM drives) and won't disconnect |
129 | * while doing long seek operations. | 55 | * while doing long seek operations. [...] These |
130 | * | ||
131 | * The workaround for this is to keep track of devices that have | ||
132 | * disconnected. If the device hasn't disconnected, for commands that | ||
133 | * should disconnect, we do something like | ||
134 | * | ||
135 | * while (!REQ is asserted) { sleep for N usecs; poll for M usecs } | ||
136 | * | ||
137 | * Some tweaking of N and M needs to be done. An algorithm based | ||
138 | * on "time to data" would give the best results as long as short time | ||
139 | * to datas (ie, on the same track) were considered, however these | ||
140 | * broken devices are the exception rather than the rule and I'd rather | 56 | * broken devices are the exception rather than the rule and I'd rather |
141 | * spend my time optimizing for the normal case. | 57 | * spend my time optimizing for the normal case. |
142 | * | 58 | * |
@@ -177,12 +93,10 @@ | |||
177 | * | 93 | * |
178 | * These macros control options : | 94 | * These macros control options : |
179 | * AUTOSENSE - if defined, REQUEST SENSE will be performed automatically | 95 | * AUTOSENSE - if defined, REQUEST SENSE will be performed automatically |
180 | * for commands that return with a CHECK CONDITION status. | 96 | * for commands that return with a CHECK CONDITION status. |
181 | * | 97 | * |
182 | * DIFFERENTIAL - if defined, NCR53c81 chips will use external differential | 98 | * DIFFERENTIAL - if defined, NCR53c81 chips will use external differential |
183 | * transceivers. | 99 | * transceivers. |
184 | * | ||
185 | * LINKED - if defined, linked commands are supported. | ||
186 | * | 100 | * |
187 | * REAL_DMA - if defined, REAL DMA is used during the data transfer phases. | 101 | * REAL_DMA - if defined, REAL DMA is used during the data transfer phases. |
188 | * | 102 | * |
@@ -195,17 +109,17 @@ | |||
195 | * NCR5380_write(register, value) - write to the specific register | 109 | * NCR5380_write(register, value) - write to the specific register |
196 | * | 110 | * |
197 | * NCR5380_implementation_fields - additional fields needed for this | 111 | * NCR5380_implementation_fields - additional fields needed for this |
198 | * specific implementation of the NCR5380 | 112 | * specific implementation of the NCR5380 |
199 | * | 113 | * |
200 | * Either real DMA *or* pseudo DMA may be implemented | 114 | * Either real DMA *or* pseudo DMA may be implemented |
201 | * REAL functions : | 115 | * REAL functions : |
202 | * NCR5380_REAL_DMA should be defined if real DMA is to be used. | 116 | * NCR5380_REAL_DMA should be defined if real DMA is to be used. |
203 | * Note that the DMA setup functions should return the number of bytes | 117 | * Note that the DMA setup functions should return the number of bytes |
204 | * that they were able to program the controller for. | 118 | * that they were able to program the controller for. |
205 | * | 119 | * |
206 | * Also note that generic i386/PC versions of these macros are | 120 | * Also note that generic i386/PC versions of these macros are |
207 | * available as NCR5380_i386_dma_write_setup, | 121 | * available as NCR5380_i386_dma_write_setup, |
208 | * NCR5380_i386_dma_read_setup, and NCR5380_i386_dma_residual. | 122 | * NCR5380_i386_dma_read_setup, and NCR5380_i386_dma_residual. |
209 | * | 123 | * |
210 | * NCR5380_dma_write_setup(instance, src, count) - initialize | 124 | * NCR5380_dma_write_setup(instance, src, count) - initialize |
211 | * NCR5380_dma_read_setup(instance, dst, count) - initialize | 125 | * NCR5380_dma_read_setup(instance, dst, count) - initialize |
@@ -221,18 +135,8 @@ | |||
221 | * possible) function may be used. | 135 | * possible) function may be used. |
222 | */ | 136 | */ |
223 | 137 | ||
224 | /* Macros ease life... :-) */ | 138 | static int do_abort(struct Scsi_Host *); |
225 | #define SETUP_HOSTDATA(in) \ | 139 | static void do_reset(struct Scsi_Host *); |
226 | struct NCR5380_hostdata *hostdata = \ | ||
227 | (struct NCR5380_hostdata *)(in)->hostdata | ||
228 | #define HOSTDATA(in) ((struct NCR5380_hostdata *)(in)->hostdata) | ||
229 | |||
230 | #define NEXT(cmd) ((struct scsi_cmnd *)(cmd)->host_scribble) | ||
231 | #define SET_NEXT(cmd,next) ((cmd)->host_scribble = (void *)(next)) | ||
232 | #define NEXTADDR(cmd) ((struct scsi_cmnd **)&(cmd)->host_scribble) | ||
233 | |||
234 | #define HOSTNO instance->host_no | ||
235 | #define H_NO(cmd) (cmd)->device->host->host_no | ||
236 | 140 | ||
237 | #ifdef SUPPORT_TAGS | 141 | #ifdef SUPPORT_TAGS |
238 | 142 | ||
@@ -251,9 +155,7 @@ | |||
251 | * cannot know it in advance :-( We just see a QUEUE_FULL status being | 155 | * cannot know it in advance :-( We just see a QUEUE_FULL status being |
252 | * returned. So, in this case, the driver internal queue size assumption is | 156 | * returned. So, in this case, the driver internal queue size assumption is |
253 | * reduced to the number of active tags if QUEUE_FULL is returned by the | 157 | * reduced to the number of active tags if QUEUE_FULL is returned by the |
254 | * target. The command is returned to the mid-level, but with status changed | 158 | * target. |
255 | * to BUSY, since --as I've seen-- the mid-level can't handle QUEUE_FULL | ||
256 | * correctly. | ||
257 | * | 159 | * |
258 | * We're also not allowed running tagged commands as long as an untagged | 160 | * We're also not allowed running tagged commands as long as an untagged |
259 | * command is active. And REQUEST SENSE commands after a contingent allegiance | 161 | * command is active. And REQUEST SENSE commands after a contingent allegiance |
@@ -304,7 +206,8 @@ static void __init init_tags(struct NCR5380_hostdata *hostdata) | |||
304 | static int is_lun_busy(struct scsi_cmnd *cmd, int should_be_tagged) | 206 | static int is_lun_busy(struct scsi_cmnd *cmd, int should_be_tagged) |
305 | { | 207 | { |
306 | u8 lun = cmd->device->lun; | 208 | u8 lun = cmd->device->lun; |
307 | SETUP_HOSTDATA(cmd->device->host); | 209 | struct Scsi_Host *instance = cmd->device->host; |
210 | struct NCR5380_hostdata *hostdata = shost_priv(instance); | ||
308 | 211 | ||
309 | if (hostdata->busy[cmd->device->id] & (1 << lun)) | 212 | if (hostdata->busy[cmd->device->id] & (1 << lun)) |
310 | return 1; | 213 | return 1; |
@@ -314,8 +217,8 @@ static int is_lun_busy(struct scsi_cmnd *cmd, int should_be_tagged) | |||
314 | return 0; | 217 | return 0; |
315 | if (hostdata->TagAlloc[scmd_id(cmd)][lun].nr_allocated >= | 218 | if (hostdata->TagAlloc[scmd_id(cmd)][lun].nr_allocated >= |
316 | hostdata->TagAlloc[scmd_id(cmd)][lun].queue_size) { | 219 | hostdata->TagAlloc[scmd_id(cmd)][lun].queue_size) { |
317 | dprintk(NDEBUG_TAGS, "scsi%d: target %d lun %d: no free tags\n", | 220 | dsprintk(NDEBUG_TAGS, instance, "target %d lun %d: no free tags\n", |
318 | H_NO(cmd), cmd->device->id, lun); | 221 | scmd_id(cmd), lun); |
319 | return 1; | 222 | return 1; |
320 | } | 223 | } |
321 | return 0; | 224 | return 0; |
@@ -330,7 +233,8 @@ static int is_lun_busy(struct scsi_cmnd *cmd, int should_be_tagged) | |||
330 | static void cmd_get_tag(struct scsi_cmnd *cmd, int should_be_tagged) | 233 | static void cmd_get_tag(struct scsi_cmnd *cmd, int should_be_tagged) |
331 | { | 234 | { |
332 | u8 lun = cmd->device->lun; | 235 | u8 lun = cmd->device->lun; |
333 | SETUP_HOSTDATA(cmd->device->host); | 236 | struct Scsi_Host *instance = cmd->device->host; |
237 | struct NCR5380_hostdata *hostdata = shost_priv(instance); | ||
334 | 238 | ||
335 | /* If we or the target don't support tagged queuing, allocate the LUN for | 239 | /* If we or the target don't support tagged queuing, allocate the LUN for |
336 | * an untagged command. | 240 | * an untagged command. |
@@ -340,18 +244,16 @@ static void cmd_get_tag(struct scsi_cmnd *cmd, int should_be_tagged) | |||
340 | !cmd->device->tagged_supported) { | 244 | !cmd->device->tagged_supported) { |
341 | cmd->tag = TAG_NONE; | 245 | cmd->tag = TAG_NONE; |
342 | hostdata->busy[cmd->device->id] |= (1 << lun); | 246 | hostdata->busy[cmd->device->id] |= (1 << lun); |
343 | dprintk(NDEBUG_TAGS, "scsi%d: target %d lun %d now allocated by untagged " | 247 | dsprintk(NDEBUG_TAGS, instance, "target %d lun %d now allocated by untagged command\n", |
344 | "command\n", H_NO(cmd), cmd->device->id, lun); | 248 | scmd_id(cmd), lun); |
345 | } else { | 249 | } else { |
346 | struct tag_alloc *ta = &hostdata->TagAlloc[scmd_id(cmd)][lun]; | 250 | struct tag_alloc *ta = &hostdata->TagAlloc[scmd_id(cmd)][lun]; |
347 | 251 | ||
348 | cmd->tag = find_first_zero_bit(ta->allocated, MAX_TAGS); | 252 | cmd->tag = find_first_zero_bit(ta->allocated, MAX_TAGS); |
349 | set_bit(cmd->tag, ta->allocated); | 253 | set_bit(cmd->tag, ta->allocated); |
350 | ta->nr_allocated++; | 254 | ta->nr_allocated++; |
351 | dprintk(NDEBUG_TAGS, "scsi%d: using tag %d for target %d lun %d " | 255 | dsprintk(NDEBUG_TAGS, instance, "using tag %d for target %d lun %d (%d tags allocated)\n", |
352 | "(now %d tags in use)\n", | 256 | cmd->tag, scmd_id(cmd), lun, ta->nr_allocated); |
353 | H_NO(cmd), cmd->tag, cmd->device->id, | ||
354 | lun, ta->nr_allocated); | ||
355 | } | 257 | } |
356 | } | 258 | } |
357 | 259 | ||
@@ -363,21 +265,22 @@ static void cmd_get_tag(struct scsi_cmnd *cmd, int should_be_tagged) | |||
363 | static void cmd_free_tag(struct scsi_cmnd *cmd) | 265 | static void cmd_free_tag(struct scsi_cmnd *cmd) |
364 | { | 266 | { |
365 | u8 lun = cmd->device->lun; | 267 | u8 lun = cmd->device->lun; |
366 | SETUP_HOSTDATA(cmd->device->host); | 268 | struct Scsi_Host *instance = cmd->device->host; |
269 | struct NCR5380_hostdata *hostdata = shost_priv(instance); | ||
367 | 270 | ||
368 | if (cmd->tag == TAG_NONE) { | 271 | if (cmd->tag == TAG_NONE) { |
369 | hostdata->busy[cmd->device->id] &= ~(1 << lun); | 272 | hostdata->busy[cmd->device->id] &= ~(1 << lun); |
370 | dprintk(NDEBUG_TAGS, "scsi%d: target %d lun %d untagged cmd finished\n", | 273 | dsprintk(NDEBUG_TAGS, instance, "target %d lun %d untagged cmd freed\n", |
371 | H_NO(cmd), cmd->device->id, lun); | 274 | scmd_id(cmd), lun); |
372 | } else if (cmd->tag >= MAX_TAGS) { | 275 | } else if (cmd->tag >= MAX_TAGS) { |
373 | printk(KERN_NOTICE "scsi%d: trying to free bad tag %d!\n", | 276 | shost_printk(KERN_NOTICE, instance, |
374 | H_NO(cmd), cmd->tag); | 277 | "trying to free bad tag %d!\n", cmd->tag); |
375 | } else { | 278 | } else { |
376 | struct tag_alloc *ta = &hostdata->TagAlloc[scmd_id(cmd)][lun]; | 279 | struct tag_alloc *ta = &hostdata->TagAlloc[scmd_id(cmd)][lun]; |
377 | clear_bit(cmd->tag, ta->allocated); | 280 | clear_bit(cmd->tag, ta->allocated); |
378 | ta->nr_allocated--; | 281 | ta->nr_allocated--; |
379 | dprintk(NDEBUG_TAGS, "scsi%d: freed tag %d for target %d lun %d\n", | 282 | dsprintk(NDEBUG_TAGS, instance, "freed tag %d for target %d lun %d\n", |
380 | H_NO(cmd), cmd->tag, cmd->device->id, lun); | 283 | cmd->tag, scmd_id(cmd), lun); |
381 | } | 284 | } |
382 | } | 285 | } |
383 | 286 | ||
@@ -401,17 +304,15 @@ static void free_all_tags(struct NCR5380_hostdata *hostdata) | |||
401 | 304 | ||
402 | #endif /* SUPPORT_TAGS */ | 305 | #endif /* SUPPORT_TAGS */ |
403 | 306 | ||
404 | 307 | /** | |
405 | /* | 308 | * merge_contiguous_buffers - coalesce scatter-gather list entries |
406 | * Function: void merge_contiguous_buffers( struct scsi_cmnd *cmd ) | 309 | * @cmd: command requesting IO |
407 | * | 310 | * |
408 | * Purpose: Try to merge several scatter-gather requests into one DMA | 311 | * Try to merge several scatter-gather buffers into one DMA transfer. |
409 | * transfer. This is possible if the scatter buffers lie on | 312 | * This is possible if the scatter buffers lie on physically |
410 | * physical contiguous addresses. | 313 | * contiguous addresses. The first scatter-gather buffer's data are |
411 | * | 314 | * assumed to be already transferred into cmd->SCp.this_residual. |
412 | * Parameters: struct scsi_cmnd *cmd | 315 | * Every buffer merged avoids an interrupt and a DMA setup operation. |
413 | * The command to work on. The first scatter buffer's data are | ||
414 | * assumed to be already transferred into ptr/this_residual. | ||
415 | */ | 316 | */ |
416 | 317 | ||
417 | static void merge_contiguous_buffers(struct scsi_cmnd *cmd) | 318 | static void merge_contiguous_buffers(struct scsi_cmnd *cmd) |
@@ -463,9 +364,7 @@ static inline void initialize_SCp(struct scsi_cmnd *cmd) | |||
463 | cmd->SCp.buffers_residual = scsi_sg_count(cmd) - 1; | 364 | cmd->SCp.buffers_residual = scsi_sg_count(cmd) - 1; |
464 | cmd->SCp.ptr = sg_virt(cmd->SCp.buffer); | 365 | cmd->SCp.ptr = sg_virt(cmd->SCp.buffer); |
465 | cmd->SCp.this_residual = cmd->SCp.buffer->length; | 366 | cmd->SCp.this_residual = cmd->SCp.buffer->length; |
466 | /* ++roman: Try to merge some scatter-buffers if they are at | 367 | |
467 | * contiguous physical addresses. | ||
468 | */ | ||
469 | merge_contiguous_buffers(cmd); | 368 | merge_contiguous_buffers(cmd); |
470 | } else { | 369 | } else { |
471 | cmd->SCp.buffer = NULL; | 370 | cmd->SCp.buffer = NULL; |
@@ -473,31 +372,110 @@ static inline void initialize_SCp(struct scsi_cmnd *cmd) | |||
473 | cmd->SCp.ptr = NULL; | 372 | cmd->SCp.ptr = NULL; |
474 | cmd->SCp.this_residual = 0; | 373 | cmd->SCp.this_residual = 0; |
475 | } | 374 | } |
375 | |||
376 | cmd->SCp.Status = 0; | ||
377 | cmd->SCp.Message = 0; | ||
378 | } | ||
379 | |||
380 | /** | ||
381 | * NCR5380_poll_politely2 - wait for two chip register values | ||
382 | * @instance: controller to poll | ||
383 | * @reg1: 5380 register to poll | ||
384 | * @bit1: Bitmask to check | ||
385 | * @val1: Expected value | ||
386 | * @reg2: Second 5380 register to poll | ||
387 | * @bit2: Second bitmask to check | ||
388 | * @val2: Second expected value | ||
389 | * @wait: Time-out in jiffies | ||
390 | * | ||
391 | * Polls the chip in a reasonably efficient manner waiting for an | ||
392 | * event to occur. After a short quick poll we begin to yield the CPU | ||
393 | * (if possible). In irq contexts the time-out is arbitrarily limited. | ||
394 | * Callers may hold locks as long as they are held in irq mode. | ||
395 | * | ||
396 | * Returns 0 if either or both event(s) occurred otherwise -ETIMEDOUT. | ||
397 | */ | ||
398 | |||
399 | static int NCR5380_poll_politely2(struct Scsi_Host *instance, | ||
400 | int reg1, int bit1, int val1, | ||
401 | int reg2, int bit2, int val2, int wait) | ||
402 | { | ||
403 | struct NCR5380_hostdata *hostdata = shost_priv(instance); | ||
404 | unsigned long deadline = jiffies + wait; | ||
405 | unsigned long n; | ||
406 | |||
407 | /* Busy-wait for up to 10 ms */ | ||
408 | n = min(10000U, jiffies_to_usecs(wait)); | ||
409 | n *= hostdata->accesses_per_ms; | ||
410 | n /= 2000; | ||
411 | do { | ||
412 | if ((NCR5380_read(reg1) & bit1) == val1) | ||
413 | return 0; | ||
414 | if ((NCR5380_read(reg2) & bit2) == val2) | ||
415 | return 0; | ||
416 | cpu_relax(); | ||
417 | } while (n--); | ||
418 | |||
419 | if (irqs_disabled() || in_interrupt()) | ||
420 | return -ETIMEDOUT; | ||
421 | |||
422 | /* Repeatedly sleep for 1 ms until deadline */ | ||
423 | while (time_is_after_jiffies(deadline)) { | ||
424 | schedule_timeout_uninterruptible(1); | ||
425 | if ((NCR5380_read(reg1) & bit1) == val1) | ||
426 | return 0; | ||
427 | if ((NCR5380_read(reg2) & bit2) == val2) | ||
428 | return 0; | ||
429 | } | ||
430 | |||
431 | return -ETIMEDOUT; | ||
476 | } | 432 | } |
477 | 433 | ||
478 | #include <linux/delay.h> | 434 | static inline int NCR5380_poll_politely(struct Scsi_Host *instance, |
435 | int reg, int bit, int val, int wait) | ||
436 | { | ||
437 | return NCR5380_poll_politely2(instance, reg, bit, val, | ||
438 | reg, bit, val, wait); | ||
439 | } | ||
479 | 440 | ||
480 | #if NDEBUG | 441 | #if NDEBUG |
481 | static struct { | 442 | static struct { |
482 | unsigned char mask; | 443 | unsigned char mask; |
483 | const char *name; | 444 | const char *name; |
484 | } signals[] = { | 445 | } signals[] = { |
485 | { SR_DBP, "PARITY"}, { SR_RST, "RST" }, { SR_BSY, "BSY" }, | 446 | {SR_DBP, "PARITY"}, |
486 | { SR_REQ, "REQ" }, { SR_MSG, "MSG" }, { SR_CD, "CD" }, { SR_IO, "IO" }, | 447 | {SR_RST, "RST"}, |
487 | { SR_SEL, "SEL" }, {0, NULL} | 448 | {SR_BSY, "BSY"}, |
488 | }, basrs[] = { | 449 | {SR_REQ, "REQ"}, |
489 | {BASR_ATN, "ATN"}, {BASR_ACK, "ACK"}, {0, NULL} | 450 | {SR_MSG, "MSG"}, |
490 | }, icrs[] = { | 451 | {SR_CD, "CD"}, |
491 | {ICR_ASSERT_RST, "ASSERT RST"},{ICR_ASSERT_ACK, "ASSERT ACK"}, | 452 | {SR_IO, "IO"}, |
492 | {ICR_ASSERT_BSY, "ASSERT BSY"}, {ICR_ASSERT_SEL, "ASSERT SEL"}, | 453 | {SR_SEL, "SEL"}, |
493 | {ICR_ASSERT_ATN, "ASSERT ATN"}, {ICR_ASSERT_DATA, "ASSERT DATA"}, | 454 | {0, NULL} |
455 | }, | ||
456 | basrs[] = { | ||
457 | {BASR_ATN, "ATN"}, | ||
458 | {BASR_ACK, "ACK"}, | ||
494 | {0, NULL} | 459 | {0, NULL} |
495 | }, mrs[] = { | 460 | }, |
496 | {MR_BLOCK_DMA_MODE, "MODE BLOCK DMA"}, {MR_TARGET, "MODE TARGET"}, | 461 | icrs[] = { |
497 | {MR_ENABLE_PAR_CHECK, "MODE PARITY CHECK"}, {MR_ENABLE_PAR_INTR, | 462 | {ICR_ASSERT_RST, "ASSERT RST"}, |
498 | "MODE PARITY INTR"}, {MR_ENABLE_EOP_INTR,"MODE EOP INTR"}, | 463 | {ICR_ASSERT_ACK, "ASSERT ACK"}, |
464 | {ICR_ASSERT_BSY, "ASSERT BSY"}, | ||
465 | {ICR_ASSERT_SEL, "ASSERT SEL"}, | ||
466 | {ICR_ASSERT_ATN, "ASSERT ATN"}, | ||
467 | {ICR_ASSERT_DATA, "ASSERT DATA"}, | ||
468 | {0, NULL} | ||
469 | }, | ||
470 | mrs[] = { | ||
471 | {MR_BLOCK_DMA_MODE, "MODE BLOCK DMA"}, | ||
472 | {MR_TARGET, "MODE TARGET"}, | ||
473 | {MR_ENABLE_PAR_CHECK, "MODE PARITY CHECK"}, | ||
474 | {MR_ENABLE_PAR_INTR, "MODE PARITY INTR"}, | ||
475 | {MR_ENABLE_EOP_INTR, "MODE EOP INTR"}, | ||
499 | {MR_MONITOR_BSY, "MODE MONITOR BSY"}, | 476 | {MR_MONITOR_BSY, "MODE MONITOR BSY"}, |
500 | {MR_DMA_MODE, "MODE DMA"}, {MR_ARBITRATE, "MODE ARBITRATION"}, | 477 | {MR_DMA_MODE, "MODE DMA"}, |
478 | {MR_ARBITRATE, "MODE ARBITRATION"}, | ||
501 | {0, NULL} | 479 | {0, NULL} |
502 | }; | 480 | }; |
503 | 481 | ||
@@ -511,15 +489,13 @@ static struct { | |||
511 | static void NCR5380_print(struct Scsi_Host *instance) | 489 | static void NCR5380_print(struct Scsi_Host *instance) |
512 | { | 490 | { |
513 | unsigned char status, data, basr, mr, icr, i; | 491 | unsigned char status, data, basr, mr, icr, i; |
514 | unsigned long flags; | ||
515 | 492 | ||
516 | local_irq_save(flags); | ||
517 | data = NCR5380_read(CURRENT_SCSI_DATA_REG); | 493 | data = NCR5380_read(CURRENT_SCSI_DATA_REG); |
518 | status = NCR5380_read(STATUS_REG); | 494 | status = NCR5380_read(STATUS_REG); |
519 | mr = NCR5380_read(MODE_REG); | 495 | mr = NCR5380_read(MODE_REG); |
520 | icr = NCR5380_read(INITIATOR_COMMAND_REG); | 496 | icr = NCR5380_read(INITIATOR_COMMAND_REG); |
521 | basr = NCR5380_read(BUS_AND_STATUS_REG); | 497 | basr = NCR5380_read(BUS_AND_STATUS_REG); |
522 | local_irq_restore(flags); | 498 | |
523 | printk("STATUS_REG: %02x ", status); | 499 | printk("STATUS_REG: %02x ", status); |
524 | for (i = 0; signals[i].mask; ++i) | 500 | for (i = 0; signals[i].mask; ++i) |
525 | if (status & signals[i].mask) | 501 | if (status & signals[i].mask) |
@@ -543,8 +519,12 @@ static struct { | |||
543 | unsigned char value; | 519 | unsigned char value; |
544 | const char *name; | 520 | const char *name; |
545 | } phases[] = { | 521 | } phases[] = { |
546 | {PHASE_DATAOUT, "DATAOUT"}, {PHASE_DATAIN, "DATAIN"}, {PHASE_CMDOUT, "CMDOUT"}, | 522 | {PHASE_DATAOUT, "DATAOUT"}, |
547 | {PHASE_STATIN, "STATIN"}, {PHASE_MSGOUT, "MSGOUT"}, {PHASE_MSGIN, "MSGIN"}, | 523 | {PHASE_DATAIN, "DATAIN"}, |
524 | {PHASE_CMDOUT, "CMDOUT"}, | ||
525 | {PHASE_STATIN, "STATIN"}, | ||
526 | {PHASE_MSGOUT, "MSGOUT"}, | ||
527 | {PHASE_MSGIN, "MSGIN"}, | ||
548 | {PHASE_UNKNOWN, "UNKNOWN"} | 528 | {PHASE_UNKNOWN, "UNKNOWN"} |
549 | }; | 529 | }; |
550 | 530 | ||
@@ -553,8 +533,6 @@ static struct { | |||
553 | * @instance: adapter to dump | 533 | * @instance: adapter to dump |
554 | * | 534 | * |
555 | * Print the current SCSI phase for debugging purposes | 535 | * Print the current SCSI phase for debugging purposes |
556 | * | ||
557 | * Locks: none | ||
558 | */ | 536 | */ |
559 | 537 | ||
560 | static void NCR5380_print_phase(struct Scsi_Host *instance) | 538 | static void NCR5380_print_phase(struct Scsi_Host *instance) |
@@ -564,54 +542,21 @@ static void NCR5380_print_phase(struct Scsi_Host *instance) | |||
564 | 542 | ||
565 | status = NCR5380_read(STATUS_REG); | 543 | status = NCR5380_read(STATUS_REG); |
566 | if (!(status & SR_REQ)) | 544 | if (!(status & SR_REQ)) |
567 | printk(KERN_DEBUG "scsi%d: REQ not asserted, phase unknown.\n", HOSTNO); | 545 | shost_printk(KERN_DEBUG, instance, "REQ not asserted, phase unknown.\n"); |
568 | else { | 546 | else { |
569 | for (i = 0; (phases[i].value != PHASE_UNKNOWN) && | 547 | for (i = 0; (phases[i].value != PHASE_UNKNOWN) && |
570 | (phases[i].value != (status & PHASE_MASK)); ++i) | 548 | (phases[i].value != (status & PHASE_MASK)); ++i) |
571 | ; | 549 | ; |
572 | printk(KERN_DEBUG "scsi%d: phase %s\n", HOSTNO, phases[i].name); | 550 | shost_printk(KERN_DEBUG, instance, "phase %s\n", phases[i].name); |
573 | } | 551 | } |
574 | } | 552 | } |
575 | |||
576 | #endif | 553 | #endif |
577 | 554 | ||
578 | /* | ||
579 | * ++roman: New scheme of calling NCR5380_main() | ||
580 | * | ||
581 | * If we're not in an interrupt, we can call our main directly, it cannot be | ||
582 | * already running. Else, we queue it on a task queue, if not 'main_running' | ||
583 | * tells us that a lower level is already executing it. This way, | ||
584 | * 'main_running' needs not be protected in a special way. | ||
585 | * | ||
586 | * queue_main() is a utility function for putting our main onto the task | ||
587 | * queue, if main_running is false. It should be called only from a | ||
588 | * interrupt or bottom half. | ||
589 | */ | ||
590 | |||
591 | #include <linux/gfp.h> | ||
592 | #include <linux/workqueue.h> | ||
593 | #include <linux/interrupt.h> | ||
594 | |||
595 | static inline void queue_main(struct NCR5380_hostdata *hostdata) | ||
596 | { | ||
597 | if (!hostdata->main_running) { | ||
598 | /* If in interrupt and NCR5380_main() not already running, | ||
599 | queue it on the 'immediate' task queue, to be processed | ||
600 | immediately after the current interrupt processing has | ||
601 | finished. */ | ||
602 | schedule_work(&hostdata->main_task); | ||
603 | } | ||
604 | /* else: nothing to do: the running NCR5380_main() will pick up | ||
605 | any newly queued command. */ | ||
606 | } | ||
607 | |||
608 | /** | 555 | /** |
609 | * NCR58380_info - report driver and host information | 556 | * NCR58380_info - report driver and host information |
610 | * @instance: relevant scsi host instance | 557 | * @instance: relevant scsi host instance |
611 | * | 558 | * |
612 | * For use as the host template info() handler. | 559 | * For use as the host template info() handler. |
613 | * | ||
614 | * Locks: none | ||
615 | */ | 560 | */ |
616 | 561 | ||
617 | static const char *NCR5380_info(struct Scsi_Host *instance) | 562 | static const char *NCR5380_info(struct Scsi_Host *instance) |
@@ -630,13 +575,14 @@ static void prepare_info(struct Scsi_Host *instance) | |||
630 | "base 0x%lx, irq %d, " | 575 | "base 0x%lx, irq %d, " |
631 | "can_queue %d, cmd_per_lun %d, " | 576 | "can_queue %d, cmd_per_lun %d, " |
632 | "sg_tablesize %d, this_id %d, " | 577 | "sg_tablesize %d, this_id %d, " |
633 | "flags { %s}, " | 578 | "flags { %s%s}, " |
634 | "options { %s} ", | 579 | "options { %s} ", |
635 | instance->hostt->name, instance->io_port, instance->n_io_port, | 580 | instance->hostt->name, instance->io_port, instance->n_io_port, |
636 | instance->base, instance->irq, | 581 | instance->base, instance->irq, |
637 | instance->can_queue, instance->cmd_per_lun, | 582 | instance->can_queue, instance->cmd_per_lun, |
638 | instance->sg_tablesize, instance->this_id, | 583 | instance->sg_tablesize, instance->this_id, |
639 | hostdata->flags & FLAG_TAGGED_QUEUING ? "TAGGED_QUEUING " : "", | 584 | hostdata->flags & FLAG_TAGGED_QUEUING ? "TAGGED_QUEUING " : "", |
585 | hostdata->flags & FLAG_TOSHIBA_DELAY ? "TOSHIBA_DELAY " : "", | ||
640 | #ifdef DIFFERENTIAL | 586 | #ifdef DIFFERENTIAL |
641 | "DIFFERENTIAL " | 587 | "DIFFERENTIAL " |
642 | #endif | 588 | #endif |
@@ -653,102 +599,6 @@ static void prepare_info(struct Scsi_Host *instance) | |||
653 | } | 599 | } |
654 | 600 | ||
655 | /** | 601 | /** |
656 | * NCR5380_print_status - dump controller info | ||
657 | * @instance: controller to dump | ||
658 | * | ||
659 | * Print commands in the various queues, called from NCR5380_abort | ||
660 | * to aid debugging. | ||
661 | */ | ||
662 | |||
663 | static void lprint_Scsi_Cmnd(struct scsi_cmnd *cmd) | ||
664 | { | ||
665 | int i, s; | ||
666 | unsigned char *command; | ||
667 | printk("scsi%d: destination target %d, lun %llu\n", | ||
668 | H_NO(cmd), cmd->device->id, cmd->device->lun); | ||
669 | printk(KERN_CONT " command = "); | ||
670 | command = cmd->cmnd; | ||
671 | printk(KERN_CONT "%2d (0x%02x)", command[0], command[0]); | ||
672 | for (i = 1, s = COMMAND_SIZE(command[0]); i < s; ++i) | ||
673 | printk(KERN_CONT " %02x", command[i]); | ||
674 | printk("\n"); | ||
675 | } | ||
676 | |||
677 | static void NCR5380_print_status(struct Scsi_Host *instance) | ||
678 | { | ||
679 | struct NCR5380_hostdata *hostdata; | ||
680 | struct scsi_cmnd *ptr; | ||
681 | unsigned long flags; | ||
682 | |||
683 | NCR5380_dprint(NDEBUG_ANY, instance); | ||
684 | NCR5380_dprint_phase(NDEBUG_ANY, instance); | ||
685 | |||
686 | hostdata = (struct NCR5380_hostdata *)instance->hostdata; | ||
687 | |||
688 | local_irq_save(flags); | ||
689 | printk("NCR5380: coroutine is%s running.\n", | ||
690 | hostdata->main_running ? "" : "n't"); | ||
691 | if (!hostdata->connected) | ||
692 | printk("scsi%d: no currently connected command\n", HOSTNO); | ||
693 | else | ||
694 | lprint_Scsi_Cmnd((struct scsi_cmnd *) hostdata->connected); | ||
695 | printk("scsi%d: issue_queue\n", HOSTNO); | ||
696 | for (ptr = (struct scsi_cmnd *)hostdata->issue_queue; ptr; ptr = NEXT(ptr)) | ||
697 | lprint_Scsi_Cmnd(ptr); | ||
698 | |||
699 | printk("scsi%d: disconnected_queue\n", HOSTNO); | ||
700 | for (ptr = (struct scsi_cmnd *) hostdata->disconnected_queue; ptr; | ||
701 | ptr = NEXT(ptr)) | ||
702 | lprint_Scsi_Cmnd(ptr); | ||
703 | |||
704 | local_irq_restore(flags); | ||
705 | printk("\n"); | ||
706 | } | ||
707 | |||
708 | static void show_Scsi_Cmnd(struct scsi_cmnd *cmd, struct seq_file *m) | ||
709 | { | ||
710 | int i, s; | ||
711 | unsigned char *command; | ||
712 | seq_printf(m, "scsi%d: destination target %d, lun %llu\n", | ||
713 | H_NO(cmd), cmd->device->id, cmd->device->lun); | ||
714 | seq_puts(m, " command = "); | ||
715 | command = cmd->cmnd; | ||
716 | seq_printf(m, "%2d (0x%02x)", command[0], command[0]); | ||
717 | for (i = 1, s = COMMAND_SIZE(command[0]); i < s; ++i) | ||
718 | seq_printf(m, " %02x", command[i]); | ||
719 | seq_putc(m, '\n'); | ||
720 | } | ||
721 | |||
722 | static int __maybe_unused NCR5380_show_info(struct seq_file *m, | ||
723 | struct Scsi_Host *instance) | ||
724 | { | ||
725 | struct NCR5380_hostdata *hostdata; | ||
726 | struct scsi_cmnd *ptr; | ||
727 | unsigned long flags; | ||
728 | |||
729 | hostdata = (struct NCR5380_hostdata *)instance->hostdata; | ||
730 | |||
731 | local_irq_save(flags); | ||
732 | seq_printf(m, "NCR5380: coroutine is%s running.\n", | ||
733 | hostdata->main_running ? "" : "n't"); | ||
734 | if (!hostdata->connected) | ||
735 | seq_printf(m, "scsi%d: no currently connected command\n", HOSTNO); | ||
736 | else | ||
737 | show_Scsi_Cmnd((struct scsi_cmnd *) hostdata->connected, m); | ||
738 | seq_printf(m, "scsi%d: issue_queue\n", HOSTNO); | ||
739 | for (ptr = (struct scsi_cmnd *)hostdata->issue_queue; ptr; ptr = NEXT(ptr)) | ||
740 | show_Scsi_Cmnd(ptr, m); | ||
741 | |||
742 | seq_printf(m, "scsi%d: disconnected_queue\n", HOSTNO); | ||
743 | for (ptr = (struct scsi_cmnd *) hostdata->disconnected_queue; ptr; | ||
744 | ptr = NEXT(ptr)) | ||
745 | show_Scsi_Cmnd(ptr, m); | ||
746 | |||
747 | local_irq_restore(flags); | ||
748 | return 0; | ||
749 | } | ||
750 | |||
751 | /** | ||
752 | * NCR5380_init - initialise an NCR5380 | 602 | * NCR5380_init - initialise an NCR5380 |
753 | * @instance: adapter to configure | 603 | * @instance: adapter to configure |
754 | * @flags: control flags | 604 | * @flags: control flags |
@@ -764,11 +614,11 @@ static int __maybe_unused NCR5380_show_info(struct seq_file *m, | |||
764 | 614 | ||
765 | static int __init NCR5380_init(struct Scsi_Host *instance, int flags) | 615 | static int __init NCR5380_init(struct Scsi_Host *instance, int flags) |
766 | { | 616 | { |
617 | struct NCR5380_hostdata *hostdata = shost_priv(instance); | ||
767 | int i; | 618 | int i; |
768 | SETUP_HOSTDATA(instance); | 619 | unsigned long deadline; |
769 | 620 | ||
770 | hostdata->host = instance; | 621 | hostdata->host = instance; |
771 | hostdata->aborted = 0; | ||
772 | hostdata->id_mask = 1 << instance->this_id; | 622 | hostdata->id_mask = 1 << instance->this_id; |
773 | hostdata->id_higher_mask = 0; | 623 | hostdata->id_higher_mask = 0; |
774 | for (i = hostdata->id_mask; i <= 0x80; i <<= 1) | 624 | for (i = hostdata->id_mask; i <= 0x80; i <<= 1) |
@@ -782,13 +632,21 @@ static int __init NCR5380_init(struct Scsi_Host *instance, int flags) | |||
782 | #if defined (REAL_DMA) | 632 | #if defined (REAL_DMA) |
783 | hostdata->dma_len = 0; | 633 | hostdata->dma_len = 0; |
784 | #endif | 634 | #endif |
785 | hostdata->targets_present = 0; | 635 | spin_lock_init(&hostdata->lock); |
786 | hostdata->connected = NULL; | 636 | hostdata->connected = NULL; |
787 | hostdata->issue_queue = NULL; | 637 | hostdata->sensing = NULL; |
788 | hostdata->disconnected_queue = NULL; | 638 | INIT_LIST_HEAD(&hostdata->autosense); |
639 | INIT_LIST_HEAD(&hostdata->unissued); | ||
640 | INIT_LIST_HEAD(&hostdata->disconnected); | ||
641 | |||
789 | hostdata->flags = flags; | 642 | hostdata->flags = flags; |
790 | 643 | ||
791 | INIT_WORK(&hostdata->main_task, NCR5380_main); | 644 | INIT_WORK(&hostdata->main_task, NCR5380_main); |
645 | hostdata->work_q = alloc_workqueue("ncr5380_%d", | ||
646 | WQ_UNBOUND | WQ_MEM_RECLAIM, | ||
647 | 1, instance->host_no); | ||
648 | if (!hostdata->work_q) | ||
649 | return -ENOMEM; | ||
792 | 650 | ||
793 | prepare_info(instance); | 651 | prepare_info(instance); |
794 | 652 | ||
@@ -797,6 +655,72 @@ static int __init NCR5380_init(struct Scsi_Host *instance, int flags) | |||
797 | NCR5380_write(TARGET_COMMAND_REG, 0); | 655 | NCR5380_write(TARGET_COMMAND_REG, 0); |
798 | NCR5380_write(SELECT_ENABLE_REG, 0); | 656 | NCR5380_write(SELECT_ENABLE_REG, 0); |
799 | 657 | ||
658 | /* Calibrate register polling loop */ | ||
659 | i = 0; | ||
660 | deadline = jiffies + 1; | ||
661 | do { | ||
662 | cpu_relax(); | ||
663 | } while (time_is_after_jiffies(deadline)); | ||
664 | deadline += msecs_to_jiffies(256); | ||
665 | do { | ||
666 | NCR5380_read(STATUS_REG); | ||
667 | ++i; | ||
668 | cpu_relax(); | ||
669 | } while (time_is_after_jiffies(deadline)); | ||
670 | hostdata->accesses_per_ms = i / 256; | ||
671 | |||
672 | return 0; | ||
673 | } | ||
674 | |||
675 | /** | ||
676 | * NCR5380_maybe_reset_bus - Detect and correct bus wedge problems. | ||
677 | * @instance: adapter to check | ||
678 | * | ||
679 | * If the system crashed, it may have crashed with a connected target and | ||
680 | * the SCSI bus busy. Check for BUS FREE phase. If not, try to abort the | ||
681 | * currently established nexus, which we know nothing about. Failing that | ||
682 | * do a bus reset. | ||
683 | * | ||
684 | * Note that a bus reset will cause the chip to assert IRQ. | ||
685 | * | ||
686 | * Returns 0 if successful, otherwise -ENXIO. | ||
687 | */ | ||
688 | |||
689 | static int NCR5380_maybe_reset_bus(struct Scsi_Host *instance) | ||
690 | { | ||
691 | struct NCR5380_hostdata *hostdata = shost_priv(instance); | ||
692 | int pass; | ||
693 | |||
694 | for (pass = 1; (NCR5380_read(STATUS_REG) & SR_BSY) && pass <= 6; ++pass) { | ||
695 | switch (pass) { | ||
696 | case 1: | ||
697 | case 3: | ||
698 | case 5: | ||
699 | shost_printk(KERN_ERR, instance, "SCSI bus busy, waiting up to five seconds\n"); | ||
700 | NCR5380_poll_politely(instance, | ||
701 | STATUS_REG, SR_BSY, 0, 5 * HZ); | ||
702 | break; | ||
703 | case 2: | ||
704 | shost_printk(KERN_ERR, instance, "bus busy, attempting abort\n"); | ||
705 | do_abort(instance); | ||
706 | break; | ||
707 | case 4: | ||
708 | shost_printk(KERN_ERR, instance, "bus busy, attempting reset\n"); | ||
709 | do_reset(instance); | ||
710 | /* Wait after a reset; the SCSI standard calls for | ||
711 | * 250ms, we wait 500ms to be on the safe side. | ||
712 | * But some Toshiba CD-ROMs need ten times that. | ||
713 | */ | ||
714 | if (hostdata->flags & FLAG_TOSHIBA_DELAY) | ||
715 | msleep(2500); | ||
716 | else | ||
717 | msleep(500); | ||
718 | break; | ||
719 | case 6: | ||
720 | shost_printk(KERN_ERR, instance, "bus locked solid\n"); | ||
721 | return -ENXIO; | ||
722 | } | ||
723 | } | ||
800 | return 0; | 724 | return 0; |
801 | } | 725 | } |
802 | 726 | ||
@@ -812,6 +736,38 @@ static void NCR5380_exit(struct Scsi_Host *instance) | |||
812 | struct NCR5380_hostdata *hostdata = shost_priv(instance); | 736 | struct NCR5380_hostdata *hostdata = shost_priv(instance); |
813 | 737 | ||
814 | cancel_work_sync(&hostdata->main_task); | 738 | cancel_work_sync(&hostdata->main_task); |
739 | destroy_workqueue(hostdata->work_q); | ||
740 | } | ||
741 | |||
742 | /** | ||
743 | * complete_cmd - finish processing a command and return it to the SCSI ML | ||
744 | * @instance: the host instance | ||
745 | * @cmd: command to complete | ||
746 | */ | ||
747 | |||
748 | static void complete_cmd(struct Scsi_Host *instance, | ||
749 | struct scsi_cmnd *cmd) | ||
750 | { | ||
751 | struct NCR5380_hostdata *hostdata = shost_priv(instance); | ||
752 | |||
753 | dsprintk(NDEBUG_QUEUES, instance, "complete_cmd: cmd %p\n", cmd); | ||
754 | |||
755 | if (hostdata->sensing == cmd) { | ||
756 | /* Autosense processing ends here */ | ||
757 | if ((cmd->result & 0xff) != SAM_STAT_GOOD) { | ||
758 | scsi_eh_restore_cmnd(cmd, &hostdata->ses); | ||
759 | set_host_byte(cmd, DID_ERROR); | ||
760 | } else | ||
761 | scsi_eh_restore_cmnd(cmd, &hostdata->ses); | ||
762 | hostdata->sensing = NULL; | ||
763 | } | ||
764 | |||
765 | #ifdef SUPPORT_TAGS | ||
766 | cmd_free_tag(cmd); | ||
767 | #else | ||
768 | hostdata->busy[scmd_id(cmd)] &= ~(1 << cmd->device->lun); | ||
769 | #endif | ||
770 | cmd->scsi_done(cmd); | ||
815 | } | 771 | } |
816 | 772 | ||
817 | /** | 773 | /** |
@@ -819,7 +775,7 @@ static void NCR5380_exit(struct Scsi_Host *instance) | |||
819 | * @instance: the relevant SCSI adapter | 775 | * @instance: the relevant SCSI adapter |
820 | * @cmd: SCSI command | 776 | * @cmd: SCSI command |
821 | * | 777 | * |
822 | * cmd is added to the per instance issue_queue, with minor | 778 | * cmd is added to the per-instance issue queue, with minor |
823 | * twiddling done to the host specific fields of cmd. If the | 779 | * twiddling done to the host specific fields of cmd. If the |
824 | * main coroutine is not running, it is restarted. | 780 | * main coroutine is not running, it is restarted. |
825 | */ | 781 | */ |
@@ -828,44 +784,23 @@ static int NCR5380_queue_command(struct Scsi_Host *instance, | |||
828 | struct scsi_cmnd *cmd) | 784 | struct scsi_cmnd *cmd) |
829 | { | 785 | { |
830 | struct NCR5380_hostdata *hostdata = shost_priv(instance); | 786 | struct NCR5380_hostdata *hostdata = shost_priv(instance); |
831 | struct scsi_cmnd *tmp; | 787 | struct NCR5380_cmd *ncmd = scsi_cmd_priv(cmd); |
832 | unsigned long flags; | 788 | unsigned long flags; |
833 | 789 | ||
834 | #if (NDEBUG & NDEBUG_NO_WRITE) | 790 | #if (NDEBUG & NDEBUG_NO_WRITE) |
835 | switch (cmd->cmnd[0]) { | 791 | switch (cmd->cmnd[0]) { |
836 | case WRITE_6: | 792 | case WRITE_6: |
837 | case WRITE_10: | 793 | case WRITE_10: |
838 | printk(KERN_NOTICE "scsi%d: WRITE attempted with NO_WRITE debugging flag set\n", | 794 | shost_printk(KERN_DEBUG, instance, "WRITE attempted with NDEBUG_NO_WRITE set\n"); |
839 | H_NO(cmd)); | ||
840 | cmd->result = (DID_ERROR << 16); | 795 | cmd->result = (DID_ERROR << 16); |
841 | cmd->scsi_done(cmd); | 796 | cmd->scsi_done(cmd); |
842 | return 0; | 797 | return 0; |
843 | } | 798 | } |
844 | #endif /* (NDEBUG & NDEBUG_NO_WRITE) */ | 799 | #endif /* (NDEBUG & NDEBUG_NO_WRITE) */ |
845 | 800 | ||
846 | /* | ||
847 | * We use the host_scribble field as a pointer to the next command | ||
848 | * in a queue | ||
849 | */ | ||
850 | |||
851 | SET_NEXT(cmd, NULL); | ||
852 | cmd->result = 0; | 801 | cmd->result = 0; |
853 | 802 | ||
854 | /* | 803 | /* |
855 | * Insert the cmd into the issue queue. Note that REQUEST SENSE | ||
856 | * commands are added to the head of the queue since any command will | ||
857 | * clear the contingent allegiance condition that exists and the | ||
858 | * sense data is only guaranteed to be valid while the condition exists. | ||
859 | */ | ||
860 | |||
861 | /* ++guenther: now that the issue queue is being set up, we can lock ST-DMA. | ||
862 | * Otherwise a running NCR5380_main may steal the lock. | ||
863 | * Lock before actually inserting due to fairness reasons explained in | ||
864 | * atari_scsi.c. If we insert first, then it's impossible for this driver | ||
865 | * to release the lock. | ||
866 | * Stop timer for this command while waiting for the lock, or timeouts | ||
867 | * may happen (and they really do), and it's no good if the command doesn't | ||
868 | * appear in any of the queues. | ||
869 | * ++roman: Just disabling the NCR interrupt isn't sufficient here, | 804 | * ++roman: Just disabling the NCR interrupt isn't sufficient here, |
870 | * because also a timer int can trigger an abort or reset, which would | 805 | * because also a timer int can trigger an abort or reset, which would |
871 | * alter queues and touch the lock. | 806 | * alter queues and touch the lock. |
@@ -873,7 +808,7 @@ static int NCR5380_queue_command(struct Scsi_Host *instance, | |||
873 | if (!NCR5380_acquire_dma_irq(instance)) | 808 | if (!NCR5380_acquire_dma_irq(instance)) |
874 | return SCSI_MLQUEUE_HOST_BUSY; | 809 | return SCSI_MLQUEUE_HOST_BUSY; |
875 | 810 | ||
876 | local_irq_save(flags); | 811 | spin_lock_irqsave(&hostdata->lock, flags); |
877 | 812 | ||
878 | /* | 813 | /* |
879 | * Insert the cmd into the issue queue. Note that REQUEST SENSE | 814 | * Insert the cmd into the issue queue. Note that REQUEST SENSE |
@@ -882,33 +817,18 @@ static int NCR5380_queue_command(struct Scsi_Host *instance, | |||
882 | * sense data is only guaranteed to be valid while the condition exists. | 817 | * sense data is only guaranteed to be valid while the condition exists. |
883 | */ | 818 | */ |
884 | 819 | ||
885 | if (!(hostdata->issue_queue) || (cmd->cmnd[0] == REQUEST_SENSE)) { | 820 | if (cmd->cmnd[0] == REQUEST_SENSE) |
886 | LIST(cmd, hostdata->issue_queue); | 821 | list_add(&ncmd->list, &hostdata->unissued); |
887 | SET_NEXT(cmd, hostdata->issue_queue); | 822 | else |
888 | hostdata->issue_queue = cmd; | 823 | list_add_tail(&ncmd->list, &hostdata->unissued); |
889 | } else { | ||
890 | for (tmp = (struct scsi_cmnd *)hostdata->issue_queue; | ||
891 | NEXT(tmp); tmp = NEXT(tmp)) | ||
892 | ; | ||
893 | LIST(cmd, tmp); | ||
894 | SET_NEXT(tmp, cmd); | ||
895 | } | ||
896 | local_irq_restore(flags); | ||
897 | 824 | ||
898 | dprintk(NDEBUG_QUEUES, "scsi%d: command added to %s of queue\n", H_NO(cmd), | 825 | spin_unlock_irqrestore(&hostdata->lock, flags); |
899 | (cmd->cmnd[0] == REQUEST_SENSE) ? "head" : "tail"); | ||
900 | 826 | ||
901 | /* If queue_command() is called from an interrupt (real one or bottom | 827 | dsprintk(NDEBUG_QUEUES, instance, "command %p added to %s of queue\n", |
902 | * half), we let queue_main() do the job of taking care about main. If it | 828 | cmd, (cmd->cmnd[0] == REQUEST_SENSE) ? "head" : "tail"); |
903 | * is already running, this is a no-op, else main will be queued. | 829 | |
904 | * | 830 | /* Kick off command processing */ |
905 | * If we're not in an interrupt, we can call NCR5380_main() | 831 | queue_work(hostdata->work_q, &hostdata->main_task); |
906 | * unconditionally, because it cannot be already running. | ||
907 | */ | ||
908 | if (in_interrupt() || irqs_disabled()) | ||
909 | queue_main(hostdata); | ||
910 | else | ||
911 | NCR5380_main(&hostdata->main_task); | ||
912 | return 0; | 832 | return 0; |
913 | } | 833 | } |
914 | 834 | ||
@@ -917,22 +837,85 @@ static inline void maybe_release_dma_irq(struct Scsi_Host *instance) | |||
917 | struct NCR5380_hostdata *hostdata = shost_priv(instance); | 837 | struct NCR5380_hostdata *hostdata = shost_priv(instance); |
918 | 838 | ||
919 | /* Caller does the locking needed to set & test these data atomically */ | 839 | /* Caller does the locking needed to set & test these data atomically */ |
920 | if (!hostdata->disconnected_queue && | 840 | if (list_empty(&hostdata->disconnected) && |
921 | !hostdata->issue_queue && | 841 | list_empty(&hostdata->unissued) && |
842 | list_empty(&hostdata->autosense) && | ||
922 | !hostdata->connected && | 843 | !hostdata->connected && |
923 | !hostdata->retain_dma_intr) | 844 | !hostdata->selecting) |
924 | NCR5380_release_dma_irq(instance); | 845 | NCR5380_release_dma_irq(instance); |
925 | } | 846 | } |
926 | 847 | ||
927 | /** | 848 | /** |
849 | * dequeue_next_cmd - dequeue a command for processing | ||
850 | * @instance: the scsi host instance | ||
851 | * | ||
852 | * Priority is given to commands on the autosense queue. These commands | ||
853 | * need autosense because of a CHECK CONDITION result. | ||
854 | * | ||
855 | * Returns a command pointer if a command is found for a target that is | ||
856 | * not already busy. Otherwise returns NULL. | ||
857 | */ | ||
858 | |||
859 | static struct scsi_cmnd *dequeue_next_cmd(struct Scsi_Host *instance) | ||
860 | { | ||
861 | struct NCR5380_hostdata *hostdata = shost_priv(instance); | ||
862 | struct NCR5380_cmd *ncmd; | ||
863 | struct scsi_cmnd *cmd; | ||
864 | |||
865 | if (list_empty(&hostdata->autosense)) { | ||
866 | list_for_each_entry(ncmd, &hostdata->unissued, list) { | ||
867 | cmd = NCR5380_to_scmd(ncmd); | ||
868 | dsprintk(NDEBUG_QUEUES, instance, "dequeue: cmd=%p target=%d busy=0x%02x lun=%llu\n", | ||
869 | cmd, scmd_id(cmd), hostdata->busy[scmd_id(cmd)], cmd->device->lun); | ||
870 | |||
871 | if ( | ||
872 | #ifdef SUPPORT_TAGS | ||
873 | !is_lun_busy(cmd, 1) | ||
874 | #else | ||
875 | !(hostdata->busy[scmd_id(cmd)] & (1 << cmd->device->lun)) | ||
876 | #endif | ||
877 | ) { | ||
878 | list_del(&ncmd->list); | ||
879 | dsprintk(NDEBUG_QUEUES, instance, | ||
880 | "dequeue: removed %p from issue queue\n", cmd); | ||
881 | return cmd; | ||
882 | } | ||
883 | } | ||
884 | } else { | ||
885 | /* Autosense processing begins here */ | ||
886 | ncmd = list_first_entry(&hostdata->autosense, | ||
887 | struct NCR5380_cmd, list); | ||
888 | list_del(&ncmd->list); | ||
889 | cmd = NCR5380_to_scmd(ncmd); | ||
890 | dsprintk(NDEBUG_QUEUES, instance, | ||
891 | "dequeue: removed %p from autosense queue\n", cmd); | ||
892 | scsi_eh_prep_cmnd(cmd, &hostdata->ses, NULL, 0, ~0); | ||
893 | hostdata->sensing = cmd; | ||
894 | return cmd; | ||
895 | } | ||
896 | return NULL; | ||
897 | } | ||
898 | |||
899 | static void requeue_cmd(struct Scsi_Host *instance, struct scsi_cmnd *cmd) | ||
900 | { | ||
901 | struct NCR5380_hostdata *hostdata = shost_priv(instance); | ||
902 | struct NCR5380_cmd *ncmd = scsi_cmd_priv(cmd); | ||
903 | |||
904 | if (hostdata->sensing) { | ||
905 | scsi_eh_restore_cmnd(cmd, &hostdata->ses); | ||
906 | list_add(&ncmd->list, &hostdata->autosense); | ||
907 | hostdata->sensing = NULL; | ||
908 | } else | ||
909 | list_add(&ncmd->list, &hostdata->unissued); | ||
910 | } | ||
911 | |||
912 | /** | ||
928 | * NCR5380_main - NCR state machines | 913 | * NCR5380_main - NCR state machines |
929 | * | 914 | * |
930 | * NCR5380_main is a coroutine that runs as long as more work can | 915 | * NCR5380_main is a coroutine that runs as long as more work can |
931 | * be done on the NCR5380 host adapters in a system. Both | 916 | * be done on the NCR5380 host adapters in a system. Both |
932 | * NCR5380_queue_command() and NCR5380_intr() will try to start it | 917 | * NCR5380_queue_command() and NCR5380_intr() will try to start it |
933 | * in case it is not running. | 918 | * in case it is not running. |
934 | * | ||
935 | * Locks: called as its own thread with no locks held. | ||
936 | */ | 919 | */ |
937 | 920 | ||
938 | static void NCR5380_main(struct work_struct *work) | 921 | static void NCR5380_main(struct work_struct *work) |
@@ -940,154 +923,69 @@ static void NCR5380_main(struct work_struct *work) | |||
940 | struct NCR5380_hostdata *hostdata = | 923 | struct NCR5380_hostdata *hostdata = |
941 | container_of(work, struct NCR5380_hostdata, main_task); | 924 | container_of(work, struct NCR5380_hostdata, main_task); |
942 | struct Scsi_Host *instance = hostdata->host; | 925 | struct Scsi_Host *instance = hostdata->host; |
943 | struct scsi_cmnd *tmp, *prev; | 926 | struct scsi_cmnd *cmd; |
944 | int done; | 927 | int done; |
945 | unsigned long flags; | ||
946 | 928 | ||
947 | /* | 929 | /* |
948 | * We run (with interrupts disabled) until we're sure that none of | ||
949 | * the host adapters have anything that can be done, at which point | ||
950 | * we set main_running to 0 and exit. | ||
951 | * | ||
952 | * Interrupts are enabled before doing various other internal | ||
953 | * instructions, after we've decided that we need to run through | ||
954 | * the loop again. | ||
955 | * | ||
956 | * this should prevent any race conditions. | ||
957 | * | ||
958 | * ++roman: Just disabling the NCR interrupt isn't sufficient here, | 930 | * ++roman: Just disabling the NCR interrupt isn't sufficient here, |
959 | * because also a timer int can trigger an abort or reset, which can | 931 | * because also a timer int can trigger an abort or reset, which can |
960 | * alter queues and touch the Falcon lock. | 932 | * alter queues and touch the Falcon lock. |
961 | */ | 933 | */ |
962 | 934 | ||
963 | /* Tell int handlers main() is now already executing. Note that | ||
964 | no races are possible here. If an int comes in before | ||
965 | 'main_running' is set here, and queues/executes main via the | ||
966 | task queue, it doesn't do any harm, just this instance of main | ||
967 | won't find any work left to do. */ | ||
968 | if (hostdata->main_running) | ||
969 | return; | ||
970 | hostdata->main_running = 1; | ||
971 | |||
972 | local_save_flags(flags); | ||
973 | do { | 935 | do { |
974 | local_irq_disable(); /* Freeze request queues */ | ||
975 | done = 1; | 936 | done = 1; |
976 | 937 | ||
977 | if (!hostdata->connected) { | 938 | spin_lock_irq(&hostdata->lock); |
978 | dprintk(NDEBUG_MAIN, "scsi%d: not connected\n", HOSTNO); | 939 | while (!hostdata->connected && |
979 | /* | 940 | (cmd = dequeue_next_cmd(instance))) { |
980 | * Search through the issue_queue for a command destined | ||
981 | * for a target that's not busy. | ||
982 | */ | ||
983 | #if (NDEBUG & NDEBUG_LISTS) | ||
984 | for (tmp = (struct scsi_cmnd *) hostdata->issue_queue, prev = NULL; | ||
985 | tmp && (tmp != prev); prev = tmp, tmp = NEXT(tmp)) | ||
986 | ; | ||
987 | /*printk("%p ", tmp);*/ | ||
988 | if ((tmp == prev) && tmp) | ||
989 | printk(" LOOP\n"); | ||
990 | /* else printk("\n"); */ | ||
991 | #endif | ||
992 | for (tmp = (struct scsi_cmnd *) hostdata->issue_queue, | ||
993 | prev = NULL; tmp; prev = tmp, tmp = NEXT(tmp)) { | ||
994 | u8 lun = tmp->device->lun; | ||
995 | |||
996 | dprintk(NDEBUG_LISTS, | ||
997 | "MAIN tmp=%p target=%d busy=%d lun=%d\n", | ||
998 | tmp, scmd_id(tmp), hostdata->busy[scmd_id(tmp)], | ||
999 | lun); | ||
1000 | /* When we find one, remove it from the issue queue. */ | ||
1001 | /* ++guenther: possible race with Falcon locking */ | ||
1002 | if ( | ||
1003 | #ifdef SUPPORT_TAGS | ||
1004 | !is_lun_busy( tmp, tmp->cmnd[0] != REQUEST_SENSE) | ||
1005 | #else | ||
1006 | !(hostdata->busy[tmp->device->id] & (1 << lun)) | ||
1007 | #endif | ||
1008 | ) { | ||
1009 | /* ++guenther: just to be sure, this must be atomic */ | ||
1010 | local_irq_disable(); | ||
1011 | if (prev) { | ||
1012 | REMOVE(prev, NEXT(prev), tmp, NEXT(tmp)); | ||
1013 | SET_NEXT(prev, NEXT(tmp)); | ||
1014 | } else { | ||
1015 | REMOVE(-1, hostdata->issue_queue, tmp, NEXT(tmp)); | ||
1016 | hostdata->issue_queue = NEXT(tmp); | ||
1017 | } | ||
1018 | SET_NEXT(tmp, NULL); | ||
1019 | hostdata->retain_dma_intr++; | ||
1020 | 941 | ||
1021 | /* reenable interrupts after finding one */ | 942 | dsprintk(NDEBUG_MAIN, instance, "main: dequeued %p\n", cmd); |
1022 | local_irq_restore(flags); | ||
1023 | 943 | ||
1024 | /* | 944 | /* |
1025 | * Attempt to establish an I_T_L nexus here. | 945 | * Attempt to establish an I_T_L nexus here. |
1026 | * On success, instance->hostdata->connected is set. | 946 | * On success, instance->hostdata->connected is set. |
1027 | * On failure, we must add the command back to the | 947 | * On failure, we must add the command back to the |
1028 | * issue queue so we can keep trying. | 948 | * issue queue so we can keep trying. |
1029 | */ | 949 | */ |
1030 | dprintk(NDEBUG_MAIN, "scsi%d: main(): command for target %d " | 950 | /* |
1031 | "lun %d removed from issue_queue\n", | 951 | * REQUEST SENSE commands are issued without tagged |
1032 | HOSTNO, tmp->device->id, lun); | 952 | * queueing, even on SCSI-II devices because the |
1033 | /* | 953 | * contingent allegiance condition exists for the |
1034 | * REQUEST SENSE commands are issued without tagged | 954 | * entire unit. |
1035 | * queueing, even on SCSI-II devices because the | 955 | */ |
1036 | * contingent allegiance condition exists for the | 956 | /* ++roman: ...and the standard also requires that |
1037 | * entire unit. | 957 | * REQUEST SENSE command are untagged. |
1038 | */ | 958 | */ |
1039 | /* ++roman: ...and the standard also requires that | ||
1040 | * REQUEST SENSE command are untagged. | ||
1041 | */ | ||
1042 | 959 | ||
1043 | #ifdef SUPPORT_TAGS | 960 | #ifdef SUPPORT_TAGS |
1044 | cmd_get_tag(tmp, tmp->cmnd[0] != REQUEST_SENSE); | 961 | cmd_get_tag(cmd, cmd->cmnd[0] != REQUEST_SENSE); |
1045 | #endif | 962 | #endif |
1046 | if (!NCR5380_select(instance, tmp)) { | 963 | cmd = NCR5380_select(instance, cmd); |
1047 | local_irq_disable(); | 964 | if (!cmd) { |
1048 | hostdata->retain_dma_intr--; | 965 | dsprintk(NDEBUG_MAIN, instance, "main: select complete\n"); |
1049 | /* release if target did not response! */ | 966 | maybe_release_dma_irq(instance); |
1050 | maybe_release_dma_irq(instance); | 967 | } else { |
1051 | local_irq_restore(flags); | 968 | dsprintk(NDEBUG_MAIN | NDEBUG_QUEUES, instance, |
1052 | break; | 969 | "main: select failed, returning %p to queue\n", cmd); |
1053 | } else { | 970 | requeue_cmd(instance, cmd); |
1054 | local_irq_disable(); | ||
1055 | LIST(tmp, hostdata->issue_queue); | ||
1056 | SET_NEXT(tmp, hostdata->issue_queue); | ||
1057 | hostdata->issue_queue = tmp; | ||
1058 | #ifdef SUPPORT_TAGS | 971 | #ifdef SUPPORT_TAGS |
1059 | cmd_free_tag(tmp); | 972 | cmd_free_tag(cmd); |
1060 | #endif | 973 | #endif |
1061 | hostdata->retain_dma_intr--; | 974 | } |
1062 | local_irq_restore(flags); | 975 | } |
1063 | dprintk(NDEBUG_MAIN, "scsi%d: main(): select() failed, " | ||
1064 | "returned to issue_queue\n", HOSTNO); | ||
1065 | if (hostdata->connected) | ||
1066 | break; | ||
1067 | } | ||
1068 | } /* if target/lun/target queue is not busy */ | ||
1069 | } /* for issue_queue */ | ||
1070 | } /* if (!hostdata->connected) */ | ||
1071 | |||
1072 | if (hostdata->connected | 976 | if (hostdata->connected |
1073 | #ifdef REAL_DMA | 977 | #ifdef REAL_DMA |
1074 | && !hostdata->dma_len | 978 | && !hostdata->dma_len |
1075 | #endif | 979 | #endif |
1076 | ) { | 980 | ) { |
1077 | local_irq_restore(flags); | 981 | dsprintk(NDEBUG_MAIN, instance, "main: performing information transfer\n"); |
1078 | dprintk(NDEBUG_MAIN, "scsi%d: main: performing information transfer\n", | ||
1079 | HOSTNO); | ||
1080 | NCR5380_information_transfer(instance); | 982 | NCR5380_information_transfer(instance); |
1081 | dprintk(NDEBUG_MAIN, "scsi%d: main: done set false\n", HOSTNO); | ||
1082 | done = 0; | 983 | done = 0; |
1083 | } | 984 | } |
985 | spin_unlock_irq(&hostdata->lock); | ||
986 | if (!done) | ||
987 | cond_resched(); | ||
1084 | } while (!done); | 988 | } while (!done); |
1085 | |||
1086 | /* Better allow ints _after_ 'main_running' has been cleared, else | ||
1087 | an interrupt could believe we'll pick up the work it left for | ||
1088 | us, but we won't see it anymore here... */ | ||
1089 | hostdata->main_running = 0; | ||
1090 | local_irq_restore(flags); | ||
1091 | } | 989 | } |
1092 | 990 | ||
1093 | 991 | ||
@@ -1096,27 +994,20 @@ static void NCR5380_main(struct work_struct *work) | |||
1096 | * Function : void NCR5380_dma_complete (struct Scsi_Host *instance) | 994 | * Function : void NCR5380_dma_complete (struct Scsi_Host *instance) |
1097 | * | 995 | * |
1098 | * Purpose : Called by interrupt handler when DMA finishes or a phase | 996 | * Purpose : Called by interrupt handler when DMA finishes or a phase |
1099 | * mismatch occurs (which would finish the DMA transfer). | 997 | * mismatch occurs (which would finish the DMA transfer). |
1100 | * | 998 | * |
1101 | * Inputs : instance - this instance of the NCR5380. | 999 | * Inputs : instance - this instance of the NCR5380. |
1102 | * | ||
1103 | */ | 1000 | */ |
1104 | 1001 | ||
1105 | static void NCR5380_dma_complete(struct Scsi_Host *instance) | 1002 | static void NCR5380_dma_complete(struct Scsi_Host *instance) |
1106 | { | 1003 | { |
1107 | SETUP_HOSTDATA(instance); | 1004 | struct NCR5380_hostdata *hostdata = shost_priv(instance); |
1108 | int transferred; | 1005 | int transferred; |
1109 | unsigned char **data; | 1006 | unsigned char **data; |
1110 | volatile int *count; | 1007 | int *count; |
1111 | int saved_data = 0, overrun = 0; | 1008 | int saved_data = 0, overrun = 0; |
1112 | unsigned char p; | 1009 | unsigned char p; |
1113 | 1010 | ||
1114 | if (!hostdata->connected) { | ||
1115 | printk(KERN_WARNING "scsi%d: received end of DMA interrupt with " | ||
1116 | "no connected cmd\n", HOSTNO); | ||
1117 | return; | ||
1118 | } | ||
1119 | |||
1120 | if (hostdata->read_overruns) { | 1011 | if (hostdata->read_overruns) { |
1121 | p = hostdata->connected->SCp.phase; | 1012 | p = hostdata->connected->SCp.phase; |
1122 | if (p & SR_IO) { | 1013 | if (p & SR_IO) { |
@@ -1126,15 +1017,11 @@ static void NCR5380_dma_complete(struct Scsi_Host *instance) | |||
1126 | (BASR_PHASE_MATCH|BASR_ACK)) { | 1017 | (BASR_PHASE_MATCH|BASR_ACK)) { |
1127 | saved_data = NCR5380_read(INPUT_DATA_REG); | 1018 | saved_data = NCR5380_read(INPUT_DATA_REG); |
1128 | overrun = 1; | 1019 | overrun = 1; |
1129 | dprintk(NDEBUG_DMA, "scsi%d: read overrun handled\n", HOSTNO); | 1020 | dsprintk(NDEBUG_DMA, instance, "read overrun handled\n"); |
1130 | } | 1021 | } |
1131 | } | 1022 | } |
1132 | } | 1023 | } |
1133 | 1024 | ||
1134 | dprintk(NDEBUG_DMA, "scsi%d: real DMA transfer complete, basr 0x%X, sr 0x%X\n", | ||
1135 | HOSTNO, NCR5380_read(BUS_AND_STATUS_REG), | ||
1136 | NCR5380_read(STATUS_REG)); | ||
1137 | |||
1138 | #if defined(CONFIG_SUN3) | 1025 | #if defined(CONFIG_SUN3) |
1139 | if ((sun3scsi_dma_finish(rq_data_dir(hostdata->connected->request)))) { | 1026 | if ((sun3scsi_dma_finish(rq_data_dir(hostdata->connected->request)))) { |
1140 | pr_err("scsi%d: overrun in UDC counter -- not prepared to deal with this!\n", | 1027 | pr_err("scsi%d: overrun in UDC counter -- not prepared to deal with this!\n", |
@@ -1153,9 +1040,9 @@ static void NCR5380_dma_complete(struct Scsi_Host *instance) | |||
1153 | } | 1040 | } |
1154 | #endif | 1041 | #endif |
1155 | 1042 | ||
1156 | (void)NCR5380_read(RESET_PARITY_INTERRUPT_REG); | ||
1157 | NCR5380_write(MODE_REG, MR_BASE); | 1043 | NCR5380_write(MODE_REG, MR_BASE); |
1158 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); | 1044 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); |
1045 | NCR5380_read(RESET_PARITY_INTERRUPT_REG); | ||
1159 | 1046 | ||
1160 | transferred = hostdata->dma_len - NCR5380_dma_residual(instance); | 1047 | transferred = hostdata->dma_len - NCR5380_dma_residual(instance); |
1161 | hostdata->dma_len = 0; | 1048 | hostdata->dma_len = 0; |
@@ -1194,140 +1081,160 @@ static void NCR5380_dma_complete(struct Scsi_Host *instance) | |||
1194 | * Handle interrupts, reestablishing I_T_L or I_T_L_Q nexuses | 1081 | * Handle interrupts, reestablishing I_T_L or I_T_L_Q nexuses |
1195 | * from the disconnected queue, and restarting NCR5380_main() | 1082 | * from the disconnected queue, and restarting NCR5380_main() |
1196 | * as required. | 1083 | * as required. |
1084 | * | ||
1085 | * The chip can assert IRQ in any of six different conditions. The IRQ flag | ||
1086 | * is then cleared by reading the Reset Parity/Interrupt Register (RPIR). | ||
1087 | * Three of these six conditions are latched in the Bus and Status Register: | ||
1088 | * - End of DMA (cleared by ending DMA Mode) | ||
1089 | * - Parity error (cleared by reading RPIR) | ||
1090 | * - Loss of BSY (cleared by reading RPIR) | ||
1091 | * Two conditions have flag bits that are not latched: | ||
1092 | * - Bus phase mismatch (non-maskable in DMA Mode, cleared by ending DMA Mode) | ||
1093 | * - Bus reset (non-maskable) | ||
1094 | * The remaining condition has no flag bit at all: | ||
1095 | * - Selection/reselection | ||
1096 | * | ||
1097 | * Hence, establishing the cause(s) of any interrupt is partly guesswork. | ||
1098 | * In "The DP8490 and DP5380 Comparison Guide", National Semiconductor | ||
1099 | * claimed that "the design of the [DP8490] interrupt logic ensures | ||
1100 | * interrupts will not be lost (they can be on the DP5380)." | ||
1101 | * The L5380/53C80 datasheet from LOGIC Devices has more details. | ||
1102 | * | ||
1103 | * Checking for bus reset by reading RST is futile because of interrupt | ||
1104 | * latency, but a bus reset will reset chip logic. Checking for parity error | ||
1105 | * is unnecessary because that interrupt is never enabled. A Loss of BSY | ||
1106 | * condition will clear DMA Mode. We can tell when this occurs because the | ||
1107 | * the Busy Monitor interrupt is enabled together with DMA Mode. | ||
1197 | */ | 1108 | */ |
1198 | 1109 | ||
1199 | static irqreturn_t NCR5380_intr(int irq, void *dev_id) | 1110 | static irqreturn_t NCR5380_intr(int irq, void *dev_id) |
1200 | { | 1111 | { |
1201 | struct Scsi_Host *instance = dev_id; | 1112 | struct Scsi_Host *instance = dev_id; |
1202 | int done = 1, handled = 0; | 1113 | struct NCR5380_hostdata *hostdata = shost_priv(instance); |
1114 | int handled = 0; | ||
1203 | unsigned char basr; | 1115 | unsigned char basr; |
1116 | unsigned long flags; | ||
1204 | 1117 | ||
1205 | dprintk(NDEBUG_INTR, "scsi%d: NCR5380 irq triggered\n", HOSTNO); | 1118 | spin_lock_irqsave(&hostdata->lock, flags); |
1206 | 1119 | ||
1207 | /* Look for pending interrupts */ | ||
1208 | basr = NCR5380_read(BUS_AND_STATUS_REG); | 1120 | basr = NCR5380_read(BUS_AND_STATUS_REG); |
1209 | dprintk(NDEBUG_INTR, "scsi%d: BASR=%02x\n", HOSTNO, basr); | ||
1210 | /* dispatch to appropriate routine if found and done=0 */ | ||
1211 | if (basr & BASR_IRQ) { | 1121 | if (basr & BASR_IRQ) { |
1212 | NCR5380_dprint(NDEBUG_INTR, instance); | 1122 | unsigned char mr = NCR5380_read(MODE_REG); |
1213 | if ((NCR5380_read(STATUS_REG) & (SR_SEL|SR_IO)) == (SR_SEL|SR_IO)) { | 1123 | unsigned char sr = NCR5380_read(STATUS_REG); |
1214 | done = 0; | 1124 | |
1215 | dprintk(NDEBUG_INTR, "scsi%d: SEL interrupt\n", HOSTNO); | 1125 | dsprintk(NDEBUG_INTR, instance, "IRQ %d, BASR 0x%02x, SR 0x%02x, MR 0x%02x\n", |
1216 | NCR5380_reselect(instance); | 1126 | irq, basr, sr, mr); |
1217 | (void)NCR5380_read(RESET_PARITY_INTERRUPT_REG); | ||
1218 | } else if (basr & BASR_PARITY_ERROR) { | ||
1219 | dprintk(NDEBUG_INTR, "scsi%d: PARITY interrupt\n", HOSTNO); | ||
1220 | (void)NCR5380_read(RESET_PARITY_INTERRUPT_REG); | ||
1221 | } else if ((NCR5380_read(STATUS_REG) & SR_RST) == SR_RST) { | ||
1222 | dprintk(NDEBUG_INTR, "scsi%d: RESET interrupt\n", HOSTNO); | ||
1223 | (void)NCR5380_read(RESET_PARITY_INTERRUPT_REG); | ||
1224 | } else { | ||
1225 | /* | ||
1226 | * The rest of the interrupt conditions can occur only during a | ||
1227 | * DMA transfer | ||
1228 | */ | ||
1229 | 1127 | ||
1230 | #if defined(REAL_DMA) | 1128 | #if defined(REAL_DMA) |
1231 | /* | 1129 | if ((mr & MR_DMA_MODE) || (mr & MR_MONITOR_BSY)) { |
1232 | * We should only get PHASE MISMATCH and EOP interrupts if we have | 1130 | /* Probably End of DMA, Phase Mismatch or Loss of BSY. |
1233 | * DMA enabled, so do a sanity check based on the current setting | 1131 | * We ack IRQ after clearing Mode Register. Workarounds |
1234 | * of the MODE register. | 1132 | * for End of DMA errata need to happen in DMA Mode. |
1235 | */ | 1133 | */ |
1236 | 1134 | ||
1237 | if ((NCR5380_read(MODE_REG) & MR_DMA_MODE) && | 1135 | dsprintk(NDEBUG_INTR, instance, "interrupt in DMA mode\n"); |
1238 | ((basr & BASR_END_DMA_TRANSFER) || | ||
1239 | !(basr & BASR_PHASE_MATCH))) { | ||
1240 | 1136 | ||
1241 | dprintk(NDEBUG_INTR, "scsi%d: PHASE MISM or EOP interrupt\n", HOSTNO); | 1137 | if (hostdata->connected) { |
1242 | NCR5380_dma_complete( instance ); | 1138 | NCR5380_dma_complete(instance); |
1243 | done = 0; | 1139 | queue_work(hostdata->work_q, &hostdata->main_task); |
1244 | } else | 1140 | } else { |
1141 | NCR5380_write(MODE_REG, MR_BASE); | ||
1142 | NCR5380_read(RESET_PARITY_INTERRUPT_REG); | ||
1143 | } | ||
1144 | } else | ||
1245 | #endif /* REAL_DMA */ | 1145 | #endif /* REAL_DMA */ |
1246 | { | 1146 | if ((NCR5380_read(CURRENT_SCSI_DATA_REG) & hostdata->id_mask) && |
1247 | /* MS: Ignore unknown phase mismatch interrupts (caused by EOP interrupt) */ | 1147 | (sr & (SR_SEL | SR_IO | SR_BSY | SR_RST)) == (SR_SEL | SR_IO)) { |
1248 | if (basr & BASR_PHASE_MATCH) | 1148 | /* Probably reselected */ |
1249 | dprintk(NDEBUG_INTR, "scsi%d: unknown interrupt, " | 1149 | NCR5380_write(SELECT_ENABLE_REG, 0); |
1250 | "BASR 0x%x, MR 0x%x, SR 0x%x\n", | 1150 | NCR5380_read(RESET_PARITY_INTERRUPT_REG); |
1251 | HOSTNO, basr, NCR5380_read(MODE_REG), | 1151 | |
1252 | NCR5380_read(STATUS_REG)); | 1152 | dsprintk(NDEBUG_INTR, instance, "interrupt with SEL and IO\n"); |
1253 | (void)NCR5380_read(RESET_PARITY_INTERRUPT_REG); | 1153 | |
1154 | if (!hostdata->connected) { | ||
1155 | NCR5380_reselect(instance); | ||
1156 | queue_work(hostdata->work_q, &hostdata->main_task); | ||
1157 | } | ||
1158 | if (!hostdata->connected) | ||
1159 | NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask); | ||
1160 | } else { | ||
1161 | /* Probably Bus Reset */ | ||
1162 | NCR5380_read(RESET_PARITY_INTERRUPT_REG); | ||
1163 | |||
1164 | dsprintk(NDEBUG_INTR, instance, "unknown interrupt\n"); | ||
1254 | #ifdef SUN3_SCSI_VME | 1165 | #ifdef SUN3_SCSI_VME |
1255 | dregs->csr |= CSR_DMA_ENABLE; | 1166 | dregs->csr |= CSR_DMA_ENABLE; |
1256 | #endif | 1167 | #endif |
1257 | } | 1168 | } |
1258 | } /* if !(SELECTION || PARITY) */ | ||
1259 | handled = 1; | 1169 | handled = 1; |
1260 | } /* BASR & IRQ */ else { | 1170 | } else { |
1261 | printk(KERN_NOTICE "scsi%d: interrupt without IRQ bit set in BASR, " | 1171 | shost_printk(KERN_NOTICE, instance, "interrupt without IRQ bit\n"); |
1262 | "BASR 0x%X, MR 0x%X, SR 0x%x\n", HOSTNO, basr, | ||
1263 | NCR5380_read(MODE_REG), NCR5380_read(STATUS_REG)); | ||
1264 | (void)NCR5380_read(RESET_PARITY_INTERRUPT_REG); | ||
1265 | #ifdef SUN3_SCSI_VME | 1172 | #ifdef SUN3_SCSI_VME |
1266 | dregs->csr |= CSR_DMA_ENABLE; | 1173 | dregs->csr |= CSR_DMA_ENABLE; |
1267 | #endif | 1174 | #endif |
1268 | } | 1175 | } |
1269 | 1176 | ||
1270 | if (!done) { | 1177 | spin_unlock_irqrestore(&hostdata->lock, flags); |
1271 | dprintk(NDEBUG_INTR, "scsi%d: in int routine, calling main\n", HOSTNO); | 1178 | |
1272 | /* Put a call to NCR5380_main() on the queue... */ | ||
1273 | queue_main(shost_priv(instance)); | ||
1274 | } | ||
1275 | return IRQ_RETVAL(handled); | 1179 | return IRQ_RETVAL(handled); |
1276 | } | 1180 | } |
1277 | 1181 | ||
1278 | /* | 1182 | /* |
1279 | * Function : int NCR5380_select(struct Scsi_Host *instance, | 1183 | * Function : int NCR5380_select(struct Scsi_Host *instance, |
1280 | * struct scsi_cmnd *cmd) | 1184 | * struct scsi_cmnd *cmd) |
1281 | * | 1185 | * |
1282 | * Purpose : establishes I_T_L or I_T_L_Q nexus for new or existing command, | 1186 | * Purpose : establishes I_T_L or I_T_L_Q nexus for new or existing command, |
1283 | * including ARBITRATION, SELECTION, and initial message out for | 1187 | * including ARBITRATION, SELECTION, and initial message out for |
1284 | * IDENTIFY and queue messages. | 1188 | * IDENTIFY and queue messages. |
1285 | * | 1189 | * |
1286 | * Inputs : instance - instantiation of the 5380 driver on which this | 1190 | * Inputs : instance - instantiation of the 5380 driver on which this |
1287 | * target lives, cmd - SCSI command to execute. | 1191 | * target lives, cmd - SCSI command to execute. |
1288 | * | 1192 | * |
1289 | * Returns : -1 if selection could not execute for some reason, | 1193 | * Returns cmd if selection failed but should be retried, |
1290 | * 0 if selection succeeded or failed because the target | 1194 | * NULL if selection failed and should not be retried, or |
1291 | * did not respond. | 1195 | * NULL if selection succeeded (hostdata->connected == cmd). |
1292 | * | 1196 | * |
1293 | * Side effects : | 1197 | * Side effects : |
1294 | * If bus busy, arbitration failed, etc, NCR5380_select() will exit | 1198 | * If bus busy, arbitration failed, etc, NCR5380_select() will exit |
1295 | * with registers as they should have been on entry - ie | 1199 | * with registers as they should have been on entry - ie |
1296 | * SELECT_ENABLE will be set appropriately, the NCR5380 | 1200 | * SELECT_ENABLE will be set appropriately, the NCR5380 |
1297 | * will cease to drive any SCSI bus signals. | 1201 | * will cease to drive any SCSI bus signals. |
1298 | * | 1202 | * |
1299 | * If successful : I_T_L or I_T_L_Q nexus will be established, | 1203 | * If successful : I_T_L or I_T_L_Q nexus will be established, |
1300 | * instance->connected will be set to cmd. | 1204 | * instance->connected will be set to cmd. |
1301 | * SELECT interrupt will be disabled. | 1205 | * SELECT interrupt will be disabled. |
1302 | * | 1206 | * |
1303 | * If failed (no target) : cmd->scsi_done() will be called, and the | 1207 | * If failed (no target) : cmd->scsi_done() will be called, and the |
1304 | * cmd->result host byte set to DID_BAD_TARGET. | 1208 | * cmd->result host byte set to DID_BAD_TARGET. |
1305 | */ | 1209 | */ |
1306 | 1210 | ||
1307 | static int NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd) | 1211 | static struct scsi_cmnd *NCR5380_select(struct Scsi_Host *instance, |
1212 | struct scsi_cmnd *cmd) | ||
1308 | { | 1213 | { |
1309 | SETUP_HOSTDATA(instance); | 1214 | struct NCR5380_hostdata *hostdata = shost_priv(instance); |
1310 | unsigned char tmp[3], phase; | 1215 | unsigned char tmp[3], phase; |
1311 | unsigned char *data; | 1216 | unsigned char *data; |
1312 | int len; | 1217 | int len; |
1313 | unsigned long timeout; | 1218 | int err; |
1314 | unsigned long flags; | ||
1315 | 1219 | ||
1316 | hostdata->restart_select = 0; | ||
1317 | NCR5380_dprint(NDEBUG_ARBITRATION, instance); | 1220 | NCR5380_dprint(NDEBUG_ARBITRATION, instance); |
1318 | dprintk(NDEBUG_ARBITRATION, "scsi%d: starting arbitration, id = %d\n", HOSTNO, | 1221 | dsprintk(NDEBUG_ARBITRATION, instance, "starting arbitration, id = %d\n", |
1319 | instance->this_id); | 1222 | instance->this_id); |
1223 | |||
1224 | /* | ||
1225 | * Arbitration and selection phases are slow and involve dropping the | ||
1226 | * lock, so we have to watch out for EH. An exception handler may | ||
1227 | * change 'selecting' to NULL. This function will then return NULL | ||
1228 | * so that the caller will forget about 'cmd'. (During information | ||
1229 | * transfer phases, EH may change 'connected' to NULL.) | ||
1230 | */ | ||
1231 | hostdata->selecting = cmd; | ||
1320 | 1232 | ||
1321 | /* | 1233 | /* |
1322 | * Set the phase bits to 0, otherwise the NCR5380 won't drive the | 1234 | * Set the phase bits to 0, otherwise the NCR5380 won't drive the |
1323 | * data bus during SELECTION. | 1235 | * data bus during SELECTION. |
1324 | */ | 1236 | */ |
1325 | 1237 | ||
1326 | local_irq_save(flags); | ||
1327 | if (hostdata->connected) { | ||
1328 | local_irq_restore(flags); | ||
1329 | return -1; | ||
1330 | } | ||
1331 | NCR5380_write(TARGET_COMMAND_REG, 0); | 1238 | NCR5380_write(TARGET_COMMAND_REG, 0); |
1332 | 1239 | ||
1333 | /* | 1240 | /* |
@@ -1337,96 +1244,77 @@ static int NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd) | |||
1337 | NCR5380_write(OUTPUT_DATA_REG, hostdata->id_mask); | 1244 | NCR5380_write(OUTPUT_DATA_REG, hostdata->id_mask); |
1338 | NCR5380_write(MODE_REG, MR_ARBITRATE); | 1245 | NCR5380_write(MODE_REG, MR_ARBITRATE); |
1339 | 1246 | ||
1340 | local_irq_restore(flags); | 1247 | /* The chip now waits for BUS FREE phase. Then after the 800 ns |
1341 | 1248 | * Bus Free Delay, arbitration will begin. | |
1342 | /* Wait for arbitration logic to complete */ | 1249 | */ |
1343 | #if defined(NCR_TIMEOUT) | ||
1344 | { | ||
1345 | unsigned long timeout = jiffies + 2*NCR_TIMEOUT; | ||
1346 | 1250 | ||
1347 | while (!(NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_PROGRESS) && | 1251 | spin_unlock_irq(&hostdata->lock); |
1348 | time_before(jiffies, timeout) && !hostdata->connected) | 1252 | err = NCR5380_poll_politely2(instance, MODE_REG, MR_ARBITRATE, 0, |
1349 | ; | 1253 | INITIATOR_COMMAND_REG, ICR_ARBITRATION_PROGRESS, |
1350 | if (time_after_eq(jiffies, timeout)) { | 1254 | ICR_ARBITRATION_PROGRESS, HZ); |
1351 | printk("scsi : arbitration timeout at %d\n", __LINE__); | 1255 | spin_lock_irq(&hostdata->lock); |
1352 | NCR5380_write(MODE_REG, MR_BASE); | 1256 | if (!(NCR5380_read(MODE_REG) & MR_ARBITRATE)) { |
1353 | NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask); | 1257 | /* Reselection interrupt */ |
1354 | return -1; | 1258 | goto out; |
1355 | } | ||
1356 | } | 1259 | } |
1357 | #else /* NCR_TIMEOUT */ | 1260 | if (err < 0) { |
1358 | while (!(NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_PROGRESS) && | ||
1359 | !hostdata->connected) | ||
1360 | ; | ||
1361 | #endif | ||
1362 | |||
1363 | dprintk(NDEBUG_ARBITRATION, "scsi%d: arbitration complete\n", HOSTNO); | ||
1364 | |||
1365 | if (hostdata->connected) { | ||
1366 | NCR5380_write(MODE_REG, MR_BASE); | 1261 | NCR5380_write(MODE_REG, MR_BASE); |
1367 | return -1; | 1262 | shost_printk(KERN_ERR, instance, |
1263 | "select: arbitration timeout\n"); | ||
1264 | goto out; | ||
1368 | } | 1265 | } |
1369 | /* | 1266 | spin_unlock_irq(&hostdata->lock); |
1370 | * The arbitration delay is 2.2us, but this is a minimum and there is | ||
1371 | * no maximum so we can safely sleep for ceil(2.2) usecs to accommodate | ||
1372 | * the integral nature of udelay(). | ||
1373 | * | ||
1374 | */ | ||
1375 | 1267 | ||
1268 | /* The SCSI-2 arbitration delay is 2.4 us */ | ||
1376 | udelay(3); | 1269 | udelay(3); |
1377 | 1270 | ||
1378 | /* Check for lost arbitration */ | 1271 | /* Check for lost arbitration */ |
1379 | if ((NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST) || | 1272 | if ((NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST) || |
1380 | (NCR5380_read(CURRENT_SCSI_DATA_REG) & hostdata->id_higher_mask) || | 1273 | (NCR5380_read(CURRENT_SCSI_DATA_REG) & hostdata->id_higher_mask) || |
1381 | (NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST) || | 1274 | (NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST)) { |
1382 | hostdata->connected) { | ||
1383 | NCR5380_write(MODE_REG, MR_BASE); | 1275 | NCR5380_write(MODE_REG, MR_BASE); |
1384 | dprintk(NDEBUG_ARBITRATION, "scsi%d: lost arbitration, deasserting MR_ARBITRATE\n", | 1276 | dsprintk(NDEBUG_ARBITRATION, instance, "lost arbitration, deasserting MR_ARBITRATE\n"); |
1385 | HOSTNO); | 1277 | spin_lock_irq(&hostdata->lock); |
1386 | return -1; | 1278 | goto out; |
1387 | } | 1279 | } |
1388 | 1280 | ||
1389 | /* after/during arbitration, BSY should be asserted. | 1281 | /* After/during arbitration, BSY should be asserted. |
1390 | IBM DPES-31080 Version S31Q works now */ | 1282 | * IBM DPES-31080 Version S31Q works now |
1391 | /* Tnx to Thomas_Roesch@m2.maus.de for finding this! (Roman) */ | 1283 | * Tnx to Thomas_Roesch@m2.maus.de for finding this! (Roman) |
1284 | */ | ||
1392 | NCR5380_write(INITIATOR_COMMAND_REG, | 1285 | NCR5380_write(INITIATOR_COMMAND_REG, |
1393 | ICR_BASE | ICR_ASSERT_SEL | ICR_ASSERT_BSY); | 1286 | ICR_BASE | ICR_ASSERT_SEL | ICR_ASSERT_BSY); |
1394 | 1287 | ||
1395 | if ((NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST) || | ||
1396 | hostdata->connected) { | ||
1397 | NCR5380_write(MODE_REG, MR_BASE); | ||
1398 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); | ||
1399 | dprintk(NDEBUG_ARBITRATION, "scsi%d: lost arbitration, deasserting ICR_ASSERT_SEL\n", | ||
1400 | HOSTNO); | ||
1401 | return -1; | ||
1402 | } | ||
1403 | |||
1404 | /* | 1288 | /* |
1405 | * Again, bus clear + bus settle time is 1.2us, however, this is | 1289 | * Again, bus clear + bus settle time is 1.2us, however, this is |
1406 | * a minimum so we'll udelay ceil(1.2) | 1290 | * a minimum so we'll udelay ceil(1.2) |
1407 | */ | 1291 | */ |
1408 | 1292 | ||
1409 | #ifdef CONFIG_ATARI_SCSI_TOSHIBA_DELAY | 1293 | if (hostdata->flags & FLAG_TOSHIBA_DELAY) |
1410 | /* ++roman: But some targets (see above :-) seem to need a bit more... */ | 1294 | udelay(15); |
1411 | udelay(15); | 1295 | else |
1412 | #else | 1296 | udelay(2); |
1413 | udelay(2); | ||
1414 | #endif | ||
1415 | 1297 | ||
1416 | if (hostdata->connected) { | 1298 | spin_lock_irq(&hostdata->lock); |
1299 | |||
1300 | /* NCR5380_reselect() clears MODE_REG after a reselection interrupt */ | ||
1301 | if (!(NCR5380_read(MODE_REG) & MR_ARBITRATE)) | ||
1302 | goto out; | ||
1303 | |||
1304 | if (!hostdata->selecting) { | ||
1417 | NCR5380_write(MODE_REG, MR_BASE); | 1305 | NCR5380_write(MODE_REG, MR_BASE); |
1418 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); | 1306 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); |
1419 | return -1; | 1307 | goto out; |
1420 | } | 1308 | } |
1421 | 1309 | ||
1422 | dprintk(NDEBUG_ARBITRATION, "scsi%d: won arbitration\n", HOSTNO); | 1310 | dsprintk(NDEBUG_ARBITRATION, instance, "won arbitration\n"); |
1423 | 1311 | ||
1424 | /* | 1312 | /* |
1425 | * Now that we have won arbitration, start Selection process, asserting | 1313 | * Now that we have won arbitration, start Selection process, asserting |
1426 | * the host and target ID's on the SCSI bus. | 1314 | * the host and target ID's on the SCSI bus. |
1427 | */ | 1315 | */ |
1428 | 1316 | ||
1429 | NCR5380_write(OUTPUT_DATA_REG, (hostdata->id_mask | (1 << cmd->device->id))); | 1317 | NCR5380_write(OUTPUT_DATA_REG, hostdata->id_mask | (1 << scmd_id(cmd))); |
1430 | 1318 | ||
1431 | /* | 1319 | /* |
1432 | * Raise ATN while SEL is true before BSY goes false from arbitration, | 1320 | * Raise ATN while SEL is true before BSY goes false from arbitration, |
@@ -1434,22 +1322,18 @@ static int NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd) | |||
1434 | * phase immediately after selection. | 1322 | * phase immediately after selection. |
1435 | */ | 1323 | */ |
1436 | 1324 | ||
1437 | NCR5380_write(INITIATOR_COMMAND_REG, (ICR_BASE | ICR_ASSERT_BSY | | 1325 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_BSY | |
1438 | ICR_ASSERT_DATA | ICR_ASSERT_ATN | ICR_ASSERT_SEL )); | 1326 | ICR_ASSERT_DATA | ICR_ASSERT_ATN | ICR_ASSERT_SEL); |
1439 | NCR5380_write(MODE_REG, MR_BASE); | 1327 | NCR5380_write(MODE_REG, MR_BASE); |
1440 | 1328 | ||
1441 | /* | 1329 | /* |
1442 | * Reselect interrupts must be turned off prior to the dropping of BSY, | 1330 | * Reselect interrupts must be turned off prior to the dropping of BSY, |
1443 | * otherwise we will trigger an interrupt. | 1331 | * otherwise we will trigger an interrupt. |
1444 | */ | 1332 | */ |
1445 | |||
1446 | if (hostdata->connected) { | ||
1447 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); | ||
1448 | return -1; | ||
1449 | } | ||
1450 | |||
1451 | NCR5380_write(SELECT_ENABLE_REG, 0); | 1333 | NCR5380_write(SELECT_ENABLE_REG, 0); |
1452 | 1334 | ||
1335 | spin_unlock_irq(&hostdata->lock); | ||
1336 | |||
1453 | /* | 1337 | /* |
1454 | * The initiator shall then wait at least two deskew delays and release | 1338 | * The initiator shall then wait at least two deskew delays and release |
1455 | * the BSY signal. | 1339 | * the BSY signal. |
@@ -1457,8 +1341,8 @@ static int NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd) | |||
1457 | udelay(1); /* wingel -- wait two bus deskew delay >2*45ns */ | 1341 | udelay(1); /* wingel -- wait two bus deskew delay >2*45ns */ |
1458 | 1342 | ||
1459 | /* Reset BSY */ | 1343 | /* Reset BSY */ |
1460 | NCR5380_write(INITIATOR_COMMAND_REG, (ICR_BASE | ICR_ASSERT_DATA | | 1344 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_DATA | |
1461 | ICR_ASSERT_ATN | ICR_ASSERT_SEL)); | 1345 | ICR_ASSERT_ATN | ICR_ASSERT_SEL); |
1462 | 1346 | ||
1463 | /* | 1347 | /* |
1464 | * Something weird happens when we cease to drive BSY - looks | 1348 | * Something weird happens when we cease to drive BSY - looks |
@@ -1479,45 +1363,39 @@ static int NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd) | |||
1479 | 1363 | ||
1480 | udelay(1); | 1364 | udelay(1); |
1481 | 1365 | ||
1482 | dprintk(NDEBUG_SELECTION, "scsi%d: selecting target %d\n", HOSTNO, cmd->device->id); | 1366 | dsprintk(NDEBUG_SELECTION, instance, "selecting target %d\n", scmd_id(cmd)); |
1483 | 1367 | ||
1484 | /* | 1368 | /* |
1485 | * The SCSI specification calls for a 250 ms timeout for the actual | 1369 | * The SCSI specification calls for a 250 ms timeout for the actual |
1486 | * selection. | 1370 | * selection. |
1487 | */ | 1371 | */ |
1488 | 1372 | ||
1489 | timeout = jiffies + msecs_to_jiffies(250); | 1373 | err = NCR5380_poll_politely(instance, STATUS_REG, SR_BSY, SR_BSY, |
1490 | 1374 | msecs_to_jiffies(250)); | |
1491 | /* | ||
1492 | * XXX very interesting - we're seeing a bounce where the BSY we | ||
1493 | * asserted is being reflected / still asserted (propagation delay?) | ||
1494 | * and it's detecting as true. Sigh. | ||
1495 | */ | ||
1496 | |||
1497 | #if 0 | ||
1498 | /* ++roman: If a target conformed to the SCSI standard, it wouldn't assert | ||
1499 | * IO while SEL is true. But again, there are some disks out the in the | ||
1500 | * world that do that nevertheless. (Somebody claimed that this announces | ||
1501 | * reselection capability of the target.) So we better skip that test and | ||
1502 | * only wait for BSY... (Famous german words: Der Klügere gibt nach :-) | ||
1503 | */ | ||
1504 | |||
1505 | while (time_before(jiffies, timeout) && | ||
1506 | !(NCR5380_read(STATUS_REG) & (SR_BSY | SR_IO))) | ||
1507 | ; | ||
1508 | 1375 | ||
1509 | if ((NCR5380_read(STATUS_REG) & (SR_SEL | SR_IO)) == (SR_SEL | SR_IO)) { | 1376 | if ((NCR5380_read(STATUS_REG) & (SR_SEL | SR_IO)) == (SR_SEL | SR_IO)) { |
1377 | spin_lock_irq(&hostdata->lock); | ||
1510 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); | 1378 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); |
1511 | NCR5380_reselect(instance); | 1379 | NCR5380_reselect(instance); |
1512 | printk(KERN_ERR "scsi%d: reselection after won arbitration?\n", | 1380 | if (!hostdata->connected) |
1513 | HOSTNO); | 1381 | NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask); |
1382 | shost_printk(KERN_ERR, instance, "reselection after won arbitration?\n"); | ||
1383 | goto out; | ||
1384 | } | ||
1385 | |||
1386 | if (err < 0) { | ||
1387 | spin_lock_irq(&hostdata->lock); | ||
1388 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); | ||
1514 | NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask); | 1389 | NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask); |
1515 | return -1; | 1390 | /* Can't touch cmd if it has been reclaimed by the scsi ML */ |
1391 | if (hostdata->selecting) { | ||
1392 | cmd->result = DID_BAD_TARGET << 16; | ||
1393 | complete_cmd(instance, cmd); | ||
1394 | dsprintk(NDEBUG_SELECTION, instance, "target did not respond within 250ms\n"); | ||
1395 | cmd = NULL; | ||
1396 | } | ||
1397 | goto out; | ||
1516 | } | 1398 | } |
1517 | #else | ||
1518 | while (time_before(jiffies, timeout) && !(NCR5380_read(STATUS_REG) & SR_BSY)) | ||
1519 | ; | ||
1520 | #endif | ||
1521 | 1399 | ||
1522 | /* | 1400 | /* |
1523 | * No less than two deskew delays after the initiator detects the | 1401 | * No less than two deskew delays after the initiator detects the |
@@ -1529,29 +1407,6 @@ static int NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd) | |||
1529 | 1407 | ||
1530 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN); | 1408 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN); |
1531 | 1409 | ||
1532 | if (!(NCR5380_read(STATUS_REG) & SR_BSY)) { | ||
1533 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); | ||
1534 | if (hostdata->targets_present & (1 << cmd->device->id)) { | ||
1535 | printk(KERN_ERR "scsi%d: weirdness\n", HOSTNO); | ||
1536 | if (hostdata->restart_select) | ||
1537 | printk(KERN_NOTICE "\trestart select\n"); | ||
1538 | NCR5380_dprint(NDEBUG_ANY, instance); | ||
1539 | NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask); | ||
1540 | return -1; | ||
1541 | } | ||
1542 | cmd->result = DID_BAD_TARGET << 16; | ||
1543 | #ifdef SUPPORT_TAGS | ||
1544 | cmd_free_tag(cmd); | ||
1545 | #endif | ||
1546 | cmd->scsi_done(cmd); | ||
1547 | NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask); | ||
1548 | dprintk(NDEBUG_SELECTION, "scsi%d: target did not respond within 250ms\n", HOSTNO); | ||
1549 | NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask); | ||
1550 | return 0; | ||
1551 | } | ||
1552 | |||
1553 | hostdata->targets_present |= (1 << cmd->device->id); | ||
1554 | |||
1555 | /* | 1410 | /* |
1556 | * Since we followed the SCSI spec, and raised ATN while SEL | 1411 | * Since we followed the SCSI spec, and raised ATN while SEL |
1557 | * was true but before BSY was false during selection, the information | 1412 | * was true but before BSY was false during selection, the information |
@@ -1563,16 +1418,27 @@ static int NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd) | |||
1563 | * until it wraps back to 0. | 1418 | * until it wraps back to 0. |
1564 | * | 1419 | * |
1565 | * XXX - it turns out that there are some broken SCSI-II devices, | 1420 | * XXX - it turns out that there are some broken SCSI-II devices, |
1566 | * which claim to support tagged queuing but fail when more than | 1421 | * which claim to support tagged queuing but fail when more than |
1567 | * some number of commands are issued at once. | 1422 | * some number of commands are issued at once. |
1568 | */ | 1423 | */ |
1569 | 1424 | ||
1570 | /* Wait for start of REQ/ACK handshake */ | 1425 | /* Wait for start of REQ/ACK handshake */ |
1571 | while (!(NCR5380_read(STATUS_REG) & SR_REQ)) | ||
1572 | ; | ||
1573 | 1426 | ||
1574 | dprintk(NDEBUG_SELECTION, "scsi%d: target %d selected, going into MESSAGE OUT phase.\n", | 1427 | err = NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, SR_REQ, HZ); |
1575 | HOSTNO, cmd->device->id); | 1428 | spin_lock_irq(&hostdata->lock); |
1429 | if (err < 0) { | ||
1430 | shost_printk(KERN_ERR, instance, "select: REQ timeout\n"); | ||
1431 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); | ||
1432 | NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask); | ||
1433 | goto out; | ||
1434 | } | ||
1435 | if (!hostdata->selecting) { | ||
1436 | do_abort(instance); | ||
1437 | goto out; | ||
1438 | } | ||
1439 | |||
1440 | dsprintk(NDEBUG_SELECTION, instance, "target %d selected, going into MESSAGE OUT phase.\n", | ||
1441 | scmd_id(cmd)); | ||
1576 | tmp[0] = IDENTIFY(1, cmd->device->lun); | 1442 | tmp[0] = IDENTIFY(1, cmd->device->lun); |
1577 | 1443 | ||
1578 | #ifdef SUPPORT_TAGS | 1444 | #ifdef SUPPORT_TAGS |
@@ -1591,11 +1457,12 @@ static int NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd) | |||
1591 | data = tmp; | 1457 | data = tmp; |
1592 | phase = PHASE_MSGOUT; | 1458 | phase = PHASE_MSGOUT; |
1593 | NCR5380_transfer_pio(instance, &phase, &len, &data); | 1459 | NCR5380_transfer_pio(instance, &phase, &len, &data); |
1594 | dprintk(NDEBUG_SELECTION, "scsi%d: nexus established.\n", HOSTNO); | 1460 | dsprintk(NDEBUG_SELECTION, instance, "nexus established.\n"); |
1595 | /* XXX need to handle errors here */ | 1461 | /* XXX need to handle errors here */ |
1462 | |||
1596 | hostdata->connected = cmd; | 1463 | hostdata->connected = cmd; |
1597 | #ifndef SUPPORT_TAGS | 1464 | #ifndef SUPPORT_TAGS |
1598 | hostdata->busy[cmd->device->id] |= (1 << cmd->device->lun); | 1465 | hostdata->busy[cmd->device->id] |= 1 << cmd->device->lun; |
1599 | #endif | 1466 | #endif |
1600 | #ifdef SUN3_SCSI_VME | 1467 | #ifdef SUN3_SCSI_VME |
1601 | dregs->csr |= CSR_INTR; | 1468 | dregs->csr |= CSR_INTR; |
@@ -1603,24 +1470,30 @@ static int NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd) | |||
1603 | 1470 | ||
1604 | initialize_SCp(cmd); | 1471 | initialize_SCp(cmd); |
1605 | 1472 | ||
1606 | return 0; | 1473 | cmd = NULL; |
1474 | |||
1475 | out: | ||
1476 | if (!hostdata->selecting) | ||
1477 | return NULL; | ||
1478 | hostdata->selecting = NULL; | ||
1479 | return cmd; | ||
1607 | } | 1480 | } |
1608 | 1481 | ||
1609 | /* | 1482 | /* |
1610 | * Function : int NCR5380_transfer_pio (struct Scsi_Host *instance, | 1483 | * Function : int NCR5380_transfer_pio (struct Scsi_Host *instance, |
1611 | * unsigned char *phase, int *count, unsigned char **data) | 1484 | * unsigned char *phase, int *count, unsigned char **data) |
1612 | * | 1485 | * |
1613 | * Purpose : transfers data in given phase using polled I/O | 1486 | * Purpose : transfers data in given phase using polled I/O |
1614 | * | 1487 | * |
1615 | * Inputs : instance - instance of driver, *phase - pointer to | 1488 | * Inputs : instance - instance of driver, *phase - pointer to |
1616 | * what phase is expected, *count - pointer to number of | 1489 | * what phase is expected, *count - pointer to number of |
1617 | * bytes to transfer, **data - pointer to data pointer. | 1490 | * bytes to transfer, **data - pointer to data pointer. |
1618 | * | 1491 | * |
1619 | * Returns : -1 when different phase is entered without transferring | 1492 | * Returns : -1 when different phase is entered without transferring |
1620 | * maximum number of bytes, 0 if all bytes are transferred or exit | 1493 | * maximum number of bytes, 0 if all bytes are transferred or exit |
1621 | * is in same phase. | 1494 | * is in same phase. |
1622 | * | 1495 | * |
1623 | * Also, *phase, *count, *data are modified in place. | 1496 | * Also, *phase, *count, *data are modified in place. |
1624 | * | 1497 | * |
1625 | * XXX Note : handling for bus free may be useful. | 1498 | * XXX Note : handling for bus free may be useful. |
1626 | */ | 1499 | */ |
@@ -1635,9 +1508,9 @@ static int NCR5380_transfer_pio(struct Scsi_Host *instance, | |||
1635 | unsigned char *phase, int *count, | 1508 | unsigned char *phase, int *count, |
1636 | unsigned char **data) | 1509 | unsigned char **data) |
1637 | { | 1510 | { |
1638 | register unsigned char p = *phase, tmp; | 1511 | unsigned char p = *phase, tmp; |
1639 | register int c = *count; | 1512 | int c = *count; |
1640 | register unsigned char *d = *data; | 1513 | unsigned char *d = *data; |
1641 | 1514 | ||
1642 | /* | 1515 | /* |
1643 | * The NCR5380 chip will only drive the SCSI bus when the | 1516 | * The NCR5380 chip will only drive the SCSI bus when the |
@@ -1652,14 +1525,15 @@ static int NCR5380_transfer_pio(struct Scsi_Host *instance, | |||
1652 | * Wait for assertion of REQ, after which the phase bits will be | 1525 | * Wait for assertion of REQ, after which the phase bits will be |
1653 | * valid | 1526 | * valid |
1654 | */ | 1527 | */ |
1655 | while (!((tmp = NCR5380_read(STATUS_REG)) & SR_REQ)) | ||
1656 | ; | ||
1657 | 1528 | ||
1658 | dprintk(NDEBUG_HANDSHAKE, "scsi%d: REQ detected\n", HOSTNO); | 1529 | if (NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, SR_REQ, HZ) < 0) |
1530 | break; | ||
1531 | |||
1532 | dsprintk(NDEBUG_HANDSHAKE, instance, "REQ asserted\n"); | ||
1659 | 1533 | ||
1660 | /* Check for phase mismatch */ | 1534 | /* Check for phase mismatch */ |
1661 | if ((tmp & PHASE_MASK) != p) { | 1535 | if ((NCR5380_read(STATUS_REG) & PHASE_MASK) != p) { |
1662 | dprintk(NDEBUG_PIO, "scsi%d: phase mismatch\n", HOSTNO); | 1536 | dsprintk(NDEBUG_PIO, instance, "phase mismatch\n"); |
1663 | NCR5380_dprint_phase(NDEBUG_PIO, instance); | 1537 | NCR5380_dprint_phase(NDEBUG_PIO, instance); |
1664 | break; | 1538 | break; |
1665 | } | 1539 | } |
@@ -1684,35 +1558,36 @@ static int NCR5380_transfer_pio(struct Scsi_Host *instance, | |||
1684 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_DATA); | 1558 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_DATA); |
1685 | NCR5380_dprint(NDEBUG_PIO, instance); | 1559 | NCR5380_dprint(NDEBUG_PIO, instance); |
1686 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | | 1560 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | |
1687 | ICR_ASSERT_DATA | ICR_ASSERT_ACK); | 1561 | ICR_ASSERT_DATA | ICR_ASSERT_ACK); |
1688 | } else { | 1562 | } else { |
1689 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | | 1563 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | |
1690 | ICR_ASSERT_DATA | ICR_ASSERT_ATN); | 1564 | ICR_ASSERT_DATA | ICR_ASSERT_ATN); |
1691 | NCR5380_dprint(NDEBUG_PIO, instance); | 1565 | NCR5380_dprint(NDEBUG_PIO, instance); |
1692 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | | 1566 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | |
1693 | ICR_ASSERT_DATA | ICR_ASSERT_ATN | ICR_ASSERT_ACK); | 1567 | ICR_ASSERT_DATA | ICR_ASSERT_ATN | ICR_ASSERT_ACK); |
1694 | } | 1568 | } |
1695 | } else { | 1569 | } else { |
1696 | NCR5380_dprint(NDEBUG_PIO, instance); | 1570 | NCR5380_dprint(NDEBUG_PIO, instance); |
1697 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ACK); | 1571 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ACK); |
1698 | } | 1572 | } |
1699 | 1573 | ||
1700 | while (NCR5380_read(STATUS_REG) & SR_REQ) | 1574 | if (NCR5380_poll_politely(instance, |
1701 | ; | 1575 | STATUS_REG, SR_REQ, 0, 5 * HZ) < 0) |
1576 | break; | ||
1702 | 1577 | ||
1703 | dprintk(NDEBUG_HANDSHAKE, "scsi%d: req false, handshake complete\n", HOSTNO); | 1578 | dsprintk(NDEBUG_HANDSHAKE, instance, "REQ negated, handshake complete\n"); |
1704 | 1579 | ||
1705 | /* | 1580 | /* |
1706 | * We have several special cases to consider during REQ/ACK handshaking : | 1581 | * We have several special cases to consider during REQ/ACK handshaking : |
1707 | * 1. We were in MSGOUT phase, and we are on the last byte of the | 1582 | * 1. We were in MSGOUT phase, and we are on the last byte of the |
1708 | * message. ATN must be dropped as ACK is dropped. | 1583 | * message. ATN must be dropped as ACK is dropped. |
1709 | * | 1584 | * |
1710 | * 2. We are in a MSGIN phase, and we are on the last byte of the | 1585 | * 2. We are in a MSGIN phase, and we are on the last byte of the |
1711 | * message. We must exit with ACK asserted, so that the calling | 1586 | * message. We must exit with ACK asserted, so that the calling |
1712 | * code may raise ATN before dropping ACK to reject the message. | 1587 | * code may raise ATN before dropping ACK to reject the message. |
1713 | * | 1588 | * |
1714 | * 3. ACK and ATN are clear and the target may proceed as normal. | 1589 | * 3. ACK and ATN are clear and the target may proceed as normal. |
1715 | */ | 1590 | */ |
1716 | if (!(p == PHASE_MSGIN && c == 1)) { | 1591 | if (!(p == PHASE_MSGIN && c == 1)) { |
1717 | if (p == PHASE_MSGOUT && c > 1) | 1592 | if (p == PHASE_MSGOUT && c > 1) |
1718 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN); | 1593 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN); |
@@ -1721,16 +1596,16 @@ static int NCR5380_transfer_pio(struct Scsi_Host *instance, | |||
1721 | } | 1596 | } |
1722 | } while (--c); | 1597 | } while (--c); |
1723 | 1598 | ||
1724 | dprintk(NDEBUG_PIO, "scsi%d: residual %d\n", HOSTNO, c); | 1599 | dsprintk(NDEBUG_PIO, instance, "residual %d\n", c); |
1725 | 1600 | ||
1726 | *count = c; | 1601 | *count = c; |
1727 | *data = d; | 1602 | *data = d; |
1728 | tmp = NCR5380_read(STATUS_REG); | 1603 | tmp = NCR5380_read(STATUS_REG); |
1729 | /* The phase read from the bus is valid if either REQ is (already) | 1604 | /* The phase read from the bus is valid if either REQ is (already) |
1730 | * asserted or if ACK hasn't been released yet. The latter is the case if | 1605 | * asserted or if ACK hasn't been released yet. The latter applies if |
1731 | * we're in MSGIN and all wanted bytes have been received. | 1606 | * we're in MSG IN, DATA IN or STATUS and all bytes have been received. |
1732 | */ | 1607 | */ |
1733 | if ((tmp & SR_REQ) || (p == PHASE_MSGIN && c == 0)) | 1608 | if ((tmp & SR_REQ) || ((tmp & SR_IO) && c == 0)) |
1734 | *phase = tmp & PHASE_MASK; | 1609 | *phase = tmp & PHASE_MASK; |
1735 | else | 1610 | else |
1736 | *phase = PHASE_UNKNOWN; | 1611 | *phase = PHASE_UNKNOWN; |
@@ -1741,19 +1616,45 @@ static int NCR5380_transfer_pio(struct Scsi_Host *instance, | |||
1741 | return -1; | 1616 | return -1; |
1742 | } | 1617 | } |
1743 | 1618 | ||
1744 | /* | 1619 | /** |
1745 | * Function : do_abort (Scsi_Host *host) | 1620 | * do_reset - issue a reset command |
1621 | * @instance: adapter to reset | ||
1746 | * | 1622 | * |
1747 | * Purpose : abort the currently established nexus. Should only be | 1623 | * Issue a reset sequence to the NCR5380 and try and get the bus |
1748 | * called from a routine which can drop into a | 1624 | * back into sane shape. |
1749 | * | 1625 | * |
1750 | * Returns : 0 on success, -1 on failure. | 1626 | * This clears the reset interrupt flag because there may be no handler for |
1627 | * it. When the driver is initialized, the NCR5380_intr() handler has not yet | ||
1628 | * been installed. And when in EH we may have released the ST DMA interrupt. | ||
1629 | */ | ||
1630 | |||
1631 | static void do_reset(struct Scsi_Host *instance) | ||
1632 | { | ||
1633 | unsigned long flags; | ||
1634 | |||
1635 | local_irq_save(flags); | ||
1636 | NCR5380_write(TARGET_COMMAND_REG, | ||
1637 | PHASE_SR_TO_TCR(NCR5380_read(STATUS_REG) & PHASE_MASK)); | ||
1638 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_RST); | ||
1639 | udelay(50); | ||
1640 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); | ||
1641 | (void)NCR5380_read(RESET_PARITY_INTERRUPT_REG); | ||
1642 | local_irq_restore(flags); | ||
1643 | } | ||
1644 | |||
1645 | /** | ||
1646 | * do_abort - abort the currently established nexus by going to | ||
1647 | * MESSAGE OUT phase and sending an ABORT message. | ||
1648 | * @instance: relevant scsi host instance | ||
1649 | * | ||
1650 | * Returns 0 on success, -1 on failure. | ||
1751 | */ | 1651 | */ |
1752 | 1652 | ||
1753 | static int do_abort(struct Scsi_Host *instance) | 1653 | static int do_abort(struct Scsi_Host *instance) |
1754 | { | 1654 | { |
1755 | unsigned char tmp, *msgptr, phase; | 1655 | unsigned char *msgptr, phase, tmp; |
1756 | int len; | 1656 | int len; |
1657 | int rc; | ||
1757 | 1658 | ||
1758 | /* Request message out phase */ | 1659 | /* Request message out phase */ |
1759 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN); | 1660 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN); |
@@ -1768,16 +1669,20 @@ static int do_abort(struct Scsi_Host *instance) | |||
1768 | * the target sees, so we just handshake. | 1669 | * the target sees, so we just handshake. |
1769 | */ | 1670 | */ |
1770 | 1671 | ||
1771 | while (!((tmp = NCR5380_read(STATUS_REG)) & SR_REQ)) | 1672 | rc = NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, SR_REQ, 10 * HZ); |
1772 | ; | 1673 | if (rc < 0) |
1674 | goto timeout; | ||
1675 | |||
1676 | tmp = NCR5380_read(STATUS_REG) & PHASE_MASK; | ||
1773 | 1677 | ||
1774 | NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(tmp)); | 1678 | NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(tmp)); |
1775 | 1679 | ||
1776 | if ((tmp & PHASE_MASK) != PHASE_MSGOUT) { | 1680 | if (tmp != PHASE_MSGOUT) { |
1777 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN | | 1681 | NCR5380_write(INITIATOR_COMMAND_REG, |
1778 | ICR_ASSERT_ACK); | 1682 | ICR_BASE | ICR_ASSERT_ATN | ICR_ASSERT_ACK); |
1779 | while (NCR5380_read(STATUS_REG) & SR_REQ) | 1683 | rc = NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, 0, 3 * HZ); |
1780 | ; | 1684 | if (rc < 0) |
1685 | goto timeout; | ||
1781 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN); | 1686 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN); |
1782 | } | 1687 | } |
1783 | 1688 | ||
@@ -1793,26 +1698,29 @@ static int do_abort(struct Scsi_Host *instance) | |||
1793 | */ | 1698 | */ |
1794 | 1699 | ||
1795 | return len ? -1 : 0; | 1700 | return len ? -1 : 0; |
1701 | |||
1702 | timeout: | ||
1703 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); | ||
1704 | return -1; | ||
1796 | } | 1705 | } |
1797 | 1706 | ||
1798 | #if defined(REAL_DMA) | 1707 | #if defined(REAL_DMA) |
1799 | /* | 1708 | /* |
1800 | * Function : int NCR5380_transfer_dma (struct Scsi_Host *instance, | 1709 | * Function : int NCR5380_transfer_dma (struct Scsi_Host *instance, |
1801 | * unsigned char *phase, int *count, unsigned char **data) | 1710 | * unsigned char *phase, int *count, unsigned char **data) |
1802 | * | 1711 | * |
1803 | * Purpose : transfers data in given phase using either real | 1712 | * Purpose : transfers data in given phase using either real |
1804 | * or pseudo DMA. | 1713 | * or pseudo DMA. |
1805 | * | 1714 | * |
1806 | * Inputs : instance - instance of driver, *phase - pointer to | 1715 | * Inputs : instance - instance of driver, *phase - pointer to |
1807 | * what phase is expected, *count - pointer to number of | 1716 | * what phase is expected, *count - pointer to number of |
1808 | * bytes to transfer, **data - pointer to data pointer. | 1717 | * bytes to transfer, **data - pointer to data pointer. |
1809 | * | 1718 | * |
1810 | * Returns : -1 when different phase is entered without transferring | 1719 | * Returns : -1 when different phase is entered without transferring |
1811 | * maximum number of bytes, 0 if all bytes or transferred or exit | 1720 | * maximum number of bytes, 0 if all bytes or transferred or exit |
1812 | * is in same phase. | 1721 | * is in same phase. |
1813 | * | ||
1814 | * Also, *phase, *count, *data are modified in place. | ||
1815 | * | 1722 | * |
1723 | * Also, *phase, *count, *data are modified in place. | ||
1816 | */ | 1724 | */ |
1817 | 1725 | ||
1818 | 1726 | ||
@@ -1820,10 +1728,9 @@ static int NCR5380_transfer_dma(struct Scsi_Host *instance, | |||
1820 | unsigned char *phase, int *count, | 1728 | unsigned char *phase, int *count, |
1821 | unsigned char **data) | 1729 | unsigned char **data) |
1822 | { | 1730 | { |
1823 | SETUP_HOSTDATA(instance); | 1731 | struct NCR5380_hostdata *hostdata = shost_priv(instance); |
1824 | register int c = *count; | 1732 | register int c = *count; |
1825 | register unsigned char p = *phase; | 1733 | register unsigned char p = *phase; |
1826 | unsigned long flags; | ||
1827 | 1734 | ||
1828 | #if defined(CONFIG_SUN3) | 1735 | #if defined(CONFIG_SUN3) |
1829 | /* sanity check */ | 1736 | /* sanity check */ |
@@ -1834,29 +1741,22 @@ static int NCR5380_transfer_dma(struct Scsi_Host *instance, | |||
1834 | } | 1741 | } |
1835 | hostdata->dma_len = c; | 1742 | hostdata->dma_len = c; |
1836 | 1743 | ||
1837 | dprintk(NDEBUG_DMA, "scsi%d: initializing DMA for %s, %d bytes %s %p\n", | 1744 | dsprintk(NDEBUG_DMA, instance, "initializing DMA %s: length %d, address %p\n", |
1838 | instance->host_no, (p & SR_IO) ? "reading" : "writing", | 1745 | (p & SR_IO) ? "receive" : "send", c, *data); |
1839 | c, (p & SR_IO) ? "to" : "from", *data); | ||
1840 | 1746 | ||
1841 | /* netbsd turns off ints here, why not be safe and do it too */ | 1747 | /* netbsd turns off ints here, why not be safe and do it too */ |
1842 | local_irq_save(flags); | ||
1843 | 1748 | ||
1844 | /* send start chain */ | 1749 | /* send start chain */ |
1845 | sun3scsi_dma_start(c, *data); | 1750 | sun3scsi_dma_start(c, *data); |
1846 | 1751 | ||
1752 | NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(p)); | ||
1753 | NCR5380_write(MODE_REG, MR_BASE | MR_DMA_MODE | MR_MONITOR_BSY | | ||
1754 | MR_ENABLE_EOP_INTR); | ||
1847 | if (p & SR_IO) { | 1755 | if (p & SR_IO) { |
1848 | NCR5380_write(TARGET_COMMAND_REG, 1); | ||
1849 | NCR5380_read(RESET_PARITY_INTERRUPT_REG); | ||
1850 | NCR5380_write(INITIATOR_COMMAND_REG, 0); | 1756 | NCR5380_write(INITIATOR_COMMAND_REG, 0); |
1851 | NCR5380_write(MODE_REG, | ||
1852 | (NCR5380_read(MODE_REG) | MR_DMA_MODE | MR_ENABLE_EOP_INTR)); | ||
1853 | NCR5380_write(START_DMA_INITIATOR_RECEIVE_REG, 0); | 1757 | NCR5380_write(START_DMA_INITIATOR_RECEIVE_REG, 0); |
1854 | } else { | 1758 | } else { |
1855 | NCR5380_write(TARGET_COMMAND_REG, 0); | ||
1856 | NCR5380_read(RESET_PARITY_INTERRUPT_REG); | ||
1857 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_ASSERT_DATA); | 1759 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_ASSERT_DATA); |
1858 | NCR5380_write(MODE_REG, | ||
1859 | (NCR5380_read(MODE_REG) | MR_DMA_MODE | MR_ENABLE_EOP_INTR)); | ||
1860 | NCR5380_write(START_DMA_SEND_REG, 0); | 1760 | NCR5380_write(START_DMA_SEND_REG, 0); |
1861 | } | 1761 | } |
1862 | 1762 | ||
@@ -1864,8 +1764,6 @@ static int NCR5380_transfer_dma(struct Scsi_Host *instance, | |||
1864 | dregs->csr |= CSR_DMA_ENABLE; | 1764 | dregs->csr |= CSR_DMA_ENABLE; |
1865 | #endif | 1765 | #endif |
1866 | 1766 | ||
1867 | local_irq_restore(flags); | ||
1868 | |||
1869 | sun3_dma_active = 1; | 1767 | sun3_dma_active = 1; |
1870 | 1768 | ||
1871 | #else /* !defined(CONFIG_SUN3) */ | 1769 | #else /* !defined(CONFIG_SUN3) */ |
@@ -1880,25 +1778,20 @@ static int NCR5380_transfer_dma(struct Scsi_Host *instance, | |||
1880 | if (hostdata->read_overruns && (p & SR_IO)) | 1778 | if (hostdata->read_overruns && (p & SR_IO)) |
1881 | c -= hostdata->read_overruns; | 1779 | c -= hostdata->read_overruns; |
1882 | 1780 | ||
1883 | dprintk(NDEBUG_DMA, "scsi%d: initializing DMA for %s, %d bytes %s %p\n", | 1781 | dsprintk(NDEBUG_DMA, instance, "initializing DMA %s: length %d, address %p\n", |
1884 | HOSTNO, (p & SR_IO) ? "reading" : "writing", | 1782 | (p & SR_IO) ? "receive" : "send", c, d); |
1885 | c, (p & SR_IO) ? "to" : "from", d); | ||
1886 | 1783 | ||
1887 | NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(p)); | 1784 | NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(p)); |
1888 | 1785 | NCR5380_write(MODE_REG, MR_BASE | MR_DMA_MODE | MR_MONITOR_BSY | | |
1889 | #ifdef REAL_DMA | 1786 | MR_ENABLE_EOP_INTR); |
1890 | NCR5380_write(MODE_REG, MR_BASE | MR_DMA_MODE | MR_ENABLE_EOP_INTR | MR_MONITOR_BSY); | ||
1891 | #endif /* def REAL_DMA */ | ||
1892 | 1787 | ||
1893 | if (!(hostdata->flags & FLAG_LATE_DMA_SETUP)) { | 1788 | if (!(hostdata->flags & FLAG_LATE_DMA_SETUP)) { |
1894 | /* On the Medusa, it is a must to initialize the DMA before | 1789 | /* On the Medusa, it is a must to initialize the DMA before |
1895 | * starting the NCR. This is also the cleaner way for the TT. | 1790 | * starting the NCR. This is also the cleaner way for the TT. |
1896 | */ | 1791 | */ |
1897 | local_irq_save(flags); | ||
1898 | hostdata->dma_len = (p & SR_IO) ? | 1792 | hostdata->dma_len = (p & SR_IO) ? |
1899 | NCR5380_dma_read_setup(instance, d, c) : | 1793 | NCR5380_dma_read_setup(instance, d, c) : |
1900 | NCR5380_dma_write_setup(instance, d, c); | 1794 | NCR5380_dma_write_setup(instance, d, c); |
1901 | local_irq_restore(flags); | ||
1902 | } | 1795 | } |
1903 | 1796 | ||
1904 | if (p & SR_IO) | 1797 | if (p & SR_IO) |
@@ -1912,11 +1805,9 @@ static int NCR5380_transfer_dma(struct Scsi_Host *instance, | |||
1912 | /* On the Falcon, the DMA setup must be done after the last */ | 1805 | /* On the Falcon, the DMA setup must be done after the last */ |
1913 | /* NCR access, else the DMA setup gets trashed! | 1806 | /* NCR access, else the DMA setup gets trashed! |
1914 | */ | 1807 | */ |
1915 | local_irq_save(flags); | ||
1916 | hostdata->dma_len = (p & SR_IO) ? | 1808 | hostdata->dma_len = (p & SR_IO) ? |
1917 | NCR5380_dma_read_setup(instance, d, c) : | 1809 | NCR5380_dma_read_setup(instance, d, c) : |
1918 | NCR5380_dma_write_setup(instance, d, c); | 1810 | NCR5380_dma_write_setup(instance, d, c); |
1919 | local_irq_restore(flags); | ||
1920 | } | 1811 | } |
1921 | #endif /* !defined(CONFIG_SUN3) */ | 1812 | #endif /* !defined(CONFIG_SUN3) */ |
1922 | 1813 | ||
@@ -1928,23 +1819,22 @@ static int NCR5380_transfer_dma(struct Scsi_Host *instance, | |||
1928 | * Function : NCR5380_information_transfer (struct Scsi_Host *instance) | 1819 | * Function : NCR5380_information_transfer (struct Scsi_Host *instance) |
1929 | * | 1820 | * |
1930 | * Purpose : run through the various SCSI phases and do as the target | 1821 | * Purpose : run through the various SCSI phases and do as the target |
1931 | * directs us to. Operates on the currently connected command, | 1822 | * directs us to. Operates on the currently connected command, |
1932 | * instance->connected. | 1823 | * instance->connected. |
1933 | * | 1824 | * |
1934 | * Inputs : instance, instance for which we are doing commands | 1825 | * Inputs : instance, instance for which we are doing commands |
1935 | * | 1826 | * |
1936 | * Side effects : SCSI things happen, the disconnected queue will be | 1827 | * Side effects : SCSI things happen, the disconnected queue will be |
1937 | * modified if a command disconnects, *instance->connected will | 1828 | * modified if a command disconnects, *instance->connected will |
1938 | * change. | 1829 | * change. |
1939 | * | 1830 | * |
1940 | * XXX Note : we need to watch for bus free or a reset condition here | 1831 | * XXX Note : we need to watch for bus free or a reset condition here |
1941 | * to recover from an unexpected bus free condition. | 1832 | * to recover from an unexpected bus free condition. |
1942 | */ | 1833 | */ |
1943 | 1834 | ||
1944 | static void NCR5380_information_transfer(struct Scsi_Host *instance) | 1835 | static void NCR5380_information_transfer(struct Scsi_Host *instance) |
1945 | { | 1836 | { |
1946 | SETUP_HOSTDATA(instance); | 1837 | struct NCR5380_hostdata *hostdata = shost_priv(instance); |
1947 | unsigned long flags; | ||
1948 | unsigned char msgout = NOP; | 1838 | unsigned char msgout = NOP; |
1949 | int sink = 0; | 1839 | int sink = 0; |
1950 | int len; | 1840 | int len; |
@@ -1953,13 +1843,15 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) | |||
1953 | #endif | 1843 | #endif |
1954 | unsigned char *data; | 1844 | unsigned char *data; |
1955 | unsigned char phase, tmp, extended_msg[10], old_phase = 0xff; | 1845 | unsigned char phase, tmp, extended_msg[10], old_phase = 0xff; |
1956 | struct scsi_cmnd *cmd = (struct scsi_cmnd *) hostdata->connected; | 1846 | struct scsi_cmnd *cmd; |
1957 | 1847 | ||
1958 | #ifdef SUN3_SCSI_VME | 1848 | #ifdef SUN3_SCSI_VME |
1959 | dregs->csr |= CSR_INTR; | 1849 | dregs->csr |= CSR_INTR; |
1960 | #endif | 1850 | #endif |
1961 | 1851 | ||
1962 | while (1) { | 1852 | while ((cmd = hostdata->connected)) { |
1853 | struct NCR5380_cmd *ncmd = scsi_cmd_priv(cmd); | ||
1854 | |||
1963 | tmp = NCR5380_read(STATUS_REG); | 1855 | tmp = NCR5380_read(STATUS_REG); |
1964 | /* We only have a valid SCSI phase when REQ is asserted */ | 1856 | /* We only have a valid SCSI phase when REQ is asserted */ |
1965 | if (tmp & SR_REQ) { | 1857 | if (tmp & SR_REQ) { |
@@ -1984,7 +1876,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) | |||
1984 | /* this command setup for dma yet? */ | 1876 | /* this command setup for dma yet? */ |
1985 | if ((count >= DMA_MIN_SIZE) && (sun3_dma_setup_done != cmd)) { | 1877 | if ((count >= DMA_MIN_SIZE) && (sun3_dma_setup_done != cmd)) { |
1986 | if (cmd->request->cmd_type == REQ_TYPE_FS) { | 1878 | if (cmd->request->cmd_type == REQ_TYPE_FS) { |
1987 | sun3scsi_dma_setup(d, count, | 1879 | sun3scsi_dma_setup(instance, d, count, |
1988 | rq_data_dir(cmd->request)); | 1880 | rq_data_dir(cmd->request)); |
1989 | sun3_dma_setup_done = cmd; | 1881 | sun3_dma_setup_done = cmd; |
1990 | } | 1882 | } |
@@ -2000,11 +1892,11 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) | |||
2000 | NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(tmp)); | 1892 | NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(tmp)); |
2001 | 1893 | ||
2002 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN | | 1894 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN | |
2003 | ICR_ASSERT_ACK); | 1895 | ICR_ASSERT_ACK); |
2004 | while (NCR5380_read(STATUS_REG) & SR_REQ) | 1896 | while (NCR5380_read(STATUS_REG) & SR_REQ) |
2005 | ; | 1897 | ; |
2006 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | | 1898 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | |
2007 | ICR_ASSERT_ATN); | 1899 | ICR_ASSERT_ATN); |
2008 | sink = 0; | 1900 | sink = 0; |
2009 | continue; | 1901 | continue; |
2010 | } | 1902 | } |
@@ -2012,12 +1904,11 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) | |||
2012 | switch (phase) { | 1904 | switch (phase) { |
2013 | case PHASE_DATAOUT: | 1905 | case PHASE_DATAOUT: |
2014 | #if (NDEBUG & NDEBUG_NO_DATAOUT) | 1906 | #if (NDEBUG & NDEBUG_NO_DATAOUT) |
2015 | printk("scsi%d: NDEBUG_NO_DATAOUT set, attempted DATAOUT " | 1907 | shost_printk(KERN_DEBUG, instance, "NDEBUG_NO_DATAOUT set, attempted DATAOUT aborted\n"); |
2016 | "aborted\n", HOSTNO); | ||
2017 | sink = 1; | 1908 | sink = 1; |
2018 | do_abort(instance); | 1909 | do_abort(instance); |
2019 | cmd->result = DID_ERROR << 16; | 1910 | cmd->result = DID_ERROR << 16; |
2020 | cmd->scsi_done(cmd); | 1911 | complete_cmd(instance, cmd); |
2021 | return; | 1912 | return; |
2022 | #endif | 1913 | #endif |
2023 | case PHASE_DATAIN: | 1914 | case PHASE_DATAIN: |
@@ -2031,13 +1922,10 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) | |||
2031 | --cmd->SCp.buffers_residual; | 1922 | --cmd->SCp.buffers_residual; |
2032 | cmd->SCp.this_residual = cmd->SCp.buffer->length; | 1923 | cmd->SCp.this_residual = cmd->SCp.buffer->length; |
2033 | cmd->SCp.ptr = sg_virt(cmd->SCp.buffer); | 1924 | cmd->SCp.ptr = sg_virt(cmd->SCp.buffer); |
2034 | /* ++roman: Try to merge some scatter-buffers if | ||
2035 | * they are at contiguous physical addresses. | ||
2036 | */ | ||
2037 | merge_contiguous_buffers(cmd); | 1925 | merge_contiguous_buffers(cmd); |
2038 | dprintk(NDEBUG_INFORMATION, "scsi%d: %d bytes and %d buffers left\n", | 1926 | dsprintk(NDEBUG_INFORMATION, instance, "%d bytes and %d buffers left\n", |
2039 | HOSTNO, cmd->SCp.this_residual, | 1927 | cmd->SCp.this_residual, |
2040 | cmd->SCp.buffers_residual); | 1928 | cmd->SCp.buffers_residual); |
2041 | } | 1929 | } |
2042 | 1930 | ||
2043 | /* | 1931 | /* |
@@ -2051,16 +1939,18 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) | |||
2051 | */ | 1939 | */ |
2052 | 1940 | ||
2053 | /* ++roman: I suggest, this should be | 1941 | /* ++roman: I suggest, this should be |
2054 | * #if def(REAL_DMA) | 1942 | * #if def(REAL_DMA) |
2055 | * instead of leaving REAL_DMA out. | 1943 | * instead of leaving REAL_DMA out. |
2056 | */ | 1944 | */ |
2057 | 1945 | ||
2058 | #if defined(REAL_DMA) | 1946 | #if defined(REAL_DMA) |
2059 | if ( | ||
2060 | #if !defined(CONFIG_SUN3) | 1947 | #if !defined(CONFIG_SUN3) |
2061 | !cmd->device->borken && | 1948 | transfersize = 0; |
1949 | if (!cmd->device->borken) | ||
2062 | #endif | 1950 | #endif |
2063 | (transfersize = NCR5380_dma_xfer_len(instance, cmd, phase)) >= DMA_MIN_SIZE) { | 1951 | transfersize = NCR5380_dma_xfer_len(instance, cmd, phase); |
1952 | |||
1953 | if (transfersize >= DMA_MIN_SIZE) { | ||
2064 | len = transfersize; | 1954 | len = transfersize; |
2065 | cmd->SCp.phase = phase; | 1955 | cmd->SCp.phase = phase; |
2066 | if (NCR5380_transfer_dma(instance, &phase, | 1956 | if (NCR5380_transfer_dma(instance, &phase, |
@@ -2068,16 +1958,15 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) | |||
2068 | /* | 1958 | /* |
2069 | * If the watchdog timer fires, all future | 1959 | * If the watchdog timer fires, all future |
2070 | * accesses to this device will use the | 1960 | * accesses to this device will use the |
2071 | * polled-IO. */ | 1961 | * polled-IO. |
1962 | */ | ||
2072 | scmd_printk(KERN_INFO, cmd, | 1963 | scmd_printk(KERN_INFO, cmd, |
2073 | "switching to slow handshake\n"); | 1964 | "switching to slow handshake\n"); |
2074 | cmd->device->borken = 1; | 1965 | cmd->device->borken = 1; |
2075 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | | ||
2076 | ICR_ASSERT_ATN); | ||
2077 | sink = 1; | 1966 | sink = 1; |
2078 | do_abort(instance); | 1967 | do_abort(instance); |
2079 | cmd->result = DID_ERROR << 16; | 1968 | cmd->result = DID_ERROR << 16; |
2080 | cmd->scsi_done(cmd); | 1969 | complete_cmd(instance, cmd); |
2081 | /* XXX - need to source or sink data here, as appropriate */ | 1970 | /* XXX - need to source or sink data here, as appropriate */ |
2082 | } else { | 1971 | } else { |
2083 | #ifdef REAL_DMA | 1972 | #ifdef REAL_DMA |
@@ -2093,9 +1982,13 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) | |||
2093 | } | 1982 | } |
2094 | } else | 1983 | } else |
2095 | #endif /* defined(REAL_DMA) */ | 1984 | #endif /* defined(REAL_DMA) */ |
1985 | { | ||
1986 | spin_unlock_irq(&hostdata->lock); | ||
2096 | NCR5380_transfer_pio(instance, &phase, | 1987 | NCR5380_transfer_pio(instance, &phase, |
2097 | (int *)&cmd->SCp.this_residual, | 1988 | (int *)&cmd->SCp.this_residual, |
2098 | (unsigned char **)&cmd->SCp.ptr); | 1989 | (unsigned char **)&cmd->SCp.ptr); |
1990 | spin_lock_irq(&hostdata->lock); | ||
1991 | } | ||
2099 | #if defined(CONFIG_SUN3) && defined(REAL_DMA) | 1992 | #if defined(CONFIG_SUN3) && defined(REAL_DMA) |
2100 | /* if we had intended to dma that command clear it */ | 1993 | /* if we had intended to dma that command clear it */ |
2101 | if (sun3_dma_setup_done == cmd) | 1994 | if (sun3_dma_setup_done == cmd) |
@@ -2105,162 +1998,64 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) | |||
2105 | case PHASE_MSGIN: | 1998 | case PHASE_MSGIN: |
2106 | len = 1; | 1999 | len = 1; |
2107 | data = &tmp; | 2000 | data = &tmp; |
2108 | NCR5380_write(SELECT_ENABLE_REG, 0); /* disable reselects */ | ||
2109 | NCR5380_transfer_pio(instance, &phase, &len, &data); | 2001 | NCR5380_transfer_pio(instance, &phase, &len, &data); |
2110 | cmd->SCp.Message = tmp; | 2002 | cmd->SCp.Message = tmp; |
2111 | 2003 | ||
2112 | switch (tmp) { | 2004 | switch (tmp) { |
2113 | /* | ||
2114 | * Linking lets us reduce the time required to get the | ||
2115 | * next command out to the device, hopefully this will | ||
2116 | * mean we don't waste another revolution due to the delays | ||
2117 | * required by ARBITRATION and another SELECTION. | ||
2118 | * | ||
2119 | * In the current implementation proposal, low level drivers | ||
2120 | * merely have to start the next command, pointed to by | ||
2121 | * next_link, done() is called as with unlinked commands. | ||
2122 | */ | ||
2123 | #ifdef LINKED | ||
2124 | case LINKED_CMD_COMPLETE: | ||
2125 | case LINKED_FLG_CMD_COMPLETE: | ||
2126 | /* Accept message by clearing ACK */ | ||
2127 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); | ||
2128 | |||
2129 | dprintk(NDEBUG_LINKED, "scsi%d: target %d lun %llu linked command " | ||
2130 | "complete.\n", HOSTNO, cmd->device->id, cmd->device->lun); | ||
2131 | |||
2132 | /* Enable reselect interrupts */ | ||
2133 | NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask); | ||
2134 | /* | ||
2135 | * Sanity check : A linked command should only terminate | ||
2136 | * with one of these messages if there are more linked | ||
2137 | * commands available. | ||
2138 | */ | ||
2139 | |||
2140 | if (!cmd->next_link) { | ||
2141 | printk(KERN_NOTICE "scsi%d: target %d lun %llu " | ||
2142 | "linked command complete, no next_link\n", | ||
2143 | HOSTNO, cmd->device->id, cmd->device->lun); | ||
2144 | sink = 1; | ||
2145 | do_abort(instance); | ||
2146 | return; | ||
2147 | } | ||
2148 | |||
2149 | initialize_SCp(cmd->next_link); | ||
2150 | /* The next command is still part of this process; copy it | ||
2151 | * and don't free it! */ | ||
2152 | cmd->next_link->tag = cmd->tag; | ||
2153 | cmd->result = cmd->SCp.Status | (cmd->SCp.Message << 8); | ||
2154 | dprintk(NDEBUG_LINKED, "scsi%d: target %d lun %llu linked request " | ||
2155 | "done, calling scsi_done().\n", | ||
2156 | HOSTNO, cmd->device->id, cmd->device->lun); | ||
2157 | cmd->scsi_done(cmd); | ||
2158 | cmd = hostdata->connected; | ||
2159 | break; | ||
2160 | #endif /* def LINKED */ | ||
2161 | case ABORT: | 2005 | case ABORT: |
2162 | case COMMAND_COMPLETE: | 2006 | case COMMAND_COMPLETE: |
2163 | /* Accept message by clearing ACK */ | 2007 | /* Accept message by clearing ACK */ |
2164 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); | 2008 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); |
2165 | dprintk(NDEBUG_QUEUES, "scsi%d: command for target %d, lun %llu " | 2009 | dsprintk(NDEBUG_QUEUES, instance, |
2166 | "completed\n", HOSTNO, cmd->device->id, cmd->device->lun); | 2010 | "COMMAND COMPLETE %p target %d lun %llu\n", |
2011 | cmd, scmd_id(cmd), cmd->device->lun); | ||
2167 | 2012 | ||
2168 | local_irq_save(flags); | ||
2169 | hostdata->retain_dma_intr++; | ||
2170 | hostdata->connected = NULL; | 2013 | hostdata->connected = NULL; |
2171 | #ifdef SUPPORT_TAGS | 2014 | #ifdef SUPPORT_TAGS |
2172 | cmd_free_tag(cmd); | 2015 | cmd_free_tag(cmd); |
2173 | if (status_byte(cmd->SCp.Status) == QUEUE_FULL) { | 2016 | if (status_byte(cmd->SCp.Status) == QUEUE_FULL) { |
2174 | /* Turn a QUEUE FULL status into BUSY, I think the | 2017 | u8 lun = cmd->device->lun; |
2175 | * mid level cannot handle QUEUE FULL :-( (The | 2018 | struct tag_alloc *ta = &hostdata->TagAlloc[scmd_id(cmd)][lun]; |
2176 | * command is retried after BUSY). Also update our | 2019 | |
2177 | * queue size to the number of currently issued | 2020 | dsprintk(NDEBUG_TAGS, instance, |
2178 | * commands now. | 2021 | "QUEUE_FULL %p target %d lun %d nr_allocated %d\n", |
2179 | */ | 2022 | cmd, scmd_id(cmd), lun, ta->nr_allocated); |
2180 | /* ++Andreas: the mid level code knows about | ||
2181 | QUEUE_FULL now. */ | ||
2182 | struct tag_alloc *ta = &hostdata->TagAlloc[scmd_id(cmd)][cmd->device->lun]; | ||
2183 | dprintk(NDEBUG_TAGS, "scsi%d: target %d lun %llu returned " | ||
2184 | "QUEUE_FULL after %d commands\n", | ||
2185 | HOSTNO, cmd->device->id, cmd->device->lun, | ||
2186 | ta->nr_allocated); | ||
2187 | if (ta->queue_size > ta->nr_allocated) | 2023 | if (ta->queue_size > ta->nr_allocated) |
2188 | ta->nr_allocated = ta->queue_size; | 2024 | ta->queue_size = ta->nr_allocated; |
2189 | } | 2025 | } |
2190 | #else | ||
2191 | hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun); | ||
2192 | #endif | 2026 | #endif |
2193 | /* Enable reselect interrupts */ | ||
2194 | NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask); | ||
2195 | |||
2196 | /* | ||
2197 | * I'm not sure what the correct thing to do here is : | ||
2198 | * | ||
2199 | * If the command that just executed is NOT a request | ||
2200 | * sense, the obvious thing to do is to set the result | ||
2201 | * code to the values of the stored parameters. | ||
2202 | * | ||
2203 | * If it was a REQUEST SENSE command, we need some way to | ||
2204 | * differentiate between the failure code of the original | ||
2205 | * and the failure code of the REQUEST sense - the obvious | ||
2206 | * case is success, where we fall through and leave the | ||
2207 | * result code unchanged. | ||
2208 | * | ||
2209 | * The non-obvious place is where the REQUEST SENSE failed | ||
2210 | */ | ||
2211 | |||
2212 | if (cmd->cmnd[0] != REQUEST_SENSE) | ||
2213 | cmd->result = cmd->SCp.Status | (cmd->SCp.Message << 8); | ||
2214 | else if (status_byte(cmd->SCp.Status) != GOOD) | ||
2215 | cmd->result = (cmd->result & 0x00ffff) | (DID_ERROR << 16); | ||
2216 | |||
2217 | if ((cmd->cmnd[0] == REQUEST_SENSE) && | ||
2218 | hostdata->ses.cmd_len) { | ||
2219 | scsi_eh_restore_cmnd(cmd, &hostdata->ses); | ||
2220 | hostdata->ses.cmd_len = 0 ; | ||
2221 | } | ||
2222 | |||
2223 | if ((cmd->cmnd[0] != REQUEST_SENSE) && | ||
2224 | (status_byte(cmd->SCp.Status) == CHECK_CONDITION)) { | ||
2225 | scsi_eh_prep_cmnd(cmd, &hostdata->ses, NULL, 0, ~0); | ||
2226 | |||
2227 | dprintk(NDEBUG_AUTOSENSE, "scsi%d: performing request sense\n", HOSTNO); | ||
2228 | 2027 | ||
2229 | LIST(cmd,hostdata->issue_queue); | 2028 | cmd->result &= ~0xffff; |
2230 | SET_NEXT(cmd, hostdata->issue_queue); | 2029 | cmd->result |= cmd->SCp.Status; |
2231 | hostdata->issue_queue = (struct scsi_cmnd *) cmd; | 2030 | cmd->result |= cmd->SCp.Message << 8; |
2232 | dprintk(NDEBUG_QUEUES, "scsi%d: REQUEST SENSE added to head of " | 2031 | |
2233 | "issue queue\n", H_NO(cmd)); | 2032 | if (cmd->cmnd[0] == REQUEST_SENSE) |
2234 | } else { | 2033 | complete_cmd(instance, cmd); |
2235 | cmd->scsi_done(cmd); | 2034 | else { |
2035 | if (cmd->SCp.Status == SAM_STAT_CHECK_CONDITION || | ||
2036 | cmd->SCp.Status == SAM_STAT_COMMAND_TERMINATED) { | ||
2037 | dsprintk(NDEBUG_QUEUES, instance, "autosense: adding cmd %p to tail of autosense queue\n", | ||
2038 | cmd); | ||
2039 | list_add_tail(&ncmd->list, | ||
2040 | &hostdata->autosense); | ||
2041 | } else | ||
2042 | complete_cmd(instance, cmd); | ||
2236 | } | 2043 | } |
2237 | 2044 | ||
2238 | local_irq_restore(flags); | ||
2239 | |||
2240 | NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask); | ||
2241 | /* | 2045 | /* |
2242 | * Restore phase bits to 0 so an interrupted selection, | 2046 | * Restore phase bits to 0 so an interrupted selection, |
2243 | * arbitration can resume. | 2047 | * arbitration can resume. |
2244 | */ | 2048 | */ |
2245 | NCR5380_write(TARGET_COMMAND_REG, 0); | 2049 | NCR5380_write(TARGET_COMMAND_REG, 0); |
2246 | 2050 | ||
2247 | while ((NCR5380_read(STATUS_REG) & SR_BSY) && !hostdata->connected) | 2051 | /* Enable reselect interrupts */ |
2248 | barrier(); | 2052 | NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask); |
2249 | 2053 | ||
2250 | local_irq_save(flags); | ||
2251 | hostdata->retain_dma_intr--; | ||
2252 | /* ++roman: For Falcon SCSI, release the lock on the | ||
2253 | * ST-DMA here if no other commands are waiting on the | ||
2254 | * disconnected queue. | ||
2255 | */ | ||
2256 | maybe_release_dma_irq(instance); | 2054 | maybe_release_dma_irq(instance); |
2257 | local_irq_restore(flags); | ||
2258 | return; | 2055 | return; |
2259 | case MESSAGE_REJECT: | 2056 | case MESSAGE_REJECT: |
2260 | /* Accept message by clearing ACK */ | 2057 | /* Accept message by clearing ACK */ |
2261 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); | 2058 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); |
2262 | /* Enable reselect interrupts */ | ||
2263 | NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask); | ||
2264 | switch (hostdata->last_message) { | 2059 | switch (hostdata->last_message) { |
2265 | case HEAD_OF_QUEUE_TAG: | 2060 | case HEAD_OF_QUEUE_TAG: |
2266 | case ORDERED_QUEUE_TAG: | 2061 | case ORDERED_QUEUE_TAG: |
@@ -2274,27 +2069,20 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) | |||
2274 | cmd->device->tagged_supported = 0; | 2069 | cmd->device->tagged_supported = 0; |
2275 | hostdata->busy[cmd->device->id] |= (1 << cmd->device->lun); | 2070 | hostdata->busy[cmd->device->id] |= (1 << cmd->device->lun); |
2276 | cmd->tag = TAG_NONE; | 2071 | cmd->tag = TAG_NONE; |
2277 | dprintk(NDEBUG_TAGS, "scsi%d: target %d lun %llu rejected " | 2072 | dsprintk(NDEBUG_TAGS, instance, "target %d lun %llu rejected QUEUE_TAG message; tagged queuing disabled\n", |
2278 | "QUEUE_TAG message; tagged queuing " | 2073 | scmd_id(cmd), cmd->device->lun); |
2279 | "disabled\n", | ||
2280 | HOSTNO, cmd->device->id, cmd->device->lun); | ||
2281 | break; | 2074 | break; |
2282 | } | 2075 | } |
2283 | break; | 2076 | break; |
2284 | case DISCONNECT: | 2077 | case DISCONNECT: |
2285 | /* Accept message by clearing ACK */ | 2078 | /* Accept message by clearing ACK */ |
2286 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); | 2079 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); |
2287 | local_irq_save(flags); | ||
2288 | cmd->device->disconnect = 1; | ||
2289 | LIST(cmd,hostdata->disconnected_queue); | ||
2290 | SET_NEXT(cmd, hostdata->disconnected_queue); | ||
2291 | hostdata->connected = NULL; | 2080 | hostdata->connected = NULL; |
2292 | hostdata->disconnected_queue = cmd; | 2081 | list_add(&ncmd->list, &hostdata->disconnected); |
2293 | local_irq_restore(flags); | 2082 | dsprintk(NDEBUG_INFORMATION | NDEBUG_QUEUES, |
2294 | dprintk(NDEBUG_QUEUES, "scsi%d: command for target %d lun %llu was " | 2083 | instance, "connected command %p for target %d lun %llu moved to disconnected queue\n", |
2295 | "moved from connected to the " | 2084 | cmd, scmd_id(cmd), cmd->device->lun); |
2296 | "disconnected_queue\n", HOSTNO, | 2085 | |
2297 | cmd->device->id, cmd->device->lun); | ||
2298 | /* | 2086 | /* |
2299 | * Restore phase bits to 0 so an interrupted selection, | 2087 | * Restore phase bits to 0 so an interrupted selection, |
2300 | * arbitration can resume. | 2088 | * arbitration can resume. |
@@ -2303,9 +2091,6 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) | |||
2303 | 2091 | ||
2304 | /* Enable reselect interrupts */ | 2092 | /* Enable reselect interrupts */ |
2305 | NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask); | 2093 | NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask); |
2306 | /* Wait for bus free to avoid nasty timeouts */ | ||
2307 | while ((NCR5380_read(STATUS_REG) & SR_BSY) && !hostdata->connected) | ||
2308 | barrier(); | ||
2309 | #ifdef SUN3_SCSI_VME | 2094 | #ifdef SUN3_SCSI_VME |
2310 | dregs->csr |= CSR_DMA_ENABLE; | 2095 | dregs->csr |= CSR_DMA_ENABLE; |
2311 | #endif | 2096 | #endif |
@@ -2324,37 +2109,30 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) | |||
2324 | case RESTORE_POINTERS: | 2109 | case RESTORE_POINTERS: |
2325 | /* Accept message by clearing ACK */ | 2110 | /* Accept message by clearing ACK */ |
2326 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); | 2111 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); |
2327 | /* Enable reselect interrupts */ | ||
2328 | NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask); | ||
2329 | break; | 2112 | break; |
2330 | case EXTENDED_MESSAGE: | 2113 | case EXTENDED_MESSAGE: |
2331 | /* | 2114 | /* |
2332 | * Extended messages are sent in the following format : | 2115 | * Start the message buffer with the EXTENDED_MESSAGE |
2333 | * Byte | ||
2334 | * 0 EXTENDED_MESSAGE == 1 | ||
2335 | * 1 length (includes one byte for code, doesn't | ||
2336 | * include first two bytes) | ||
2337 | * 2 code | ||
2338 | * 3..length+1 arguments | ||
2339 | * | ||
2340 | * Start the extended message buffer with the EXTENDED_MESSAGE | ||
2341 | * byte, since spi_print_msg() wants the whole thing. | 2116 | * byte, since spi_print_msg() wants the whole thing. |
2342 | */ | 2117 | */ |
2343 | extended_msg[0] = EXTENDED_MESSAGE; | 2118 | extended_msg[0] = EXTENDED_MESSAGE; |
2344 | /* Accept first byte by clearing ACK */ | 2119 | /* Accept first byte by clearing ACK */ |
2345 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); | 2120 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); |
2346 | 2121 | ||
2347 | dprintk(NDEBUG_EXTENDED, "scsi%d: receiving extended message\n", HOSTNO); | 2122 | spin_unlock_irq(&hostdata->lock); |
2123 | |||
2124 | dsprintk(NDEBUG_EXTENDED, instance, "receiving extended message\n"); | ||
2348 | 2125 | ||
2349 | len = 2; | 2126 | len = 2; |
2350 | data = extended_msg + 1; | 2127 | data = extended_msg + 1; |
2351 | phase = PHASE_MSGIN; | 2128 | phase = PHASE_MSGIN; |
2352 | NCR5380_transfer_pio(instance, &phase, &len, &data); | 2129 | NCR5380_transfer_pio(instance, &phase, &len, &data); |
2353 | dprintk(NDEBUG_EXTENDED, "scsi%d: length=%d, code=0x%02x\n", HOSTNO, | 2130 | dsprintk(NDEBUG_EXTENDED, instance, "length %d, code 0x%02x\n", |
2354 | (int)extended_msg[1], (int)extended_msg[2]); | 2131 | (int)extended_msg[1], |
2132 | (int)extended_msg[2]); | ||
2355 | 2133 | ||
2356 | if (!len && extended_msg[1] <= | 2134 | if (!len && extended_msg[1] > 0 && |
2357 | (sizeof(extended_msg) - 1)) { | 2135 | extended_msg[1] <= sizeof(extended_msg) - 2) { |
2358 | /* Accept third byte by clearing ACK */ | 2136 | /* Accept third byte by clearing ACK */ |
2359 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); | 2137 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); |
2360 | len = extended_msg[1] - 1; | 2138 | len = extended_msg[1] - 1; |
@@ -2362,8 +2140,8 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) | |||
2362 | phase = PHASE_MSGIN; | 2140 | phase = PHASE_MSGIN; |
2363 | 2141 | ||
2364 | NCR5380_transfer_pio(instance, &phase, &len, &data); | 2142 | NCR5380_transfer_pio(instance, &phase, &len, &data); |
2365 | dprintk(NDEBUG_EXTENDED, "scsi%d: message received, residual %d\n", | 2143 | dsprintk(NDEBUG_EXTENDED, instance, "message received, residual %d\n", |
2366 | HOSTNO, len); | 2144 | len); |
2367 | 2145 | ||
2368 | switch (extended_msg[2]) { | 2146 | switch (extended_msg[2]) { |
2369 | case EXTENDED_SDTR: | 2147 | case EXTENDED_SDTR: |
@@ -2373,15 +2151,18 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) | |||
2373 | tmp = 0; | 2151 | tmp = 0; |
2374 | } | 2152 | } |
2375 | } else if (len) { | 2153 | } else if (len) { |
2376 | printk(KERN_NOTICE "scsi%d: error receiving " | 2154 | shost_printk(KERN_ERR, instance, "error receiving extended message\n"); |
2377 | "extended message\n", HOSTNO); | ||
2378 | tmp = 0; | 2155 | tmp = 0; |
2379 | } else { | 2156 | } else { |
2380 | printk(KERN_NOTICE "scsi%d: extended message " | 2157 | shost_printk(KERN_NOTICE, instance, "extended message code %02x length %d is too long\n", |
2381 | "code %02x length %d is too long\n", | 2158 | extended_msg[2], extended_msg[1]); |
2382 | HOSTNO, extended_msg[2], extended_msg[1]); | ||
2383 | tmp = 0; | 2159 | tmp = 0; |
2384 | } | 2160 | } |
2161 | |||
2162 | spin_lock_irq(&hostdata->lock); | ||
2163 | if (!hostdata->connected) | ||
2164 | return; | ||
2165 | |||
2385 | /* Fall through to reject message */ | 2166 | /* Fall through to reject message */ |
2386 | 2167 | ||
2387 | /* | 2168 | /* |
@@ -2390,8 +2171,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) | |||
2390 | */ | 2171 | */ |
2391 | default: | 2172 | default: |
2392 | if (!tmp) { | 2173 | if (!tmp) { |
2393 | printk(KERN_INFO "scsi%d: rejecting message ", | 2174 | shost_printk(KERN_ERR, instance, "rejecting message "); |
2394 | instance->host_no); | ||
2395 | spi_print_msg(extended_msg); | 2175 | spi_print_msg(extended_msg); |
2396 | printk("\n"); | 2176 | printk("\n"); |
2397 | } else if (tmp != EXTENDED_MESSAGE) | 2177 | } else if (tmp != EXTENDED_MESSAGE) |
@@ -2414,18 +2194,11 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) | |||
2414 | hostdata->last_message = msgout; | 2194 | hostdata->last_message = msgout; |
2415 | NCR5380_transfer_pio(instance, &phase, &len, &data); | 2195 | NCR5380_transfer_pio(instance, &phase, &len, &data); |
2416 | if (msgout == ABORT) { | 2196 | if (msgout == ABORT) { |
2417 | local_irq_save(flags); | ||
2418 | #ifdef SUPPORT_TAGS | ||
2419 | cmd_free_tag(cmd); | ||
2420 | #else | ||
2421 | hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun); | ||
2422 | #endif | ||
2423 | hostdata->connected = NULL; | 2197 | hostdata->connected = NULL; |
2424 | cmd->result = DID_ERROR << 16; | 2198 | cmd->result = DID_ERROR << 16; |
2425 | NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask); | 2199 | complete_cmd(instance, cmd); |
2426 | maybe_release_dma_irq(instance); | 2200 | maybe_release_dma_irq(instance); |
2427 | local_irq_restore(flags); | 2201 | NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask); |
2428 | cmd->scsi_done(cmd); | ||
2429 | return; | 2202 | return; |
2430 | } | 2203 | } |
2431 | msgout = NOP; | 2204 | msgout = NOP; |
@@ -2447,22 +2220,25 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) | |||
2447 | cmd->SCp.Status = tmp; | 2220 | cmd->SCp.Status = tmp; |
2448 | break; | 2221 | break; |
2449 | default: | 2222 | default: |
2450 | printk("scsi%d: unknown phase\n", HOSTNO); | 2223 | shost_printk(KERN_ERR, instance, "unknown phase\n"); |
2451 | NCR5380_dprint(NDEBUG_ANY, instance); | 2224 | NCR5380_dprint(NDEBUG_ANY, instance); |
2452 | } /* switch(phase) */ | 2225 | } /* switch(phase) */ |
2453 | } /* if (tmp * SR_REQ) */ | 2226 | } else { |
2454 | } /* while (1) */ | 2227 | spin_unlock_irq(&hostdata->lock); |
2228 | NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, SR_REQ, HZ); | ||
2229 | spin_lock_irq(&hostdata->lock); | ||
2230 | } | ||
2231 | } | ||
2455 | } | 2232 | } |
2456 | 2233 | ||
2457 | /* | 2234 | /* |
2458 | * Function : void NCR5380_reselect (struct Scsi_Host *instance) | 2235 | * Function : void NCR5380_reselect (struct Scsi_Host *instance) |
2459 | * | 2236 | * |
2460 | * Purpose : does reselection, initializing the instance->connected | 2237 | * Purpose : does reselection, initializing the instance->connected |
2461 | * field to point to the scsi_cmnd for which the I_T_L or I_T_L_Q | 2238 | * field to point to the scsi_cmnd for which the I_T_L or I_T_L_Q |
2462 | * nexus has been reestablished, | 2239 | * nexus has been reestablished, |
2463 | * | 2240 | * |
2464 | * Inputs : instance - this instance of the NCR5380. | 2241 | * Inputs : instance - this instance of the NCR5380. |
2465 | * | ||
2466 | */ | 2242 | */ |
2467 | 2243 | ||
2468 | 2244 | ||
@@ -2471,7 +2247,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) | |||
2471 | 2247 | ||
2472 | static void NCR5380_reselect(struct Scsi_Host *instance) | 2248 | static void NCR5380_reselect(struct Scsi_Host *instance) |
2473 | { | 2249 | { |
2474 | SETUP_HOSTDATA(instance); | 2250 | struct NCR5380_hostdata *hostdata = shost_priv(instance); |
2475 | unsigned char target_mask; | 2251 | unsigned char target_mask; |
2476 | unsigned char lun; | 2252 | unsigned char lun; |
2477 | #ifdef SUPPORT_TAGS | 2253 | #ifdef SUPPORT_TAGS |
@@ -2480,7 +2256,8 @@ static void NCR5380_reselect(struct Scsi_Host *instance) | |||
2480 | unsigned char msg[3]; | 2256 | unsigned char msg[3]; |
2481 | int __maybe_unused len; | 2257 | int __maybe_unused len; |
2482 | unsigned char __maybe_unused *data, __maybe_unused phase; | 2258 | unsigned char __maybe_unused *data, __maybe_unused phase; |
2483 | struct scsi_cmnd *tmp = NULL, *prev; | 2259 | struct NCR5380_cmd *ncmd; |
2260 | struct scsi_cmnd *tmp; | ||
2484 | 2261 | ||
2485 | /* | 2262 | /* |
2486 | * Disable arbitration, etc. since the host adapter obviously | 2263 | * Disable arbitration, etc. since the host adapter obviously |
@@ -2488,11 +2265,10 @@ static void NCR5380_reselect(struct Scsi_Host *instance) | |||
2488 | */ | 2265 | */ |
2489 | 2266 | ||
2490 | NCR5380_write(MODE_REG, MR_BASE); | 2267 | NCR5380_write(MODE_REG, MR_BASE); |
2491 | hostdata->restart_select = 1; | ||
2492 | 2268 | ||
2493 | target_mask = NCR5380_read(CURRENT_SCSI_DATA_REG) & ~(hostdata->id_mask); | 2269 | target_mask = NCR5380_read(CURRENT_SCSI_DATA_REG) & ~(hostdata->id_mask); |
2494 | 2270 | ||
2495 | dprintk(NDEBUG_RESELECTION, "scsi%d: reselect\n", HOSTNO); | 2271 | dsprintk(NDEBUG_RESELECTION, instance, "reselect\n"); |
2496 | 2272 | ||
2497 | /* | 2273 | /* |
2498 | * At this point, we have detected that our SCSI ID is on the bus, | 2274 | * At this point, we have detected that our SCSI ID is on the bus, |
@@ -2504,17 +2280,22 @@ static void NCR5380_reselect(struct Scsi_Host *instance) | |||
2504 | */ | 2280 | */ |
2505 | 2281 | ||
2506 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_BSY); | 2282 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_BSY); |
2507 | 2283 | if (NCR5380_poll_politely(instance, | |
2508 | while (NCR5380_read(STATUS_REG) & SR_SEL) | 2284 | STATUS_REG, SR_SEL, 0, 2 * HZ) < 0) { |
2509 | ; | 2285 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); |
2286 | return; | ||
2287 | } | ||
2510 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); | 2288 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); |
2511 | 2289 | ||
2512 | /* | 2290 | /* |
2513 | * Wait for target to go into MSGIN. | 2291 | * Wait for target to go into MSGIN. |
2514 | */ | 2292 | */ |
2515 | 2293 | ||
2516 | while (!(NCR5380_read(STATUS_REG) & SR_REQ)) | 2294 | if (NCR5380_poll_politely(instance, |
2517 | ; | 2295 | STATUS_REG, SR_REQ, SR_REQ, 2 * HZ) < 0) { |
2296 | do_abort(instance); | ||
2297 | return; | ||
2298 | } | ||
2518 | 2299 | ||
2519 | #if defined(CONFIG_SUN3) && defined(REAL_DMA) | 2300 | #if defined(CONFIG_SUN3) && defined(REAL_DMA) |
2520 | /* acknowledge toggle to MSGIN */ | 2301 | /* acknowledge toggle to MSGIN */ |
@@ -2527,15 +2308,21 @@ static void NCR5380_reselect(struct Scsi_Host *instance) | |||
2527 | data = msg; | 2308 | data = msg; |
2528 | phase = PHASE_MSGIN; | 2309 | phase = PHASE_MSGIN; |
2529 | NCR5380_transfer_pio(instance, &phase, &len, &data); | 2310 | NCR5380_transfer_pio(instance, &phase, &len, &data); |
2311 | |||
2312 | if (len) { | ||
2313 | do_abort(instance); | ||
2314 | return; | ||
2315 | } | ||
2530 | #endif | 2316 | #endif |
2531 | 2317 | ||
2532 | if (!(msg[0] & 0x80)) { | 2318 | if (!(msg[0] & 0x80)) { |
2533 | printk(KERN_DEBUG "scsi%d: expecting IDENTIFY message, got ", HOSTNO); | 2319 | shost_printk(KERN_ERR, instance, "expecting IDENTIFY message, got "); |
2534 | spi_print_msg(msg); | 2320 | spi_print_msg(msg); |
2321 | printk("\n"); | ||
2535 | do_abort(instance); | 2322 | do_abort(instance); |
2536 | return; | 2323 | return; |
2537 | } | 2324 | } |
2538 | lun = (msg[0] & 0x07); | 2325 | lun = msg[0] & 0x07; |
2539 | 2326 | ||
2540 | #if defined(SUPPORT_TAGS) && !defined(CONFIG_SUN3) | 2327 | #if defined(SUPPORT_TAGS) && !defined(CONFIG_SUN3) |
2541 | /* If the phase is still MSGIN, the target wants to send some more | 2328 | /* If the phase is still MSGIN, the target wants to send some more |
@@ -2551,8 +2338,8 @@ static void NCR5380_reselect(struct Scsi_Host *instance) | |||
2551 | if (!NCR5380_transfer_pio(instance, &phase, &len, &data) && | 2338 | if (!NCR5380_transfer_pio(instance, &phase, &len, &data) && |
2552 | msg[1] == SIMPLE_QUEUE_TAG) | 2339 | msg[1] == SIMPLE_QUEUE_TAG) |
2553 | tag = msg[2]; | 2340 | tag = msg[2]; |
2554 | dprintk(NDEBUG_TAGS, "scsi%d: target mask %02x, lun %d sent tag %d at " | 2341 | dsprintk(NDEBUG_TAGS, instance, "reselect: target mask %02x, lun %d sent tag %d\n", |
2555 | "reselection\n", HOSTNO, target_mask, lun, tag); | 2342 | target_mask, lun, tag); |
2556 | } | 2343 | } |
2557 | #endif | 2344 | #endif |
2558 | 2345 | ||
@@ -2561,36 +2348,34 @@ static void NCR5380_reselect(struct Scsi_Host *instance) | |||
2561 | * just reestablished, and remove it from the disconnected queue. | 2348 | * just reestablished, and remove it from the disconnected queue. |
2562 | */ | 2349 | */ |
2563 | 2350 | ||
2564 | for (tmp = (struct scsi_cmnd *) hostdata->disconnected_queue, prev = NULL; | 2351 | tmp = NULL; |
2565 | tmp; prev = tmp, tmp = NEXT(tmp)) { | 2352 | list_for_each_entry(ncmd, &hostdata->disconnected, list) { |
2566 | if ((target_mask == (1 << tmp->device->id)) && (lun == tmp->device->lun) | 2353 | struct scsi_cmnd *cmd = NCR5380_to_scmd(ncmd); |
2354 | |||
2355 | if (target_mask == (1 << scmd_id(cmd)) && | ||
2356 | lun == (u8)cmd->device->lun | ||
2567 | #ifdef SUPPORT_TAGS | 2357 | #ifdef SUPPORT_TAGS |
2568 | && (tag == tmp->tag) | 2358 | && (tag == cmd->tag) |
2569 | #endif | 2359 | #endif |
2570 | ) { | 2360 | ) { |
2571 | if (prev) { | 2361 | list_del(&ncmd->list); |
2572 | REMOVE(prev, NEXT(prev), tmp, NEXT(tmp)); | 2362 | tmp = cmd; |
2573 | SET_NEXT(prev, NEXT(tmp)); | ||
2574 | } else { | ||
2575 | REMOVE(-1, hostdata->disconnected_queue, tmp, NEXT(tmp)); | ||
2576 | hostdata->disconnected_queue = NEXT(tmp); | ||
2577 | } | ||
2578 | SET_NEXT(tmp, NULL); | ||
2579 | break; | 2363 | break; |
2580 | } | 2364 | } |
2581 | } | 2365 | } |
2582 | 2366 | ||
2583 | if (!tmp) { | 2367 | if (tmp) { |
2584 | printk(KERN_WARNING "scsi%d: warning: target bitmask %02x lun %d " | 2368 | dsprintk(NDEBUG_RESELECTION | NDEBUG_QUEUES, instance, |
2585 | #ifdef SUPPORT_TAGS | 2369 | "reselect: removed %p from disconnected queue\n", tmp); |
2586 | "tag %d " | 2370 | } else { |
2587 | #endif | 2371 | |
2588 | "not in disconnected_queue.\n", | ||
2589 | HOSTNO, target_mask, lun | ||
2590 | #ifdef SUPPORT_TAGS | 2372 | #ifdef SUPPORT_TAGS |
2591 | , tag | 2373 | shost_printk(KERN_ERR, instance, "target bitmask 0x%02x lun %d tag %d not in disconnected queue.\n", |
2374 | target_mask, lun, tag); | ||
2375 | #else | ||
2376 | shost_printk(KERN_ERR, instance, "target bitmask 0x%02x lun %d not in disconnected queue.\n", | ||
2377 | target_mask, lun); | ||
2592 | #endif | 2378 | #endif |
2593 | ); | ||
2594 | /* | 2379 | /* |
2595 | * Since we have an established nexus that we can't do anything | 2380 | * Since we have an established nexus that we can't do anything |
2596 | * with, we must abort it. | 2381 | * with, we must abort it. |
@@ -2614,7 +2399,8 @@ static void NCR5380_reselect(struct Scsi_Host *instance) | |||
2614 | } | 2399 | } |
2615 | /* setup this command for dma if not already */ | 2400 | /* setup this command for dma if not already */ |
2616 | if ((count >= DMA_MIN_SIZE) && (sun3_dma_setup_done != tmp)) { | 2401 | if ((count >= DMA_MIN_SIZE) && (sun3_dma_setup_done != tmp)) { |
2617 | sun3scsi_dma_setup(d, count, rq_data_dir(tmp->request)); | 2402 | sun3scsi_dma_setup(instance, d, count, |
2403 | rq_data_dir(tmp->request)); | ||
2618 | sun3_dma_setup_done = tmp; | 2404 | sun3_dma_setup_done = tmp; |
2619 | } | 2405 | } |
2620 | } | 2406 | } |
@@ -2639,235 +2425,196 @@ static void NCR5380_reselect(struct Scsi_Host *instance) | |||
2639 | if (!NCR5380_transfer_pio(instance, &phase, &len, &data) && | 2425 | if (!NCR5380_transfer_pio(instance, &phase, &len, &data) && |
2640 | msg[1] == SIMPLE_QUEUE_TAG) | 2426 | msg[1] == SIMPLE_QUEUE_TAG) |
2641 | tag = msg[2]; | 2427 | tag = msg[2]; |
2642 | dprintk(NDEBUG_TAGS, "scsi%d: target mask %02x, lun %d sent tag %d at reselection\n" | 2428 | dsprintk(NDEBUG_TAGS, instance, "reselect: target mask %02x, lun %d sent tag %d\n" |
2643 | HOSTNO, target_mask, lun, tag); | 2429 | target_mask, lun, tag); |
2644 | } | 2430 | } |
2645 | #endif | 2431 | #endif |
2646 | 2432 | ||
2647 | hostdata->connected = tmp; | 2433 | hostdata->connected = tmp; |
2648 | dprintk(NDEBUG_RESELECTION, "scsi%d: nexus established, target = %d, lun = %llu, tag = %d\n", | 2434 | dsprintk(NDEBUG_RESELECTION, instance, "nexus established, target %d, lun %llu, tag %d\n", |
2649 | HOSTNO, tmp->device->id, tmp->device->lun, tmp->tag); | 2435 | scmd_id(tmp), tmp->device->lun, tmp->tag); |
2650 | } | 2436 | } |
2651 | 2437 | ||
2652 | 2438 | ||
2653 | /* | 2439 | /** |
2654 | * Function : int NCR5380_abort (struct scsi_cmnd *cmd) | 2440 | * list_find_cmd - test for presence of a command in a linked list |
2655 | * | 2441 | * @haystack: list of commands |
2656 | * Purpose : abort a command | 2442 | * @needle: command to search for |
2657 | * | ||
2658 | * Inputs : cmd - the scsi_cmnd to abort, code - code to set the | ||
2659 | * host byte of the result field to, if zero DID_ABORTED is | ||
2660 | * used. | ||
2661 | * | ||
2662 | * Returns : SUCCESS - success, FAILED on failure. | ||
2663 | * | ||
2664 | * XXX - there is no way to abort the command that is currently | ||
2665 | * connected, you have to wait for it to complete. If this is | ||
2666 | * a problem, we could implement longjmp() / setjmp(), setjmp() | ||
2667 | * called where the loop started in NCR5380_main(). | ||
2668 | */ | 2443 | */ |
2669 | 2444 | ||
2670 | static | 2445 | static bool list_find_cmd(struct list_head *haystack, |
2671 | int NCR5380_abort(struct scsi_cmnd *cmd) | 2446 | struct scsi_cmnd *needle) |
2672 | { | 2447 | { |
2673 | struct Scsi_Host *instance = cmd->device->host; | 2448 | struct NCR5380_cmd *ncmd; |
2674 | SETUP_HOSTDATA(instance); | ||
2675 | struct scsi_cmnd *tmp, **prev; | ||
2676 | unsigned long flags; | ||
2677 | 2449 | ||
2678 | scmd_printk(KERN_NOTICE, cmd, "aborting command\n"); | 2450 | list_for_each_entry(ncmd, haystack, list) |
2451 | if (NCR5380_to_scmd(ncmd) == needle) | ||
2452 | return true; | ||
2453 | return false; | ||
2454 | } | ||
2679 | 2455 | ||
2680 | NCR5380_print_status(instance); | 2456 | /** |
2457 | * list_remove_cmd - remove a command from linked list | ||
2458 | * @haystack: list of commands | ||
2459 | * @needle: command to remove | ||
2460 | */ | ||
2681 | 2461 | ||
2682 | local_irq_save(flags); | 2462 | static bool list_del_cmd(struct list_head *haystack, |
2463 | struct scsi_cmnd *needle) | ||
2464 | { | ||
2465 | if (list_find_cmd(haystack, needle)) { | ||
2466 | struct NCR5380_cmd *ncmd = scsi_cmd_priv(needle); | ||
2683 | 2467 | ||
2684 | dprintk(NDEBUG_ABORT, "scsi%d: abort called basr 0x%02x, sr 0x%02x\n", HOSTNO, | 2468 | list_del(&ncmd->list); |
2685 | NCR5380_read(BUS_AND_STATUS_REG), | 2469 | return true; |
2686 | NCR5380_read(STATUS_REG)); | 2470 | } |
2471 | return false; | ||
2472 | } | ||
2687 | 2473 | ||
2688 | #if 1 | 2474 | /** |
2689 | /* | 2475 | * NCR5380_abort - scsi host eh_abort_handler() method |
2690 | * Case 1 : If the command is the currently executing command, | 2476 | * @cmd: the command to be aborted |
2691 | * we'll set the aborted flag and return control so that | 2477 | * |
2692 | * information transfer routine can exit cleanly. | 2478 | * Try to abort a given command by removing it from queues and/or sending |
2693 | */ | 2479 | * the target an abort message. This may not succeed in causing a target |
2480 | * to abort the command. Nonetheless, the low-level driver must forget about | ||
2481 | * the command because the mid-layer reclaims it and it may be re-issued. | ||
2482 | * | ||
2483 | * The normal path taken by a command is as follows. For EH we trace this | ||
2484 | * same path to locate and abort the command. | ||
2485 | * | ||
2486 | * unissued -> selecting -> [unissued -> selecting ->]... connected -> | ||
2487 | * [disconnected -> connected ->]... | ||
2488 | * [autosense -> connected ->] done | ||
2489 | * | ||
2490 | * If cmd is unissued then just remove it. | ||
2491 | * If cmd is disconnected, try to select the target. | ||
2492 | * If cmd is connected, try to send an abort message. | ||
2493 | * If cmd is waiting for autosense, give it a chance to complete but check | ||
2494 | * that it isn't left connected. | ||
2495 | * If cmd was not found at all then presumably it has already been completed, | ||
2496 | * in which case return SUCCESS to try to avoid further EH measures. | ||
2497 | * If the command has not completed yet, we must not fail to find it. | ||
2498 | */ | ||
2694 | 2499 | ||
2695 | if (hostdata->connected == cmd) { | 2500 | static int NCR5380_abort(struct scsi_cmnd *cmd) |
2501 | { | ||
2502 | struct Scsi_Host *instance = cmd->device->host; | ||
2503 | struct NCR5380_hostdata *hostdata = shost_priv(instance); | ||
2504 | unsigned long flags; | ||
2505 | int result = SUCCESS; | ||
2696 | 2506 | ||
2697 | dprintk(NDEBUG_ABORT, "scsi%d: aborting connected command\n", HOSTNO); | 2507 | spin_lock_irqsave(&hostdata->lock, flags); |
2698 | /* | ||
2699 | * We should perform BSY checking, and make sure we haven't slipped | ||
2700 | * into BUS FREE. | ||
2701 | */ | ||
2702 | 2508 | ||
2703 | /* NCR5380_write(INITIATOR_COMMAND_REG, ICR_ASSERT_ATN); */ | 2509 | #if (NDEBUG & NDEBUG_ANY) |
2704 | /* | 2510 | scmd_printk(KERN_INFO, cmd, __func__); |
2705 | * Since we can't change phases until we've completed the current | 2511 | #endif |
2706 | * handshake, we have to source or sink a byte of data if the current | 2512 | NCR5380_dprint(NDEBUG_ANY, instance); |
2707 | * phase is not MSGOUT. | 2513 | NCR5380_dprint_phase(NDEBUG_ANY, instance); |
2708 | */ | ||
2709 | 2514 | ||
2710 | /* | 2515 | if (list_del_cmd(&hostdata->unissued, cmd)) { |
2711 | * Return control to the executing NCR drive so we can clear the | 2516 | dsprintk(NDEBUG_ABORT, instance, |
2712 | * aborted flag and get back into our main loop. | 2517 | "abort: removed %p from issue queue\n", cmd); |
2713 | */ | 2518 | cmd->result = DID_ABORT << 16; |
2519 | cmd->scsi_done(cmd); /* No tag or busy flag to worry about */ | ||
2520 | } | ||
2714 | 2521 | ||
2715 | if (do_abort(instance) == 0) { | 2522 | if (hostdata->selecting == cmd) { |
2716 | hostdata->aborted = 1; | 2523 | dsprintk(NDEBUG_ABORT, instance, |
2717 | hostdata->connected = NULL; | 2524 | "abort: cmd %p == selecting\n", cmd); |
2718 | cmd->result = DID_ABORT << 16; | 2525 | hostdata->selecting = NULL; |
2719 | #ifdef SUPPORT_TAGS | 2526 | cmd->result = DID_ABORT << 16; |
2720 | cmd_free_tag(cmd); | 2527 | complete_cmd(instance, cmd); |
2721 | #else | 2528 | goto out; |
2722 | hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun); | ||
2723 | #endif | ||
2724 | maybe_release_dma_irq(instance); | ||
2725 | local_irq_restore(flags); | ||
2726 | cmd->scsi_done(cmd); | ||
2727 | return SUCCESS; | ||
2728 | } else { | ||
2729 | local_irq_restore(flags); | ||
2730 | printk("scsi%d: abort of connected command failed!\n", HOSTNO); | ||
2731 | return FAILED; | ||
2732 | } | ||
2733 | } | 2529 | } |
2734 | #endif | ||
2735 | 2530 | ||
2736 | /* | 2531 | if (list_del_cmd(&hostdata->disconnected, cmd)) { |
2737 | * Case 2 : If the command hasn't been issued yet, we simply remove it | 2532 | dsprintk(NDEBUG_ABORT, instance, |
2738 | * from the issue queue. | 2533 | "abort: removed %p from disconnected list\n", cmd); |
2739 | */ | 2534 | cmd->result = DID_ERROR << 16; |
2740 | for (prev = (struct scsi_cmnd **)&(hostdata->issue_queue), | 2535 | if (!hostdata->connected) |
2741 | tmp = (struct scsi_cmnd *)hostdata->issue_queue; | 2536 | NCR5380_select(instance, cmd); |
2742 | tmp; prev = NEXTADDR(tmp), tmp = NEXT(tmp)) { | 2537 | if (hostdata->connected != cmd) { |
2743 | if (cmd == tmp) { | 2538 | complete_cmd(instance, cmd); |
2744 | REMOVE(5, *prev, tmp, NEXT(tmp)); | 2539 | result = FAILED; |
2745 | (*prev) = NEXT(tmp); | 2540 | goto out; |
2746 | SET_NEXT(tmp, NULL); | ||
2747 | tmp->result = DID_ABORT << 16; | ||
2748 | maybe_release_dma_irq(instance); | ||
2749 | local_irq_restore(flags); | ||
2750 | dprintk(NDEBUG_ABORT, "scsi%d: abort removed command from issue queue.\n", | ||
2751 | HOSTNO); | ||
2752 | /* Tagged queuing note: no tag to free here, hasn't been assigned | ||
2753 | * yet... */ | ||
2754 | tmp->scsi_done(tmp); | ||
2755 | return SUCCESS; | ||
2756 | } | 2541 | } |
2757 | } | 2542 | } |
2758 | 2543 | ||
2759 | /* | 2544 | if (hostdata->connected == cmd) { |
2760 | * Case 3 : If any commands are connected, we're going to fail the abort | 2545 | dsprintk(NDEBUG_ABORT, instance, "abort: cmd %p is connected\n", cmd); |
2761 | * and let the high level SCSI driver retry at a later time or | 2546 | hostdata->connected = NULL; |
2762 | * issue a reset. | 2547 | if (do_abort(instance)) { |
2763 | * | 2548 | set_host_byte(cmd, DID_ERROR); |
2764 | * Timeouts, and therefore aborted commands, will be highly unlikely | 2549 | complete_cmd(instance, cmd); |
2765 | * and handling them cleanly in this situation would make the common | 2550 | result = FAILED; |
2766 | * case of noresets less efficient, and would pollute our code. So, | 2551 | goto out; |
2767 | * we fail. | 2552 | } |
2768 | */ | 2553 | set_host_byte(cmd, DID_ABORT); |
2554 | #ifdef REAL_DMA | ||
2555 | hostdata->dma_len = 0; | ||
2556 | #endif | ||
2557 | if (cmd->cmnd[0] == REQUEST_SENSE) | ||
2558 | complete_cmd(instance, cmd); | ||
2559 | else { | ||
2560 | struct NCR5380_cmd *ncmd = scsi_cmd_priv(cmd); | ||
2769 | 2561 | ||
2770 | if (hostdata->connected) { | 2562 | /* Perform autosense for this command */ |
2771 | local_irq_restore(flags); | 2563 | list_add(&ncmd->list, &hostdata->autosense); |
2772 | dprintk(NDEBUG_ABORT, "scsi%d: abort failed, command connected.\n", HOSTNO); | 2564 | } |
2773 | return FAILED; | ||
2774 | } | 2565 | } |
2775 | 2566 | ||
2776 | /* | 2567 | if (list_find_cmd(&hostdata->autosense, cmd)) { |
2777 | * Case 4: If the command is currently disconnected from the bus, and | 2568 | dsprintk(NDEBUG_ABORT, instance, |
2778 | * there are no connected commands, we reconnect the I_T_L or | 2569 | "abort: found %p on sense queue\n", cmd); |
2779 | * I_T_L_Q nexus associated with it, go into message out, and send | 2570 | spin_unlock_irqrestore(&hostdata->lock, flags); |
2780 | * an abort message. | 2571 | queue_work(hostdata->work_q, &hostdata->main_task); |
2781 | * | 2572 | msleep(1000); |
2782 | * This case is especially ugly. In order to reestablish the nexus, we | 2573 | spin_lock_irqsave(&hostdata->lock, flags); |
2783 | * need to call NCR5380_select(). The easiest way to implement this | 2574 | if (list_del_cmd(&hostdata->autosense, cmd)) { |
2784 | * function was to abort if the bus was busy, and let the interrupt | 2575 | dsprintk(NDEBUG_ABORT, instance, |
2785 | * handler triggered on the SEL for reselect take care of lost arbitrations | 2576 | "abort: removed %p from sense queue\n", cmd); |
2786 | * where necessary, meaning interrupts need to be enabled. | 2577 | set_host_byte(cmd, DID_ABORT); |
2787 | * | 2578 | complete_cmd(instance, cmd); |
2788 | * When interrupts are enabled, the queues may change - so we | 2579 | goto out; |
2789 | * can't remove it from the disconnected queue before selecting it | ||
2790 | * because that could cause a failure in hashing the nexus if that | ||
2791 | * device reselected. | ||
2792 | * | ||
2793 | * Since the queues may change, we can't use the pointers from when we | ||
2794 | * first locate it. | ||
2795 | * | ||
2796 | * So, we must first locate the command, and if NCR5380_select() | ||
2797 | * succeeds, then issue the abort, relocate the command and remove | ||
2798 | * it from the disconnected queue. | ||
2799 | */ | ||
2800 | |||
2801 | for (tmp = (struct scsi_cmnd *) hostdata->disconnected_queue; tmp; | ||
2802 | tmp = NEXT(tmp)) { | ||
2803 | if (cmd == tmp) { | ||
2804 | local_irq_restore(flags); | ||
2805 | dprintk(NDEBUG_ABORT, "scsi%d: aborting disconnected command.\n", HOSTNO); | ||
2806 | |||
2807 | if (NCR5380_select(instance, cmd)) | ||
2808 | return FAILED; | ||
2809 | |||
2810 | dprintk(NDEBUG_ABORT, "scsi%d: nexus reestablished.\n", HOSTNO); | ||
2811 | |||
2812 | do_abort(instance); | ||
2813 | |||
2814 | local_irq_save(flags); | ||
2815 | for (prev = (struct scsi_cmnd **)&(hostdata->disconnected_queue), | ||
2816 | tmp = (struct scsi_cmnd *)hostdata->disconnected_queue; | ||
2817 | tmp; prev = NEXTADDR(tmp), tmp = NEXT(tmp)) { | ||
2818 | if (cmd == tmp) { | ||
2819 | REMOVE(5, *prev, tmp, NEXT(tmp)); | ||
2820 | *prev = NEXT(tmp); | ||
2821 | SET_NEXT(tmp, NULL); | ||
2822 | tmp->result = DID_ABORT << 16; | ||
2823 | /* We must unlock the tag/LUN immediately here, since the | ||
2824 | * target goes to BUS FREE and doesn't send us another | ||
2825 | * message (COMMAND_COMPLETE or the like) | ||
2826 | */ | ||
2827 | #ifdef SUPPORT_TAGS | ||
2828 | cmd_free_tag(tmp); | ||
2829 | #else | ||
2830 | hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun); | ||
2831 | #endif | ||
2832 | maybe_release_dma_irq(instance); | ||
2833 | local_irq_restore(flags); | ||
2834 | tmp->scsi_done(tmp); | ||
2835 | return SUCCESS; | ||
2836 | } | ||
2837 | } | ||
2838 | } | 2580 | } |
2839 | } | 2581 | } |
2840 | 2582 | ||
2841 | /* Maybe it is sufficient just to release the ST-DMA lock... (if | 2583 | if (hostdata->connected == cmd) { |
2842 | * possible at all) At least, we should check if the lock could be | 2584 | dsprintk(NDEBUG_ABORT, instance, "abort: cmd %p is connected\n", cmd); |
2843 | * released after the abort, in case it is kept due to some bug. | 2585 | hostdata->connected = NULL; |
2844 | */ | 2586 | if (do_abort(instance)) { |
2845 | maybe_release_dma_irq(instance); | 2587 | set_host_byte(cmd, DID_ERROR); |
2846 | local_irq_restore(flags); | 2588 | complete_cmd(instance, cmd); |
2589 | result = FAILED; | ||
2590 | goto out; | ||
2591 | } | ||
2592 | set_host_byte(cmd, DID_ABORT); | ||
2593 | #ifdef REAL_DMA | ||
2594 | hostdata->dma_len = 0; | ||
2595 | #endif | ||
2596 | complete_cmd(instance, cmd); | ||
2597 | } | ||
2847 | 2598 | ||
2848 | /* | 2599 | out: |
2849 | * Case 5 : If we reached this point, the command was not found in any of | 2600 | if (result == FAILED) |
2850 | * the queues. | 2601 | dsprintk(NDEBUG_ABORT, instance, "abort: failed to abort %p\n", cmd); |
2851 | * | 2602 | else |
2852 | * We probably reached this point because of an unlikely race condition | 2603 | dsprintk(NDEBUG_ABORT, instance, "abort: successfully aborted %p\n", cmd); |
2853 | * between the command completing successfully and the abortion code, | ||
2854 | * so we won't panic, but we will notify the user in case something really | ||
2855 | * broke. | ||
2856 | */ | ||
2857 | 2604 | ||
2858 | printk(KERN_INFO "scsi%d: warning : SCSI command probably completed successfully before abortion\n", HOSTNO); | 2605 | queue_work(hostdata->work_q, &hostdata->main_task); |
2606 | maybe_release_dma_irq(instance); | ||
2607 | spin_unlock_irqrestore(&hostdata->lock, flags); | ||
2859 | 2608 | ||
2860 | return FAILED; | 2609 | return result; |
2861 | } | 2610 | } |
2862 | 2611 | ||
2863 | 2612 | ||
2864 | /* | 2613 | /** |
2865 | * Function : int NCR5380_reset (struct scsi_cmnd *cmd) | 2614 | * NCR5380_bus_reset - reset the SCSI bus |
2866 | * | 2615 | * @cmd: SCSI command undergoing EH |
2867 | * Purpose : reset the SCSI bus. | ||
2868 | * | ||
2869 | * Returns : SUCCESS or FAILURE | ||
2870 | * | 2616 | * |
2617 | * Returns SUCCESS | ||
2871 | */ | 2618 | */ |
2872 | 2619 | ||
2873 | static int NCR5380_bus_reset(struct scsi_cmnd *cmd) | 2620 | static int NCR5380_bus_reset(struct scsi_cmnd *cmd) |
@@ -2876,23 +2623,22 @@ static int NCR5380_bus_reset(struct scsi_cmnd *cmd) | |||
2876 | struct NCR5380_hostdata *hostdata = shost_priv(instance); | 2623 | struct NCR5380_hostdata *hostdata = shost_priv(instance); |
2877 | int i; | 2624 | int i; |
2878 | unsigned long flags; | 2625 | unsigned long flags; |
2626 | struct NCR5380_cmd *ncmd; | ||
2879 | 2627 | ||
2880 | NCR5380_print_status(instance); | 2628 | spin_lock_irqsave(&hostdata->lock, flags); |
2629 | |||
2630 | #if (NDEBUG & NDEBUG_ANY) | ||
2631 | scmd_printk(KERN_INFO, cmd, __func__); | ||
2632 | #endif | ||
2633 | NCR5380_dprint(NDEBUG_ANY, instance); | ||
2634 | NCR5380_dprint_phase(NDEBUG_ANY, instance); | ||
2635 | |||
2636 | do_reset(instance); | ||
2881 | 2637 | ||
2882 | /* get in phase */ | ||
2883 | NCR5380_write(TARGET_COMMAND_REG, | ||
2884 | PHASE_SR_TO_TCR(NCR5380_read(STATUS_REG))); | ||
2885 | /* assert RST */ | ||
2886 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_RST); | ||
2887 | udelay(40); | ||
2888 | /* reset NCR registers */ | 2638 | /* reset NCR registers */ |
2889 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); | ||
2890 | NCR5380_write(MODE_REG, MR_BASE); | 2639 | NCR5380_write(MODE_REG, MR_BASE); |
2891 | NCR5380_write(TARGET_COMMAND_REG, 0); | 2640 | NCR5380_write(TARGET_COMMAND_REG, 0); |
2892 | NCR5380_write(SELECT_ENABLE_REG, 0); | 2641 | NCR5380_write(SELECT_ENABLE_REG, 0); |
2893 | /* ++roman: reset interrupt condition! otherwise no interrupts don't get | ||
2894 | * through anymore ... */ | ||
2895 | (void)NCR5380_read(RESET_PARITY_INTERRUPT_REG); | ||
2896 | 2642 | ||
2897 | /* After the reset, there are no more connected or disconnected commands | 2643 | /* After the reset, there are no more connected or disconnected commands |
2898 | * and no busy units; so clear the low-level status here to avoid | 2644 | * and no busy units; so clear the low-level status here to avoid |
@@ -2900,17 +2646,34 @@ static int NCR5380_bus_reset(struct scsi_cmnd *cmd) | |||
2900 | * commands! | 2646 | * commands! |
2901 | */ | 2647 | */ |
2902 | 2648 | ||
2903 | if (hostdata->issue_queue) | 2649 | hostdata->selecting = NULL; |
2904 | dprintk(NDEBUG_ABORT, "scsi%d: reset aborted issued command(s)\n", H_NO(cmd)); | 2650 | |
2905 | if (hostdata->connected) | 2651 | list_for_each_entry(ncmd, &hostdata->disconnected, list) { |
2906 | dprintk(NDEBUG_ABORT, "scsi%d: reset aborted a connected command\n", H_NO(cmd)); | 2652 | struct scsi_cmnd *cmd = NCR5380_to_scmd(ncmd); |
2907 | if (hostdata->disconnected_queue) | 2653 | |
2908 | dprintk(NDEBUG_ABORT, "scsi%d: reset aborted disconnected command(s)\n", H_NO(cmd)); | 2654 | set_host_byte(cmd, DID_RESET); |
2655 | cmd->scsi_done(cmd); | ||
2656 | } | ||
2657 | |||
2658 | list_for_each_entry(ncmd, &hostdata->autosense, list) { | ||
2659 | struct scsi_cmnd *cmd = NCR5380_to_scmd(ncmd); | ||
2660 | |||
2661 | set_host_byte(cmd, DID_RESET); | ||
2662 | cmd->scsi_done(cmd); | ||
2663 | } | ||
2664 | |||
2665 | if (hostdata->connected) { | ||
2666 | set_host_byte(hostdata->connected, DID_RESET); | ||
2667 | complete_cmd(instance, hostdata->connected); | ||
2668 | hostdata->connected = NULL; | ||
2669 | } | ||
2670 | |||
2671 | if (hostdata->sensing) { | ||
2672 | set_host_byte(hostdata->connected, DID_RESET); | ||
2673 | complete_cmd(instance, hostdata->sensing); | ||
2674 | hostdata->sensing = NULL; | ||
2675 | } | ||
2909 | 2676 | ||
2910 | local_irq_save(flags); | ||
2911 | hostdata->issue_queue = NULL; | ||
2912 | hostdata->connected = NULL; | ||
2913 | hostdata->disconnected_queue = NULL; | ||
2914 | #ifdef SUPPORT_TAGS | 2677 | #ifdef SUPPORT_TAGS |
2915 | free_all_tags(hostdata); | 2678 | free_all_tags(hostdata); |
2916 | #endif | 2679 | #endif |
@@ -2920,8 +2683,9 @@ static int NCR5380_bus_reset(struct scsi_cmnd *cmd) | |||
2920 | hostdata->dma_len = 0; | 2683 | hostdata->dma_len = 0; |
2921 | #endif | 2684 | #endif |
2922 | 2685 | ||
2686 | queue_work(hostdata->work_q, &hostdata->main_task); | ||
2923 | maybe_release_dma_irq(instance); | 2687 | maybe_release_dma_irq(instance); |
2924 | local_irq_restore(flags); | 2688 | spin_unlock_irqrestore(&hostdata->lock, flags); |
2925 | 2689 | ||
2926 | return SUCCESS; | 2690 | return SUCCESS; |
2927 | } | 2691 | } |
diff --git a/drivers/scsi/atari_scsi.c b/drivers/scsi/atari_scsi.c index 5ede3daa93dc..78d1b2963f2c 100644 --- a/drivers/scsi/atari_scsi.c +++ b/drivers/scsi/atari_scsi.c | |||
@@ -66,7 +66,6 @@ | |||
66 | 66 | ||
67 | #include <linux/module.h> | 67 | #include <linux/module.h> |
68 | #include <linux/types.h> | 68 | #include <linux/types.h> |
69 | #include <linux/delay.h> | ||
70 | #include <linux/blkdev.h> | 69 | #include <linux/blkdev.h> |
71 | #include <linux/interrupt.h> | 70 | #include <linux/interrupt.h> |
72 | #include <linux/init.h> | 71 | #include <linux/init.h> |
@@ -98,7 +97,6 @@ | |||
98 | 97 | ||
99 | #define NCR5380_queue_command atari_scsi_queue_command | 98 | #define NCR5380_queue_command atari_scsi_queue_command |
100 | #define NCR5380_abort atari_scsi_abort | 99 | #define NCR5380_abort atari_scsi_abort |
101 | #define NCR5380_show_info atari_scsi_show_info | ||
102 | #define NCR5380_info atari_scsi_info | 100 | #define NCR5380_info atari_scsi_info |
103 | 101 | ||
104 | #define NCR5380_dma_read_setup(instance, data, count) \ | 102 | #define NCR5380_dma_read_setup(instance, data, count) \ |
@@ -161,23 +159,10 @@ static inline unsigned long SCSI_DMA_GETADR(void) | |||
161 | return adr; | 159 | return adr; |
162 | } | 160 | } |
163 | 161 | ||
164 | #define HOSTDATA_DMALEN (((struct NCR5380_hostdata *) \ | ||
165 | (atari_scsi_host->hostdata))->dma_len) | ||
166 | |||
167 | /* Time (in jiffies) to wait after a reset; the SCSI standard calls for 250ms, | ||
168 | * we usually do 0.5s to be on the safe side. But Toshiba CD-ROMs once more | ||
169 | * need ten times the standard value... */ | ||
170 | #ifndef CONFIG_ATARI_SCSI_TOSHIBA_DELAY | ||
171 | #define AFTER_RESET_DELAY (HZ/2) | ||
172 | #else | ||
173 | #define AFTER_RESET_DELAY (5*HZ/2) | ||
174 | #endif | ||
175 | |||
176 | #ifdef REAL_DMA | 162 | #ifdef REAL_DMA |
177 | static void atari_scsi_fetch_restbytes(void); | 163 | static void atari_scsi_fetch_restbytes(void); |
178 | #endif | 164 | #endif |
179 | 165 | ||
180 | static struct Scsi_Host *atari_scsi_host; | ||
181 | static unsigned char (*atari_scsi_reg_read)(unsigned char reg); | 166 | static unsigned char (*atari_scsi_reg_read)(unsigned char reg); |
182 | static void (*atari_scsi_reg_write)(unsigned char reg, unsigned char value); | 167 | static void (*atari_scsi_reg_write)(unsigned char reg, unsigned char value); |
183 | 168 | ||
@@ -208,12 +193,12 @@ static int setup_cmd_per_lun = -1; | |||
208 | module_param(setup_cmd_per_lun, int, 0); | 193 | module_param(setup_cmd_per_lun, int, 0); |
209 | static int setup_sg_tablesize = -1; | 194 | static int setup_sg_tablesize = -1; |
210 | module_param(setup_sg_tablesize, int, 0); | 195 | module_param(setup_sg_tablesize, int, 0); |
211 | #ifdef SUPPORT_TAGS | ||
212 | static int setup_use_tagged_queuing = -1; | 196 | static int setup_use_tagged_queuing = -1; |
213 | module_param(setup_use_tagged_queuing, int, 0); | 197 | module_param(setup_use_tagged_queuing, int, 0); |
214 | #endif | ||
215 | static int setup_hostid = -1; | 198 | static int setup_hostid = -1; |
216 | module_param(setup_hostid, int, 0); | 199 | module_param(setup_hostid, int, 0); |
200 | static int setup_toshiba_delay = -1; | ||
201 | module_param(setup_toshiba_delay, int, 0); | ||
217 | 202 | ||
218 | 203 | ||
219 | #if defined(REAL_DMA) | 204 | #if defined(REAL_DMA) |
@@ -273,15 +258,17 @@ static void scsi_dma_buserr(int irq, void *dummy) | |||
273 | #endif | 258 | #endif |
274 | 259 | ||
275 | 260 | ||
276 | static irqreturn_t scsi_tt_intr(int irq, void *dummy) | 261 | static irqreturn_t scsi_tt_intr(int irq, void *dev) |
277 | { | 262 | { |
278 | #ifdef REAL_DMA | 263 | #ifdef REAL_DMA |
264 | struct Scsi_Host *instance = dev; | ||
265 | struct NCR5380_hostdata *hostdata = shost_priv(instance); | ||
279 | int dma_stat; | 266 | int dma_stat; |
280 | 267 | ||
281 | dma_stat = tt_scsi_dma.dma_ctrl; | 268 | dma_stat = tt_scsi_dma.dma_ctrl; |
282 | 269 | ||
283 | dprintk(NDEBUG_INTR, "scsi%d: NCR5380 interrupt, DMA status = %02x\n", | 270 | dsprintk(NDEBUG_INTR, instance, "NCR5380 interrupt, DMA status = %02x\n", |
284 | atari_scsi_host->host_no, dma_stat & 0xff); | 271 | dma_stat & 0xff); |
285 | 272 | ||
286 | /* Look if it was the DMA that has interrupted: First possibility | 273 | /* Look if it was the DMA that has interrupted: First possibility |
287 | * is that a bus error occurred... | 274 | * is that a bus error occurred... |
@@ -304,7 +291,8 @@ static irqreturn_t scsi_tt_intr(int irq, void *dummy) | |||
304 | * data reg! | 291 | * data reg! |
305 | */ | 292 | */ |
306 | if ((dma_stat & 0x02) && !(dma_stat & 0x40)) { | 293 | if ((dma_stat & 0x02) && !(dma_stat & 0x40)) { |
307 | atari_dma_residual = HOSTDATA_DMALEN - (SCSI_DMA_READ_P(dma_addr) - atari_dma_startaddr); | 294 | atari_dma_residual = hostdata->dma_len - |
295 | (SCSI_DMA_READ_P(dma_addr) - atari_dma_startaddr); | ||
308 | 296 | ||
309 | dprintk(NDEBUG_DMA, "SCSI DMA: There are %ld residual bytes.\n", | 297 | dprintk(NDEBUG_DMA, "SCSI DMA: There are %ld residual bytes.\n", |
310 | atari_dma_residual); | 298 | atari_dma_residual); |
@@ -356,15 +344,17 @@ static irqreturn_t scsi_tt_intr(int irq, void *dummy) | |||
356 | 344 | ||
357 | #endif /* REAL_DMA */ | 345 | #endif /* REAL_DMA */ |
358 | 346 | ||
359 | NCR5380_intr(irq, dummy); | 347 | NCR5380_intr(irq, dev); |
360 | 348 | ||
361 | return IRQ_HANDLED; | 349 | return IRQ_HANDLED; |
362 | } | 350 | } |
363 | 351 | ||
364 | 352 | ||
365 | static irqreturn_t scsi_falcon_intr(int irq, void *dummy) | 353 | static irqreturn_t scsi_falcon_intr(int irq, void *dev) |
366 | { | 354 | { |
367 | #ifdef REAL_DMA | 355 | #ifdef REAL_DMA |
356 | struct Scsi_Host *instance = dev; | ||
357 | struct NCR5380_hostdata *hostdata = shost_priv(instance); | ||
368 | int dma_stat; | 358 | int dma_stat; |
369 | 359 | ||
370 | /* Turn off DMA and select sector counter register before | 360 | /* Turn off DMA and select sector counter register before |
@@ -399,7 +389,7 @@ static irqreturn_t scsi_falcon_intr(int irq, void *dummy) | |||
399 | printk(KERN_ERR "SCSI DMA error: %ld bytes lost in " | 389 | printk(KERN_ERR "SCSI DMA error: %ld bytes lost in " |
400 | "ST-DMA fifo\n", transferred & 15); | 390 | "ST-DMA fifo\n", transferred & 15); |
401 | 391 | ||
402 | atari_dma_residual = HOSTDATA_DMALEN - transferred; | 392 | atari_dma_residual = hostdata->dma_len - transferred; |
403 | dprintk(NDEBUG_DMA, "SCSI DMA: There are %ld residual bytes.\n", | 393 | dprintk(NDEBUG_DMA, "SCSI DMA: There are %ld residual bytes.\n", |
404 | atari_dma_residual); | 394 | atari_dma_residual); |
405 | } else | 395 | } else |
@@ -411,13 +401,14 @@ static irqreturn_t scsi_falcon_intr(int irq, void *dummy) | |||
411 | * data to the original destination address. | 401 | * data to the original destination address. |
412 | */ | 402 | */ |
413 | memcpy(atari_dma_orig_addr, phys_to_virt(atari_dma_startaddr), | 403 | memcpy(atari_dma_orig_addr, phys_to_virt(atari_dma_startaddr), |
414 | HOSTDATA_DMALEN - atari_dma_residual); | 404 | hostdata->dma_len - atari_dma_residual); |
415 | atari_dma_orig_addr = NULL; | 405 | atari_dma_orig_addr = NULL; |
416 | } | 406 | } |
417 | 407 | ||
418 | #endif /* REAL_DMA */ | 408 | #endif /* REAL_DMA */ |
419 | 409 | ||
420 | NCR5380_intr(irq, dummy); | 410 | NCR5380_intr(irq, dev); |
411 | |||
421 | return IRQ_HANDLED; | 412 | return IRQ_HANDLED; |
422 | } | 413 | } |
423 | 414 | ||
@@ -488,7 +479,7 @@ static int __init atari_scsi_setup(char *str) | |||
488 | * Defaults depend on TT or Falcon, determined at run time. | 479 | * Defaults depend on TT or Falcon, determined at run time. |
489 | * Negative values mean don't change. | 480 | * Negative values mean don't change. |
490 | */ | 481 | */ |
491 | int ints[6]; | 482 | int ints[8]; |
492 | 483 | ||
493 | get_options(str, ARRAY_SIZE(ints), ints); | 484 | get_options(str, ARRAY_SIZE(ints), ints); |
494 | 485 | ||
@@ -504,10 +495,11 @@ static int __init atari_scsi_setup(char *str) | |||
504 | setup_sg_tablesize = ints[3]; | 495 | setup_sg_tablesize = ints[3]; |
505 | if (ints[0] >= 4) | 496 | if (ints[0] >= 4) |
506 | setup_hostid = ints[4]; | 497 | setup_hostid = ints[4]; |
507 | #ifdef SUPPORT_TAGS | ||
508 | if (ints[0] >= 5) | 498 | if (ints[0] >= 5) |
509 | setup_use_tagged_queuing = ints[5]; | 499 | setup_use_tagged_queuing = ints[5]; |
510 | #endif | 500 | /* ints[6] (use_pdma) is ignored */ |
501 | if (ints[0] >= 7) | ||
502 | setup_toshiba_delay = ints[7]; | ||
511 | 503 | ||
512 | return 1; | 504 | return 1; |
513 | } | 505 | } |
@@ -516,38 +508,6 @@ __setup("atascsi=", atari_scsi_setup); | |||
516 | #endif /* !MODULE */ | 508 | #endif /* !MODULE */ |
517 | 509 | ||
518 | 510 | ||
519 | #ifdef CONFIG_ATARI_SCSI_RESET_BOOT | ||
520 | static void __init atari_scsi_reset_boot(void) | ||
521 | { | ||
522 | unsigned long end; | ||
523 | |||
524 | /* | ||
525 | * Do a SCSI reset to clean up the bus during initialization. No messing | ||
526 | * with the queues, interrupts, or locks necessary here. | ||
527 | */ | ||
528 | |||
529 | printk("Atari SCSI: resetting the SCSI bus..."); | ||
530 | |||
531 | /* get in phase */ | ||
532 | NCR5380_write(TARGET_COMMAND_REG, | ||
533 | PHASE_SR_TO_TCR(NCR5380_read(STATUS_REG))); | ||
534 | |||
535 | /* assert RST */ | ||
536 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_RST); | ||
537 | /* The min. reset hold time is 25us, so 40us should be enough */ | ||
538 | udelay(50); | ||
539 | /* reset RST and interrupt */ | ||
540 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); | ||
541 | NCR5380_read(RESET_PARITY_INTERRUPT_REG); | ||
542 | |||
543 | end = jiffies + AFTER_RESET_DELAY; | ||
544 | while (time_before(jiffies, end)) | ||
545 | barrier(); | ||
546 | |||
547 | printk(" done\n"); | ||
548 | } | ||
549 | #endif | ||
550 | |||
551 | #if defined(REAL_DMA) | 511 | #if defined(REAL_DMA) |
552 | 512 | ||
553 | static unsigned long atari_scsi_dma_setup(struct Scsi_Host *instance, | 513 | static unsigned long atari_scsi_dma_setup(struct Scsi_Host *instance, |
@@ -815,14 +775,14 @@ static int atari_scsi_bus_reset(struct scsi_cmnd *cmd) | |||
815 | static struct scsi_host_template atari_scsi_template = { | 775 | static struct scsi_host_template atari_scsi_template = { |
816 | .module = THIS_MODULE, | 776 | .module = THIS_MODULE, |
817 | .proc_name = DRV_MODULE_NAME, | 777 | .proc_name = DRV_MODULE_NAME, |
818 | .show_info = atari_scsi_show_info, | ||
819 | .name = "Atari native SCSI", | 778 | .name = "Atari native SCSI", |
820 | .info = atari_scsi_info, | 779 | .info = atari_scsi_info, |
821 | .queuecommand = atari_scsi_queue_command, | 780 | .queuecommand = atari_scsi_queue_command, |
822 | .eh_abort_handler = atari_scsi_abort, | 781 | .eh_abort_handler = atari_scsi_abort, |
823 | .eh_bus_reset_handler = atari_scsi_bus_reset, | 782 | .eh_bus_reset_handler = atari_scsi_bus_reset, |
824 | .this_id = 7, | 783 | .this_id = 7, |
825 | .use_clustering = DISABLE_CLUSTERING | 784 | .use_clustering = DISABLE_CLUSTERING, |
785 | .cmd_size = NCR5380_CMD_SIZE, | ||
826 | }; | 786 | }; |
827 | 787 | ||
828 | static int __init atari_scsi_probe(struct platform_device *pdev) | 788 | static int __init atari_scsi_probe(struct platform_device *pdev) |
@@ -880,7 +840,7 @@ static int __init atari_scsi_probe(struct platform_device *pdev) | |||
880 | } else { | 840 | } else { |
881 | /* Test if a host id is set in the NVRam */ | 841 | /* Test if a host id is set in the NVRam */ |
882 | if (ATARIHW_PRESENT(TT_CLK) && nvram_check_checksum()) { | 842 | if (ATARIHW_PRESENT(TT_CLK) && nvram_check_checksum()) { |
883 | unsigned char b = nvram_read_byte(14); | 843 | unsigned char b = nvram_read_byte(16); |
884 | 844 | ||
885 | /* Arbitration enabled? (for TOS) | 845 | /* Arbitration enabled? (for TOS) |
886 | * If yes, use configured host ID | 846 | * If yes, use configured host ID |
@@ -915,21 +875,18 @@ static int __init atari_scsi_probe(struct platform_device *pdev) | |||
915 | error = -ENOMEM; | 875 | error = -ENOMEM; |
916 | goto fail_alloc; | 876 | goto fail_alloc; |
917 | } | 877 | } |
918 | atari_scsi_host = instance; | ||
919 | |||
920 | #ifdef CONFIG_ATARI_SCSI_RESET_BOOT | ||
921 | atari_scsi_reset_boot(); | ||
922 | #endif | ||
923 | 878 | ||
924 | instance->irq = irq->start; | 879 | instance->irq = irq->start; |
925 | 880 | ||
926 | host_flags |= IS_A_TT() ? 0 : FLAG_LATE_DMA_SETUP; | 881 | host_flags |= IS_A_TT() ? 0 : FLAG_LATE_DMA_SETUP; |
927 | |||
928 | #ifdef SUPPORT_TAGS | 882 | #ifdef SUPPORT_TAGS |
929 | host_flags |= setup_use_tagged_queuing > 0 ? FLAG_TAGGED_QUEUING : 0; | 883 | host_flags |= setup_use_tagged_queuing > 0 ? FLAG_TAGGED_QUEUING : 0; |
930 | #endif | 884 | #endif |
885 | host_flags |= setup_toshiba_delay > 0 ? FLAG_TOSHIBA_DELAY : 0; | ||
931 | 886 | ||
932 | NCR5380_init(instance, host_flags); | 887 | error = NCR5380_init(instance, host_flags); |
888 | if (error) | ||
889 | goto fail_init; | ||
933 | 890 | ||
934 | if (IS_A_TT()) { | 891 | if (IS_A_TT()) { |
935 | error = request_irq(instance->irq, scsi_tt_intr, 0, | 892 | error = request_irq(instance->irq, scsi_tt_intr, 0, |
@@ -975,6 +932,8 @@ static int __init atari_scsi_probe(struct platform_device *pdev) | |||
975 | #endif | 932 | #endif |
976 | } | 933 | } |
977 | 934 | ||
935 | NCR5380_maybe_reset_bus(instance); | ||
936 | |||
978 | error = scsi_add_host(instance, NULL); | 937 | error = scsi_add_host(instance, NULL); |
979 | if (error) | 938 | if (error) |
980 | goto fail_host; | 939 | goto fail_host; |
@@ -989,6 +948,7 @@ fail_host: | |||
989 | free_irq(instance->irq, instance); | 948 | free_irq(instance->irq, instance); |
990 | fail_irq: | 949 | fail_irq: |
991 | NCR5380_exit(instance); | 950 | NCR5380_exit(instance); |
951 | fail_init: | ||
992 | scsi_host_put(instance); | 952 | scsi_host_put(instance); |
993 | fail_alloc: | 953 | fail_alloc: |
994 | if (atari_dma_buffer) | 954 | if (atari_dma_buffer) |
diff --git a/drivers/scsi/cxgbi/cxgb3i/cxgb3i.c b/drivers/scsi/cxgbi/cxgb3i/cxgb3i.c index 0e2bee937fe8..e22a268fd311 100644 --- a/drivers/scsi/cxgbi/cxgb3i/cxgb3i.c +++ b/drivers/scsi/cxgbi/cxgb3i/cxgb3i.c | |||
@@ -57,7 +57,7 @@ MODULE_PARM_DESC(cxgb3i_snd_win, "TCP send window in bytes (default=128KB)"); | |||
57 | 57 | ||
58 | static int cxgb3i_rx_credit_thres = 10 * 1024; | 58 | static int cxgb3i_rx_credit_thres = 10 * 1024; |
59 | module_param(cxgb3i_rx_credit_thres, int, 0644); | 59 | module_param(cxgb3i_rx_credit_thres, int, 0644); |
60 | MODULE_PARM_DESC(rx_credit_thres, | 60 | MODULE_PARM_DESC(cxgb3i_rx_credit_thres, |
61 | "RX credits return threshold in bytes (default=10KB)"); | 61 | "RX credits return threshold in bytes (default=10KB)"); |
62 | 62 | ||
63 | static unsigned int cxgb3i_max_connect = 8 * 1024; | 63 | static unsigned int cxgb3i_max_connect = 8 * 1024; |
diff --git a/drivers/scsi/dmx3191d.c b/drivers/scsi/dmx3191d.c index 3e088125a8be..6c14e68b9e1a 100644 --- a/drivers/scsi/dmx3191d.c +++ b/drivers/scsi/dmx3191d.c | |||
@@ -36,17 +36,10 @@ | |||
36 | 36 | ||
37 | #define DONT_USE_INTR | 37 | #define DONT_USE_INTR |
38 | 38 | ||
39 | #define NCR5380_read(reg) inb(port + reg) | 39 | #define NCR5380_read(reg) inb(instance->io_port + reg) |
40 | #define NCR5380_write(reg, value) outb(value, port + reg) | 40 | #define NCR5380_write(reg, value) outb(value, instance->io_port + reg) |
41 | 41 | ||
42 | #define NCR5380_implementation_fields /* none */ | 42 | #define NCR5380_implementation_fields /* none */ |
43 | #define NCR5380_local_declare() unsigned int port | ||
44 | #define NCR5380_setup(instance) port = instance->io_port | ||
45 | |||
46 | /* | ||
47 | * Includes needed for NCR5380.[ch] (XXX: Move them to NCR5380.h) | ||
48 | */ | ||
49 | #include <linux/delay.h> | ||
50 | 43 | ||
51 | #include "NCR5380.h" | 44 | #include "NCR5380.h" |
52 | #include "NCR5380.c" | 45 | #include "NCR5380.c" |
@@ -56,6 +49,7 @@ | |||
56 | 49 | ||
57 | 50 | ||
58 | static struct scsi_host_template dmx3191d_driver_template = { | 51 | static struct scsi_host_template dmx3191d_driver_template = { |
52 | .module = THIS_MODULE, | ||
59 | .proc_name = DMX3191D_DRIVER_NAME, | 53 | .proc_name = DMX3191D_DRIVER_NAME, |
60 | .name = "Domex DMX3191D", | 54 | .name = "Domex DMX3191D", |
61 | .info = NCR5380_info, | 55 | .info = NCR5380_info, |
@@ -67,6 +61,8 @@ static struct scsi_host_template dmx3191d_driver_template = { | |||
67 | .sg_tablesize = SG_ALL, | 61 | .sg_tablesize = SG_ALL, |
68 | .cmd_per_lun = 2, | 62 | .cmd_per_lun = 2, |
69 | .use_clustering = DISABLE_CLUSTERING, | 63 | .use_clustering = DISABLE_CLUSTERING, |
64 | .cmd_size = NCR5380_CMD_SIZE, | ||
65 | .max_sectors = 128, | ||
70 | }; | 66 | }; |
71 | 67 | ||
72 | static int dmx3191d_probe_one(struct pci_dev *pdev, | 68 | static int dmx3191d_probe_one(struct pci_dev *pdev, |
@@ -97,17 +93,25 @@ static int dmx3191d_probe_one(struct pci_dev *pdev, | |||
97 | */ | 93 | */ |
98 | shost->irq = NO_IRQ; | 94 | shost->irq = NO_IRQ; |
99 | 95 | ||
100 | NCR5380_init(shost, FLAG_NO_PSEUDO_DMA | FLAG_DTC3181E); | 96 | error = NCR5380_init(shost, FLAG_NO_PSEUDO_DMA); |
97 | if (error) | ||
98 | goto out_host_put; | ||
99 | |||
100 | NCR5380_maybe_reset_bus(shost); | ||
101 | 101 | ||
102 | pci_set_drvdata(pdev, shost); | 102 | pci_set_drvdata(pdev, shost); |
103 | 103 | ||
104 | error = scsi_add_host(shost, &pdev->dev); | 104 | error = scsi_add_host(shost, &pdev->dev); |
105 | if (error) | 105 | if (error) |
106 | goto out_release_region; | 106 | goto out_exit; |
107 | 107 | ||
108 | scsi_scan_host(shost); | 108 | scsi_scan_host(shost); |
109 | return 0; | 109 | return 0; |
110 | 110 | ||
111 | out_exit: | ||
112 | NCR5380_exit(shost); | ||
113 | out_host_put: | ||
114 | scsi_host_put(shost); | ||
111 | out_release_region: | 115 | out_release_region: |
112 | release_region(io, DMX3191D_REGION_LEN); | 116 | release_region(io, DMX3191D_REGION_LEN); |
113 | out_disable_device: | 117 | out_disable_device: |
@@ -119,15 +123,14 @@ static int dmx3191d_probe_one(struct pci_dev *pdev, | |||
119 | static void dmx3191d_remove_one(struct pci_dev *pdev) | 123 | static void dmx3191d_remove_one(struct pci_dev *pdev) |
120 | { | 124 | { |
121 | struct Scsi_Host *shost = pci_get_drvdata(pdev); | 125 | struct Scsi_Host *shost = pci_get_drvdata(pdev); |
126 | unsigned long io = shost->io_port; | ||
122 | 127 | ||
123 | scsi_remove_host(shost); | 128 | scsi_remove_host(shost); |
124 | 129 | ||
125 | NCR5380_exit(shost); | 130 | NCR5380_exit(shost); |
126 | |||
127 | release_region(shost->io_port, DMX3191D_REGION_LEN); | ||
128 | pci_disable_device(pdev); | ||
129 | |||
130 | scsi_host_put(shost); | 131 | scsi_host_put(shost); |
132 | release_region(io, DMX3191D_REGION_LEN); | ||
133 | pci_disable_device(pdev); | ||
131 | } | 134 | } |
132 | 135 | ||
133 | static struct pci_device_id dmx3191d_pci_tbl[] = { | 136 | static struct pci_device_id dmx3191d_pci_tbl[] = { |
diff --git a/drivers/scsi/dtc.c b/drivers/scsi/dtc.c index 4c74c7ba2dff..6c736b071cf4 100644 --- a/drivers/scsi/dtc.c +++ b/drivers/scsi/dtc.c | |||
@@ -1,9 +1,5 @@ | |||
1 | |||
2 | #define PSEUDO_DMA | 1 | #define PSEUDO_DMA |
3 | #define DONT_USE_INTR | 2 | #define DONT_USE_INTR |
4 | #define UNSAFE /* Leave interrupts enabled during pseudo-dma I/O */ | ||
5 | #define DMA_WORKS_RIGHT | ||
6 | |||
7 | 3 | ||
8 | /* | 4 | /* |
9 | * DTC 3180/3280 driver, by | 5 | * DTC 3180/3280 driver, by |
@@ -50,15 +46,13 @@ | |||
50 | 46 | ||
51 | 47 | ||
52 | #include <linux/module.h> | 48 | #include <linux/module.h> |
53 | #include <linux/signal.h> | ||
54 | #include <linux/blkdev.h> | 49 | #include <linux/blkdev.h> |
55 | #include <linux/delay.h> | ||
56 | #include <linux/stat.h> | ||
57 | #include <linux/string.h> | 50 | #include <linux/string.h> |
58 | #include <linux/init.h> | 51 | #include <linux/init.h> |
59 | #include <linux/interrupt.h> | 52 | #include <linux/interrupt.h> |
60 | #include <linux/io.h> | 53 | #include <linux/io.h> |
61 | #include <scsi/scsi_host.h> | 54 | #include <scsi/scsi_host.h> |
55 | |||
62 | #include "dtc.h" | 56 | #include "dtc.h" |
63 | #define AUTOPROBE_IRQ | 57 | #define AUTOPROBE_IRQ |
64 | #include "NCR5380.h" | 58 | #include "NCR5380.h" |
@@ -150,7 +144,7 @@ static const struct signature { | |||
150 | 144 | ||
151 | static int __init dtc_setup(char *str) | 145 | static int __init dtc_setup(char *str) |
152 | { | 146 | { |
153 | static int commandline_current = 0; | 147 | static int commandline_current; |
154 | int i; | 148 | int i; |
155 | int ints[10]; | 149 | int ints[10]; |
156 | 150 | ||
@@ -188,7 +182,7 @@ __setup("dtc=", dtc_setup); | |||
188 | 182 | ||
189 | static int __init dtc_detect(struct scsi_host_template * tpnt) | 183 | static int __init dtc_detect(struct scsi_host_template * tpnt) |
190 | { | 184 | { |
191 | static int current_override = 0, current_base = 0; | 185 | static int current_override, current_base; |
192 | struct Scsi_Host *instance; | 186 | struct Scsi_Host *instance; |
193 | unsigned int addr; | 187 | unsigned int addr; |
194 | void __iomem *base; | 188 | void __iomem *base; |
@@ -205,9 +199,8 @@ static int __init dtc_detect(struct scsi_host_template * tpnt) | |||
205 | addr = 0; | 199 | addr = 0; |
206 | } else | 200 | } else |
207 | for (; !addr && (current_base < NO_BASES); ++current_base) { | 201 | for (; !addr && (current_base < NO_BASES); ++current_base) { |
208 | #if (DTCDEBUG & DTCDEBUG_INIT) | 202 | dprintk(NDEBUG_INIT, "dtc: probing address 0x%08x\n", |
209 | printk(KERN_DEBUG "scsi-dtc : probing address %08x\n", bases[current_base].address); | 203 | (unsigned int)bases[current_base].address); |
210 | #endif | ||
211 | if (bases[current_base].noauto) | 204 | if (bases[current_base].noauto) |
212 | continue; | 205 | continue; |
213 | base = ioremap(bases[current_base].address, 0x2000); | 206 | base = ioremap(bases[current_base].address, 0x2000); |
@@ -216,18 +209,14 @@ static int __init dtc_detect(struct scsi_host_template * tpnt) | |||
216 | for (sig = 0; sig < NO_SIGNATURES; ++sig) { | 209 | for (sig = 0; sig < NO_SIGNATURES; ++sig) { |
217 | if (check_signature(base + signatures[sig].offset, signatures[sig].string, strlen(signatures[sig].string))) { | 210 | if (check_signature(base + signatures[sig].offset, signatures[sig].string, strlen(signatures[sig].string))) { |
218 | addr = bases[current_base].address; | 211 | addr = bases[current_base].address; |
219 | #if (DTCDEBUG & DTCDEBUG_INIT) | 212 | dprintk(NDEBUG_INIT, "dtc: detected board\n"); |
220 | printk(KERN_DEBUG "scsi-dtc : detected board.\n"); | ||
221 | #endif | ||
222 | goto found; | 213 | goto found; |
223 | } | 214 | } |
224 | } | 215 | } |
225 | iounmap(base); | 216 | iounmap(base); |
226 | } | 217 | } |
227 | 218 | ||
228 | #if defined(DTCDEBUG) && (DTCDEBUG & DTCDEBUG_INIT) | 219 | dprintk(NDEBUG_INIT, "dtc: addr = 0x%08x\n", addr); |
229 | printk(KERN_DEBUG "scsi-dtc : base = %08x\n", addr); | ||
230 | #endif | ||
231 | 220 | ||
232 | if (!addr) | 221 | if (!addr) |
233 | break; | 222 | break; |
@@ -235,12 +224,15 @@ static int __init dtc_detect(struct scsi_host_template * tpnt) | |||
235 | found: | 224 | found: |
236 | instance = scsi_register(tpnt, sizeof(struct NCR5380_hostdata)); | 225 | instance = scsi_register(tpnt, sizeof(struct NCR5380_hostdata)); |
237 | if (instance == NULL) | 226 | if (instance == NULL) |
238 | break; | 227 | goto out_unmap; |
239 | 228 | ||
240 | instance->base = addr; | 229 | instance->base = addr; |
241 | ((struct NCR5380_hostdata *)(instance)->hostdata)->base = base; | 230 | ((struct NCR5380_hostdata *)(instance)->hostdata)->base = base; |
242 | 231 | ||
243 | NCR5380_init(instance, 0); | 232 | if (NCR5380_init(instance, FLAG_NO_DMA_FIXUP)) |
233 | goto out_unregister; | ||
234 | |||
235 | NCR5380_maybe_reset_bus(instance); | ||
244 | 236 | ||
245 | NCR5380_write(DTC_CONTROL_REG, CSR_5380_INTR); /* Enable int's */ | 237 | NCR5380_write(DTC_CONTROL_REG, CSR_5380_INTR); /* Enable int's */ |
246 | if (overrides[current_override].irq != IRQ_AUTO) | 238 | if (overrides[current_override].irq != IRQ_AUTO) |
@@ -271,14 +263,19 @@ found: | |||
271 | printk(KERN_WARNING "scsi%d : interrupts not used. Might as well not jumper it.\n", instance->host_no); | 263 | printk(KERN_WARNING "scsi%d : interrupts not used. Might as well not jumper it.\n", instance->host_no); |
272 | instance->irq = NO_IRQ; | 264 | instance->irq = NO_IRQ; |
273 | #endif | 265 | #endif |
274 | #if defined(DTCDEBUG) && (DTCDEBUG & DTCDEBUG_INIT) | 266 | dprintk(NDEBUG_INIT, "scsi%d : irq = %d\n", |
275 | printk("scsi%d : irq = %d\n", instance->host_no, instance->irq); | 267 | instance->host_no, instance->irq); |
276 | #endif | ||
277 | 268 | ||
278 | ++current_override; | 269 | ++current_override; |
279 | ++count; | 270 | ++count; |
280 | } | 271 | } |
281 | return count; | 272 | return count; |
273 | |||
274 | out_unregister: | ||
275 | scsi_unregister(instance); | ||
276 | out_unmap: | ||
277 | iounmap(base); | ||
278 | return count; | ||
282 | } | 279 | } |
283 | 280 | ||
284 | /* | 281 | /* |
@@ -331,12 +328,8 @@ static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst, | |||
331 | unsigned char *d = dst; | 328 | unsigned char *d = dst; |
332 | int i; /* For counting time spent in the poll-loop */ | 329 | int i; /* For counting time spent in the poll-loop */ |
333 | struct NCR5380_hostdata *hostdata = shost_priv(instance); | 330 | struct NCR5380_hostdata *hostdata = shost_priv(instance); |
334 | NCR5380_local_declare(); | ||
335 | NCR5380_setup(instance); | ||
336 | 331 | ||
337 | i = 0; | 332 | i = 0; |
338 | NCR5380_read(RESET_PARITY_INTERRUPT_REG); | ||
339 | NCR5380_write(MODE_REG, MR_ENABLE_EOP_INTR | MR_DMA_MODE); | ||
340 | if (instance->irq == NO_IRQ) | 333 | if (instance->irq == NO_IRQ) |
341 | NCR5380_write(DTC_CONTROL_REG, CSR_DIR_READ); | 334 | NCR5380_write(DTC_CONTROL_REG, CSR_DIR_READ); |
342 | else | 335 | else |
@@ -348,7 +341,7 @@ static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst, | |||
348 | while (NCR5380_read(DTC_CONTROL_REG) & CSR_HOST_BUF_NOT_RDY) | 341 | while (NCR5380_read(DTC_CONTROL_REG) & CSR_HOST_BUF_NOT_RDY) |
349 | ++i; | 342 | ++i; |
350 | rtrc(3); | 343 | rtrc(3); |
351 | memcpy_fromio(d, base + DTC_DATA_BUF, 128); | 344 | memcpy_fromio(d, hostdata->base + DTC_DATA_BUF, 128); |
352 | d += 128; | 345 | d += 128; |
353 | len -= 128; | 346 | len -= 128; |
354 | rtrc(7); | 347 | rtrc(7); |
@@ -358,9 +351,7 @@ static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst, | |||
358 | rtrc(4); | 351 | rtrc(4); |
359 | while (!(NCR5380_read(DTC_CONTROL_REG) & D_CR_ACCESS)) | 352 | while (!(NCR5380_read(DTC_CONTROL_REG) & D_CR_ACCESS)) |
360 | ++i; | 353 | ++i; |
361 | NCR5380_write(MODE_REG, 0); /* Clear the operating mode */ | ||
362 | rtrc(0); | 354 | rtrc(0); |
363 | NCR5380_read(RESET_PARITY_INTERRUPT_REG); | ||
364 | if (i > hostdata->spin_max_r) | 355 | if (i > hostdata->spin_max_r) |
365 | hostdata->spin_max_r = i; | 356 | hostdata->spin_max_r = i; |
366 | return (0); | 357 | return (0); |
@@ -383,12 +374,7 @@ static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src, | |||
383 | { | 374 | { |
384 | int i; | 375 | int i; |
385 | struct NCR5380_hostdata *hostdata = shost_priv(instance); | 376 | struct NCR5380_hostdata *hostdata = shost_priv(instance); |
386 | NCR5380_local_declare(); | ||
387 | NCR5380_setup(instance); | ||
388 | 377 | ||
389 | NCR5380_read(RESET_PARITY_INTERRUPT_REG); | ||
390 | NCR5380_write(MODE_REG, MR_ENABLE_EOP_INTR | MR_DMA_MODE); | ||
391 | /* set direction (write) */ | ||
392 | if (instance->irq == NO_IRQ) | 378 | if (instance->irq == NO_IRQ) |
393 | NCR5380_write(DTC_CONTROL_REG, 0); | 379 | NCR5380_write(DTC_CONTROL_REG, 0); |
394 | else | 380 | else |
@@ -400,7 +386,7 @@ static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src, | |||
400 | while (NCR5380_read(DTC_CONTROL_REG) & CSR_HOST_BUF_NOT_RDY) | 386 | while (NCR5380_read(DTC_CONTROL_REG) & CSR_HOST_BUF_NOT_RDY) |
401 | ++i; | 387 | ++i; |
402 | rtrc(3); | 388 | rtrc(3); |
403 | memcpy_toio(base + DTC_DATA_BUF, src, 128); | 389 | memcpy_toio(hostdata->base + DTC_DATA_BUF, src, 128); |
404 | src += 128; | 390 | src += 128; |
405 | len -= 128; | 391 | len -= 128; |
406 | } | 392 | } |
@@ -413,47 +399,60 @@ static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src, | |||
413 | ++i; | 399 | ++i; |
414 | rtrc(7); | 400 | rtrc(7); |
415 | /* Check for parity error here. fixme. */ | 401 | /* Check for parity error here. fixme. */ |
416 | NCR5380_write(MODE_REG, 0); /* Clear the operating mode */ | ||
417 | rtrc(0); | 402 | rtrc(0); |
418 | if (i > hostdata->spin_max_w) | 403 | if (i > hostdata->spin_max_w) |
419 | hostdata->spin_max_w = i; | 404 | hostdata->spin_max_w = i; |
420 | return (0); | 405 | return (0); |
421 | } | 406 | } |
422 | 407 | ||
408 | static int dtc_dma_xfer_len(struct scsi_cmnd *cmd) | ||
409 | { | ||
410 | int transfersize = cmd->transfersize; | ||
411 | |||
412 | /* Limit transfers to 32K, for xx400 & xx406 | ||
413 | * pseudoDMA that transfers in 128 bytes blocks. | ||
414 | */ | ||
415 | if (transfersize > 32 * 1024 && cmd->SCp.this_residual && | ||
416 | !(cmd->SCp.this_residual % transfersize)) | ||
417 | transfersize = 32 * 1024; | ||
418 | |||
419 | return transfersize; | ||
420 | } | ||
421 | |||
423 | MODULE_LICENSE("GPL"); | 422 | MODULE_LICENSE("GPL"); |
424 | 423 | ||
425 | #include "NCR5380.c" | 424 | #include "NCR5380.c" |
426 | 425 | ||
427 | static int dtc_release(struct Scsi_Host *shost) | 426 | static int dtc_release(struct Scsi_Host *shost) |
428 | { | 427 | { |
429 | NCR5380_local_declare(); | 428 | struct NCR5380_hostdata *hostdata = shost_priv(shost); |
430 | NCR5380_setup(shost); | 429 | |
431 | if (shost->irq != NO_IRQ) | 430 | if (shost->irq != NO_IRQ) |
432 | free_irq(shost->irq, shost); | 431 | free_irq(shost->irq, shost); |
433 | NCR5380_exit(shost); | 432 | NCR5380_exit(shost); |
434 | if (shost->io_port && shost->n_io_port) | ||
435 | release_region(shost->io_port, shost->n_io_port); | ||
436 | scsi_unregister(shost); | 433 | scsi_unregister(shost); |
437 | iounmap(base); | 434 | iounmap(hostdata->base); |
438 | return 0; | 435 | return 0; |
439 | } | 436 | } |
440 | 437 | ||
441 | static struct scsi_host_template driver_template = { | 438 | static struct scsi_host_template driver_template = { |
442 | .name = "DTC 3180/3280 ", | 439 | .name = "DTC 3180/3280", |
443 | .detect = dtc_detect, | 440 | .detect = dtc_detect, |
444 | .release = dtc_release, | 441 | .release = dtc_release, |
445 | .proc_name = "dtc3x80", | 442 | .proc_name = "dtc3x80", |
446 | .show_info = dtc_show_info, | 443 | .show_info = dtc_show_info, |
447 | .write_info = dtc_write_info, | 444 | .write_info = dtc_write_info, |
448 | .info = dtc_info, | 445 | .info = dtc_info, |
449 | .queuecommand = dtc_queue_command, | 446 | .queuecommand = dtc_queue_command, |
450 | .eh_abort_handler = dtc_abort, | 447 | .eh_abort_handler = dtc_abort, |
451 | .eh_bus_reset_handler = dtc_bus_reset, | 448 | .eh_bus_reset_handler = dtc_bus_reset, |
452 | .bios_param = dtc_biosparam, | 449 | .bios_param = dtc_biosparam, |
453 | .can_queue = CAN_QUEUE, | 450 | .can_queue = 32, |
454 | .this_id = 7, | 451 | .this_id = 7, |
455 | .sg_tablesize = SG_ALL, | 452 | .sg_tablesize = SG_ALL, |
456 | .cmd_per_lun = CMD_PER_LUN, | 453 | .cmd_per_lun = 2, |
457 | .use_clustering = DISABLE_CLUSTERING, | 454 | .use_clustering = DISABLE_CLUSTERING, |
455 | .cmd_size = NCR5380_CMD_SIZE, | ||
456 | .max_sectors = 128, | ||
458 | }; | 457 | }; |
459 | #include "scsi_module.c" | 458 | #include "scsi_module.c" |
diff --git a/drivers/scsi/dtc.h b/drivers/scsi/dtc.h index 78a2332e9064..56732cba8aba 100644 --- a/drivers/scsi/dtc.h +++ b/drivers/scsi/dtc.h | |||
@@ -10,54 +10,17 @@ | |||
10 | #ifndef DTC3280_H | 10 | #ifndef DTC3280_H |
11 | #define DTC3280_H | 11 | #define DTC3280_H |
12 | 12 | ||
13 | #define DTCDEBUG 0 | ||
14 | #define DTCDEBUG_INIT 0x1 | ||
15 | #define DTCDEBUG_TRANSFER 0x2 | ||
16 | |||
17 | #ifndef CMD_PER_LUN | ||
18 | #define CMD_PER_LUN 2 | ||
19 | #endif | ||
20 | |||
21 | #ifndef CAN_QUEUE | ||
22 | #define CAN_QUEUE 32 | ||
23 | #endif | ||
24 | |||
25 | #define NCR5380_implementation_fields \ | 13 | #define NCR5380_implementation_fields \ |
26 | void __iomem *base | 14 | void __iomem *base |
27 | 15 | ||
28 | #define NCR5380_local_declare() \ | 16 | #define DTC_address(reg) \ |
29 | void __iomem *base | 17 | (((struct NCR5380_hostdata *)shost_priv(instance))->base + DTC_5380_OFFSET + reg) |
30 | |||
31 | #define NCR5380_setup(instance) \ | ||
32 | base = ((struct NCR5380_hostdata *)(instance)->hostdata)->base | ||
33 | 18 | ||
34 | #define DTC_address(reg) (base + DTC_5380_OFFSET + reg) | ||
35 | |||
36 | #define dbNCR5380_read(reg) \ | ||
37 | (rval=readb(DTC_address(reg)), \ | ||
38 | (((unsigned char) printk("DTC : read register %d at addr %p is: %02x\n"\ | ||
39 | , (reg), DTC_address(reg), rval)), rval ) ) | ||
40 | |||
41 | #define dbNCR5380_write(reg, value) do { \ | ||
42 | printk("DTC : write %02x to register %d at address %p\n", \ | ||
43 | (value), (reg), DTC_address(reg)); \ | ||
44 | writeb(value, DTC_address(reg));} while(0) | ||
45 | |||
46 | |||
47 | #if !(DTCDEBUG & DTCDEBUG_TRANSFER) | ||
48 | #define NCR5380_read(reg) (readb(DTC_address(reg))) | 19 | #define NCR5380_read(reg) (readb(DTC_address(reg))) |
49 | #define NCR5380_write(reg, value) (writeb(value, DTC_address(reg))) | 20 | #define NCR5380_write(reg, value) (writeb(value, DTC_address(reg))) |
50 | #else | ||
51 | #define NCR5380_read(reg) (readb(DTC_address(reg))) | ||
52 | #define xNCR5380_read(reg) \ | ||
53 | (((unsigned char) printk("DTC : read register %d at address %p\n"\ | ||
54 | , (reg), DTC_address(reg))), readb(DTC_address(reg))) | ||
55 | 21 | ||
56 | #define NCR5380_write(reg, value) do { \ | 22 | #define NCR5380_dma_xfer_len(instance, cmd, phase) \ |
57 | printk("DTC : write %02x to register %d at address %p\n", \ | 23 | dtc_dma_xfer_len(cmd) |
58 | (value), (reg), DTC_address(reg)); \ | ||
59 | writeb(value, DTC_address(reg));} while(0) | ||
60 | #endif | ||
61 | 24 | ||
62 | #define NCR5380_intr dtc_intr | 25 | #define NCR5380_intr dtc_intr |
63 | #define NCR5380_queue_command dtc_queue_command | 26 | #define NCR5380_queue_command dtc_queue_command |
diff --git a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c index f8d2478b11cc..90091e693020 100644 --- a/drivers/scsi/g_NCR5380.c +++ b/drivers/scsi/g_NCR5380.c | |||
@@ -56,40 +56,31 @@ | |||
56 | * | 56 | * |
57 | */ | 57 | */ |
58 | 58 | ||
59 | /* settings for DTC3181E card with only Mustek scanner attached */ | ||
60 | #define USLEEP_POLL msecs_to_jiffies(10) | ||
61 | #define USLEEP_SLEEP msecs_to_jiffies(200) | ||
62 | #define USLEEP_WAITLONG msecs_to_jiffies(5000) | ||
63 | |||
64 | #define AUTOPROBE_IRQ | 59 | #define AUTOPROBE_IRQ |
65 | 60 | ||
66 | #ifdef CONFIG_SCSI_GENERIC_NCR53C400 | 61 | #ifdef CONFIG_SCSI_GENERIC_NCR53C400 |
67 | #define NCR53C400_PSEUDO_DMA 1 | ||
68 | #define PSEUDO_DMA | 62 | #define PSEUDO_DMA |
69 | #define NCR53C400 | ||
70 | #endif | 63 | #endif |
71 | 64 | ||
72 | #include <asm/io.h> | 65 | #include <asm/io.h> |
73 | #include <linux/signal.h> | ||
74 | #include <linux/blkdev.h> | 66 | #include <linux/blkdev.h> |
67 | #include <linux/module.h> | ||
75 | #include <scsi/scsi_host.h> | 68 | #include <scsi/scsi_host.h> |
76 | #include "g_NCR5380.h" | 69 | #include "g_NCR5380.h" |
77 | #include "NCR5380.h" | 70 | #include "NCR5380.h" |
78 | #include <linux/stat.h> | ||
79 | #include <linux/init.h> | 71 | #include <linux/init.h> |
80 | #include <linux/ioport.h> | 72 | #include <linux/ioport.h> |
81 | #include <linux/isapnp.h> | 73 | #include <linux/isapnp.h> |
82 | #include <linux/delay.h> | ||
83 | #include <linux/interrupt.h> | 74 | #include <linux/interrupt.h> |
84 | 75 | ||
85 | #define NCR_NOT_SET 0 | 76 | static int ncr_irq; |
86 | static int ncr_irq = NCR_NOT_SET; | 77 | static int ncr_dma; |
87 | static int ncr_dma = NCR_NOT_SET; | 78 | static int ncr_addr; |
88 | static int ncr_addr = NCR_NOT_SET; | 79 | static int ncr_5380; |
89 | static int ncr_5380 = NCR_NOT_SET; | 80 | static int ncr_53c400; |
90 | static int ncr_53c400 = NCR_NOT_SET; | 81 | static int ncr_53c400a; |
91 | static int ncr_53c400a = NCR_NOT_SET; | 82 | static int dtc_3181e; |
92 | static int dtc_3181e = NCR_NOT_SET; | 83 | static int hp_c2502; |
93 | 84 | ||
94 | static struct override { | 85 | static struct override { |
95 | NCR5380_map_type NCR5380_map_name; | 86 | NCR5380_map_type NCR5380_map_name; |
@@ -121,7 +112,7 @@ static struct override { | |||
121 | 112 | ||
122 | static void __init internal_setup(int board, char *str, int *ints) | 113 | static void __init internal_setup(int board, char *str, int *ints) |
123 | { | 114 | { |
124 | static int commandline_current = 0; | 115 | static int commandline_current; |
125 | switch (board) { | 116 | switch (board) { |
126 | case BOARD_NCR5380: | 117 | case BOARD_NCR5380: |
127 | if (ints[0] != 2 && ints[0] != 3) { | 118 | if (ints[0] != 2 && ints[0] != 3) { |
@@ -235,6 +226,30 @@ static int __init do_DTC3181E_setup(char *str) | |||
235 | 226 | ||
236 | #endif | 227 | #endif |
237 | 228 | ||
229 | #ifndef SCSI_G_NCR5380_MEM | ||
230 | /* | ||
231 | * Configure I/O address of 53C400A or DTC436 by writing magic numbers | ||
232 | * to ports 0x779 and 0x379. | ||
233 | */ | ||
234 | static void magic_configure(int idx, u8 irq, u8 magic[]) | ||
235 | { | ||
236 | u8 cfg = 0; | ||
237 | |||
238 | outb(magic[0], 0x779); | ||
239 | outb(magic[1], 0x379); | ||
240 | outb(magic[2], 0x379); | ||
241 | outb(magic[3], 0x379); | ||
242 | outb(magic[4], 0x379); | ||
243 | |||
244 | /* allowed IRQs for HP C2502 */ | ||
245 | if (irq != 2 && irq != 3 && irq != 4 && irq != 5 && irq != 7) | ||
246 | irq = 0; | ||
247 | if (idx >= 0 && idx <= 7) | ||
248 | cfg = 0x80 | idx | (irq << 4); | ||
249 | outb(cfg, 0x379); | ||
250 | } | ||
251 | #endif | ||
252 | |||
238 | /** | 253 | /** |
239 | * generic_NCR5380_detect - look for NCR5380 controllers | 254 | * generic_NCR5380_detect - look for NCR5380 controllers |
240 | * @tpnt: the scsi template | 255 | * @tpnt: the scsi template |
@@ -243,19 +258,18 @@ static int __init do_DTC3181E_setup(char *str) | |||
243 | * and DTC436(ISAPnP) controllers. If overrides have been set we use | 258 | * and DTC436(ISAPnP) controllers. If overrides have been set we use |
244 | * them. | 259 | * them. |
245 | * | 260 | * |
246 | * The caller supplied NCR5380_init function is invoked from here, before | ||
247 | * the interrupt line is taken. | ||
248 | * | ||
249 | * Locks: none | 261 | * Locks: none |
250 | */ | 262 | */ |
251 | 263 | ||
252 | static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt) | 264 | static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt) |
253 | { | 265 | { |
254 | static int current_override = 0; | 266 | static int current_override; |
255 | int count; | 267 | int count; |
256 | unsigned int *ports; | 268 | unsigned int *ports; |
269 | u8 *magic = NULL; | ||
257 | #ifndef SCSI_G_NCR5380_MEM | 270 | #ifndef SCSI_G_NCR5380_MEM |
258 | int i; | 271 | int i; |
272 | int port_idx = -1; | ||
259 | unsigned long region_size = 16; | 273 | unsigned long region_size = 16; |
260 | #endif | 274 | #endif |
261 | static unsigned int __initdata ncr_53c400a_ports[] = { | 275 | static unsigned int __initdata ncr_53c400a_ports[] = { |
@@ -264,27 +278,36 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt) | |||
264 | static unsigned int __initdata dtc_3181e_ports[] = { | 278 | static unsigned int __initdata dtc_3181e_ports[] = { |
265 | 0x220, 0x240, 0x280, 0x2a0, 0x2c0, 0x300, 0x320, 0x340, 0 | 279 | 0x220, 0x240, 0x280, 0x2a0, 0x2c0, 0x300, 0x320, 0x340, 0 |
266 | }; | 280 | }; |
267 | int flags = 0; | 281 | static u8 ncr_53c400a_magic[] __initdata = { /* 53C400A & DTC436 */ |
282 | 0x59, 0xb9, 0xc5, 0xae, 0xa6 | ||
283 | }; | ||
284 | static u8 hp_c2502_magic[] __initdata = { /* HP C2502 */ | ||
285 | 0x0f, 0x22, 0xf0, 0x20, 0x80 | ||
286 | }; | ||
287 | int flags; | ||
268 | struct Scsi_Host *instance; | 288 | struct Scsi_Host *instance; |
289 | struct NCR5380_hostdata *hostdata; | ||
269 | #ifdef SCSI_G_NCR5380_MEM | 290 | #ifdef SCSI_G_NCR5380_MEM |
270 | unsigned long base; | 291 | unsigned long base; |
271 | void __iomem *iomem; | 292 | void __iomem *iomem; |
272 | #endif | 293 | #endif |
273 | 294 | ||
274 | if (ncr_irq != NCR_NOT_SET) | 295 | if (ncr_irq) |
275 | overrides[0].irq = ncr_irq; | 296 | overrides[0].irq = ncr_irq; |
276 | if (ncr_dma != NCR_NOT_SET) | 297 | if (ncr_dma) |
277 | overrides[0].dma = ncr_dma; | 298 | overrides[0].dma = ncr_dma; |
278 | if (ncr_addr != NCR_NOT_SET) | 299 | if (ncr_addr) |
279 | overrides[0].NCR5380_map_name = (NCR5380_map_type) ncr_addr; | 300 | overrides[0].NCR5380_map_name = (NCR5380_map_type) ncr_addr; |
280 | if (ncr_5380 != NCR_NOT_SET) | 301 | if (ncr_5380) |
281 | overrides[0].board = BOARD_NCR5380; | 302 | overrides[0].board = BOARD_NCR5380; |
282 | else if (ncr_53c400 != NCR_NOT_SET) | 303 | else if (ncr_53c400) |
283 | overrides[0].board = BOARD_NCR53C400; | 304 | overrides[0].board = BOARD_NCR53C400; |
284 | else if (ncr_53c400a != NCR_NOT_SET) | 305 | else if (ncr_53c400a) |
285 | overrides[0].board = BOARD_NCR53C400A; | 306 | overrides[0].board = BOARD_NCR53C400A; |
286 | else if (dtc_3181e != NCR_NOT_SET) | 307 | else if (dtc_3181e) |
287 | overrides[0].board = BOARD_DTC3181E; | 308 | overrides[0].board = BOARD_DTC3181E; |
309 | else if (hp_c2502) | ||
310 | overrides[0].board = BOARD_HP_C2502; | ||
288 | #ifndef SCSI_G_NCR5380_MEM | 311 | #ifndef SCSI_G_NCR5380_MEM |
289 | if (!current_override && isapnp_present()) { | 312 | if (!current_override && isapnp_present()) { |
290 | struct pnp_dev *dev = NULL; | 313 | struct pnp_dev *dev = NULL; |
@@ -318,41 +341,45 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt) | |||
318 | } | 341 | } |
319 | } | 342 | } |
320 | #endif | 343 | #endif |
321 | tpnt->proc_name = "g_NCR5380"; | ||
322 | 344 | ||
323 | for (count = 0; current_override < NO_OVERRIDES; ++current_override) { | 345 | for (count = 0; current_override < NO_OVERRIDES; ++current_override) { |
324 | if (!(overrides[current_override].NCR5380_map_name)) | 346 | if (!(overrides[current_override].NCR5380_map_name)) |
325 | continue; | 347 | continue; |
326 | 348 | ||
327 | ports = NULL; | 349 | ports = NULL; |
350 | flags = 0; | ||
328 | switch (overrides[current_override].board) { | 351 | switch (overrides[current_override].board) { |
329 | case BOARD_NCR5380: | 352 | case BOARD_NCR5380: |
330 | flags = FLAG_NO_PSEUDO_DMA; | 353 | flags = FLAG_NO_PSEUDO_DMA; |
331 | break; | 354 | break; |
332 | case BOARD_NCR53C400: | 355 | case BOARD_NCR53C400: |
333 | flags = FLAG_NCR53C400; | 356 | #ifdef PSEUDO_DMA |
357 | flags = FLAG_NO_DMA_FIXUP; | ||
358 | #endif | ||
334 | break; | 359 | break; |
335 | case BOARD_NCR53C400A: | 360 | case BOARD_NCR53C400A: |
336 | flags = FLAG_NO_PSEUDO_DMA; | 361 | flags = FLAG_NO_DMA_FIXUP; |
362 | ports = ncr_53c400a_ports; | ||
363 | magic = ncr_53c400a_magic; | ||
364 | break; | ||
365 | case BOARD_HP_C2502: | ||
366 | flags = FLAG_NO_DMA_FIXUP; | ||
337 | ports = ncr_53c400a_ports; | 367 | ports = ncr_53c400a_ports; |
368 | magic = hp_c2502_magic; | ||
338 | break; | 369 | break; |
339 | case BOARD_DTC3181E: | 370 | case BOARD_DTC3181E: |
340 | flags = FLAG_NO_PSEUDO_DMA | FLAG_DTC3181E; | 371 | flags = FLAG_NO_DMA_FIXUP; |
341 | ports = dtc_3181e_ports; | 372 | ports = dtc_3181e_ports; |
373 | magic = ncr_53c400a_magic; | ||
342 | break; | 374 | break; |
343 | } | 375 | } |
344 | 376 | ||
345 | #ifndef SCSI_G_NCR5380_MEM | 377 | #ifndef SCSI_G_NCR5380_MEM |
346 | if (ports) { | 378 | if (ports && magic) { |
347 | /* wakeup sequence for the NCR53C400A and DTC3181E */ | 379 | /* wakeup sequence for the NCR53C400A and DTC3181E */ |
348 | 380 | ||
349 | /* Disable the adapter and look for a free io port */ | 381 | /* Disable the adapter and look for a free io port */ |
350 | outb(0x59, 0x779); | 382 | magic_configure(-1, 0, magic); |
351 | outb(0xb9, 0x379); | ||
352 | outb(0xc5, 0x379); | ||
353 | outb(0xae, 0x379); | ||
354 | outb(0xa6, 0x379); | ||
355 | outb(0x00, 0x379); | ||
356 | 383 | ||
357 | if (overrides[current_override].NCR5380_map_name != PORT_AUTO) | 384 | if (overrides[current_override].NCR5380_map_name != PORT_AUTO) |
358 | for (i = 0; ports[i]; i++) { | 385 | for (i = 0; ports[i]; i++) { |
@@ -371,17 +398,12 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt) | |||
371 | } | 398 | } |
372 | if (ports[i]) { | 399 | if (ports[i]) { |
373 | /* At this point we have our region reserved */ | 400 | /* At this point we have our region reserved */ |
374 | outb(0x59, 0x779); | 401 | magic_configure(i, 0, magic); /* no IRQ yet */ |
375 | outb(0xb9, 0x379); | ||
376 | outb(0xc5, 0x379); | ||
377 | outb(0xae, 0x379); | ||
378 | outb(0xa6, 0x379); | ||
379 | outb(0x80 | i, 0x379); /* set io port to be used */ | ||
380 | outb(0xc0, ports[i] + 9); | 402 | outb(0xc0, ports[i] + 9); |
381 | if (inb(ports[i] + 9) != 0x80) | 403 | if (inb(ports[i] + 9) != 0x80) |
382 | continue; | 404 | continue; |
383 | else | 405 | overrides[current_override].NCR5380_map_name = ports[i]; |
384 | overrides[current_override].NCR5380_map_name = ports[i]; | 406 | port_idx = i; |
385 | } else | 407 | } else |
386 | continue; | 408 | continue; |
387 | } | 409 | } |
@@ -403,24 +425,65 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt) | |||
403 | } | 425 | } |
404 | #endif | 426 | #endif |
405 | instance = scsi_register(tpnt, sizeof(struct NCR5380_hostdata)); | 427 | instance = scsi_register(tpnt, sizeof(struct NCR5380_hostdata)); |
406 | if (instance == NULL) { | 428 | if (instance == NULL) |
407 | #ifndef SCSI_G_NCR5380_MEM | 429 | goto out_release; |
408 | release_region(overrides[current_override].NCR5380_map_name, region_size); | 430 | hostdata = shost_priv(instance); |
409 | #else | ||
410 | iounmap(iomem); | ||
411 | release_mem_region(base, NCR5380_region_size); | ||
412 | #endif | ||
413 | continue; | ||
414 | } | ||
415 | 431 | ||
416 | instance->NCR5380_instance_name = overrides[current_override].NCR5380_map_name; | ||
417 | #ifndef SCSI_G_NCR5380_MEM | 432 | #ifndef SCSI_G_NCR5380_MEM |
433 | instance->io_port = overrides[current_override].NCR5380_map_name; | ||
418 | instance->n_io_port = region_size; | 434 | instance->n_io_port = region_size; |
435 | hostdata->io_width = 1; /* 8-bit PDMA by default */ | ||
436 | |||
437 | /* | ||
438 | * On NCR53C400 boards, NCR5380 registers are mapped 8 past | ||
439 | * the base address. | ||
440 | */ | ||
441 | switch (overrides[current_override].board) { | ||
442 | case BOARD_NCR53C400: | ||
443 | instance->io_port += 8; | ||
444 | hostdata->c400_ctl_status = 0; | ||
445 | hostdata->c400_blk_cnt = 1; | ||
446 | hostdata->c400_host_buf = 4; | ||
447 | break; | ||
448 | case BOARD_DTC3181E: | ||
449 | hostdata->io_width = 2; /* 16-bit PDMA */ | ||
450 | /* fall through */ | ||
451 | case BOARD_NCR53C400A: | ||
452 | case BOARD_HP_C2502: | ||
453 | hostdata->c400_ctl_status = 9; | ||
454 | hostdata->c400_blk_cnt = 10; | ||
455 | hostdata->c400_host_buf = 8; | ||
456 | break; | ||
457 | } | ||
419 | #else | 458 | #else |
420 | ((struct NCR5380_hostdata *)instance->hostdata)->iomem = iomem; | 459 | instance->base = overrides[current_override].NCR5380_map_name; |
460 | hostdata->iomem = iomem; | ||
461 | switch (overrides[current_override].board) { | ||
462 | case BOARD_NCR53C400: | ||
463 | hostdata->c400_ctl_status = 0x100; | ||
464 | hostdata->c400_blk_cnt = 0x101; | ||
465 | hostdata->c400_host_buf = 0x104; | ||
466 | break; | ||
467 | case BOARD_DTC3181E: | ||
468 | case BOARD_NCR53C400A: | ||
469 | case BOARD_HP_C2502: | ||
470 | pr_err(DRV_MODULE_NAME ": unknown register offsets\n"); | ||
471 | goto out_unregister; | ||
472 | } | ||
421 | #endif | 473 | #endif |
422 | 474 | ||
423 | NCR5380_init(instance, flags); | 475 | if (NCR5380_init(instance, flags)) |
476 | goto out_unregister; | ||
477 | |||
478 | switch (overrides[current_override].board) { | ||
479 | case BOARD_NCR53C400: | ||
480 | case BOARD_DTC3181E: | ||
481 | case BOARD_NCR53C400A: | ||
482 | case BOARD_HP_C2502: | ||
483 | NCR5380_write(hostdata->c400_ctl_status, CSR_BASE); | ||
484 | } | ||
485 | |||
486 | NCR5380_maybe_reset_bus(instance); | ||
424 | 487 | ||
425 | if (overrides[current_override].irq != IRQ_AUTO) | 488 | if (overrides[current_override].irq != IRQ_AUTO) |
426 | instance->irq = overrides[current_override].irq; | 489 | instance->irq = overrides[current_override].irq; |
@@ -431,12 +494,18 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt) | |||
431 | if (instance->irq == 255) | 494 | if (instance->irq == 255) |
432 | instance->irq = NO_IRQ; | 495 | instance->irq = NO_IRQ; |
433 | 496 | ||
434 | if (instance->irq != NO_IRQ) | 497 | if (instance->irq != NO_IRQ) { |
498 | #ifndef SCSI_G_NCR5380_MEM | ||
499 | /* set IRQ for HP C2502 */ | ||
500 | if (overrides[current_override].board == BOARD_HP_C2502) | ||
501 | magic_configure(port_idx, instance->irq, magic); | ||
502 | #endif | ||
435 | if (request_irq(instance->irq, generic_NCR5380_intr, | 503 | if (request_irq(instance->irq, generic_NCR5380_intr, |
436 | 0, "NCR5380", instance)) { | 504 | 0, "NCR5380", instance)) { |
437 | printk(KERN_WARNING "scsi%d : IRQ%d not free, interrupts disabled\n", instance->host_no, instance->irq); | 505 | printk(KERN_WARNING "scsi%d : IRQ%d not free, interrupts disabled\n", instance->host_no, instance->irq); |
438 | instance->irq = NO_IRQ; | 506 | instance->irq = NO_IRQ; |
439 | } | 507 | } |
508 | } | ||
440 | 509 | ||
441 | if (instance->irq == NO_IRQ) { | 510 | if (instance->irq == NO_IRQ) { |
442 | printk(KERN_INFO "scsi%d : interrupts not enabled. for better interactive performance,\n", instance->host_no); | 511 | printk(KERN_INFO "scsi%d : interrupts not enabled. for better interactive performance,\n", instance->host_no); |
@@ -447,6 +516,17 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt) | |||
447 | ++count; | 516 | ++count; |
448 | } | 517 | } |
449 | return count; | 518 | return count; |
519 | |||
520 | out_unregister: | ||
521 | scsi_unregister(instance); | ||
522 | out_release: | ||
523 | #ifndef SCSI_G_NCR5380_MEM | ||
524 | release_region(overrides[current_override].NCR5380_map_name, region_size); | ||
525 | #else | ||
526 | iounmap(iomem); | ||
527 | release_mem_region(base, NCR5380_region_size); | ||
528 | #endif | ||
529 | return count; | ||
450 | } | 530 | } |
451 | 531 | ||
452 | /** | 532 | /** |
@@ -460,21 +540,15 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt) | |||
460 | 540 | ||
461 | static int generic_NCR5380_release_resources(struct Scsi_Host *instance) | 541 | static int generic_NCR5380_release_resources(struct Scsi_Host *instance) |
462 | { | 542 | { |
463 | NCR5380_local_declare(); | ||
464 | NCR5380_setup(instance); | ||
465 | |||
466 | if (instance->irq != NO_IRQ) | 543 | if (instance->irq != NO_IRQ) |
467 | free_irq(instance->irq, instance); | 544 | free_irq(instance->irq, instance); |
468 | NCR5380_exit(instance); | 545 | NCR5380_exit(instance); |
469 | |||
470 | #ifndef SCSI_G_NCR5380_MEM | 546 | #ifndef SCSI_G_NCR5380_MEM |
471 | release_region(instance->NCR5380_instance_name, instance->n_io_port); | 547 | release_region(instance->io_port, instance->n_io_port); |
472 | #else | 548 | #else |
473 | iounmap(((struct NCR5380_hostdata *)instance->hostdata)->iomem); | 549 | iounmap(((struct NCR5380_hostdata *)instance->hostdata)->iomem); |
474 | release_mem_region(instance->NCR5380_instance_name, NCR5380_region_size); | 550 | release_mem_region(instance->base, NCR5380_region_size); |
475 | #endif | 551 | #endif |
476 | |||
477 | |||
478 | return 0; | 552 | return 0; |
479 | } | 553 | } |
480 | 554 | ||
@@ -507,7 +581,7 @@ generic_NCR5380_biosparam(struct scsi_device *sdev, struct block_device *bdev, | |||
507 | } | 581 | } |
508 | #endif | 582 | #endif |
509 | 583 | ||
510 | #ifdef NCR53C400_PSEUDO_DMA | 584 | #ifdef PSEUDO_DMA |
511 | 585 | ||
512 | /** | 586 | /** |
513 | * NCR5380_pread - pseudo DMA read | 587 | * NCR5380_pread - pseudo DMA read |
@@ -521,75 +595,68 @@ generic_NCR5380_biosparam(struct scsi_device *sdev, struct block_device *bdev, | |||
521 | 595 | ||
522 | static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst, int len) | 596 | static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst, int len) |
523 | { | 597 | { |
598 | struct NCR5380_hostdata *hostdata = shost_priv(instance); | ||
524 | int blocks = len / 128; | 599 | int blocks = len / 128; |
525 | int start = 0; | 600 | int start = 0; |
526 | int bl; | ||
527 | |||
528 | NCR5380_local_declare(); | ||
529 | NCR5380_setup(instance); | ||
530 | 601 | ||
531 | NCR5380_write(C400_CONTROL_STATUS_REG, CSR_BASE | CSR_TRANS_DIR); | 602 | NCR5380_write(hostdata->c400_ctl_status, CSR_BASE | CSR_TRANS_DIR); |
532 | NCR5380_write(C400_BLOCK_COUNTER_REG, blocks); | 603 | NCR5380_write(hostdata->c400_blk_cnt, blocks); |
533 | while (1) { | 604 | while (1) { |
534 | if ((bl = NCR5380_read(C400_BLOCK_COUNTER_REG)) == 0) { | 605 | if (NCR5380_read(hostdata->c400_blk_cnt) == 0) |
535 | break; | 606 | break; |
536 | } | 607 | if (NCR5380_read(hostdata->c400_ctl_status) & CSR_GATED_53C80_IRQ) { |
537 | if (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_GATED_53C80_IRQ) { | ||
538 | printk(KERN_ERR "53C400r: Got 53C80_IRQ start=%d, blocks=%d\n", start, blocks); | 608 | printk(KERN_ERR "53C400r: Got 53C80_IRQ start=%d, blocks=%d\n", start, blocks); |
539 | return -1; | 609 | return -1; |
540 | } | 610 | } |
541 | while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_HOST_BUF_NOT_RDY); | 611 | while (NCR5380_read(hostdata->c400_ctl_status) & CSR_HOST_BUF_NOT_RDY) |
612 | ; /* FIXME - no timeout */ | ||
542 | 613 | ||
543 | #ifndef SCSI_G_NCR5380_MEM | 614 | #ifndef SCSI_G_NCR5380_MEM |
544 | { | 615 | if (hostdata->io_width == 2) |
545 | int i; | 616 | insw(instance->io_port + hostdata->c400_host_buf, |
546 | for (i = 0; i < 128; i++) | 617 | dst + start, 64); |
547 | dst[start + i] = NCR5380_read(C400_HOST_BUFFER); | 618 | else |
548 | } | 619 | insb(instance->io_port + hostdata->c400_host_buf, |
620 | dst + start, 128); | ||
549 | #else | 621 | #else |
550 | /* implies SCSI_G_NCR5380_MEM */ | 622 | /* implies SCSI_G_NCR5380_MEM */ |
551 | memcpy_fromio(dst + start, iomem + NCR53C400_host_buffer, 128); | 623 | memcpy_fromio(dst + start, |
624 | hostdata->iomem + NCR53C400_host_buffer, 128); | ||
552 | #endif | 625 | #endif |
553 | start += 128; | 626 | start += 128; |
554 | blocks--; | 627 | blocks--; |
555 | } | 628 | } |
556 | 629 | ||
557 | if (blocks) { | 630 | if (blocks) { |
558 | while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_HOST_BUF_NOT_RDY) | 631 | while (NCR5380_read(hostdata->c400_ctl_status) & CSR_HOST_BUF_NOT_RDY) |
559 | { | 632 | ; /* FIXME - no timeout */ |
560 | // FIXME - no timeout | ||
561 | } | ||
562 | 633 | ||
563 | #ifndef SCSI_G_NCR5380_MEM | 634 | #ifndef SCSI_G_NCR5380_MEM |
564 | { | 635 | if (hostdata->io_width == 2) |
565 | int i; | 636 | insw(instance->io_port + hostdata->c400_host_buf, |
566 | for (i = 0; i < 128; i++) | 637 | dst + start, 64); |
567 | dst[start + i] = NCR5380_read(C400_HOST_BUFFER); | 638 | else |
568 | } | 639 | insb(instance->io_port + hostdata->c400_host_buf, |
640 | dst + start, 128); | ||
569 | #else | 641 | #else |
570 | /* implies SCSI_G_NCR5380_MEM */ | 642 | /* implies SCSI_G_NCR5380_MEM */ |
571 | memcpy_fromio(dst + start, iomem + NCR53C400_host_buffer, 128); | 643 | memcpy_fromio(dst + start, |
644 | hostdata->iomem + NCR53C400_host_buffer, 128); | ||
572 | #endif | 645 | #endif |
573 | start += 128; | 646 | start += 128; |
574 | blocks--; | 647 | blocks--; |
575 | } | 648 | } |
576 | 649 | ||
577 | if (!(NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_GATED_53C80_IRQ)) | 650 | if (!(NCR5380_read(hostdata->c400_ctl_status) & CSR_GATED_53C80_IRQ)) |
578 | printk("53C400r: no 53C80 gated irq after transfer"); | 651 | printk("53C400r: no 53C80 gated irq after transfer"); |
579 | 652 | ||
580 | #if 0 | 653 | /* wait for 53C80 registers to be available */ |
581 | /* | 654 | while (!(NCR5380_read(hostdata->c400_ctl_status) & CSR_53C80_REG)) |
582 | * DON'T DO THIS - THEY NEVER ARRIVE! | ||
583 | */ | ||
584 | printk("53C400r: Waiting for 53C80 registers\n"); | ||
585 | while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_53C80_REG) | ||
586 | ; | 655 | ; |
587 | #endif | 656 | |
588 | if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_END_DMA_TRANSFER)) | 657 | if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_END_DMA_TRANSFER)) |
589 | printk(KERN_ERR "53C400r: no end dma signal\n"); | 658 | printk(KERN_ERR "53C400r: no end dma signal\n"); |
590 | 659 | ||
591 | NCR5380_write(MODE_REG, MR_BASE); | ||
592 | NCR5380_read(RESET_PARITY_INTERRUPT_REG); | ||
593 | return 0; | 660 | return 0; |
594 | } | 661 | } |
595 | 662 | ||
@@ -605,89 +672,91 @@ static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst, | |||
605 | 672 | ||
606 | static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src, int len) | 673 | static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src, int len) |
607 | { | 674 | { |
675 | struct NCR5380_hostdata *hostdata = shost_priv(instance); | ||
608 | int blocks = len / 128; | 676 | int blocks = len / 128; |
609 | int start = 0; | 677 | int start = 0; |
610 | int bl; | ||
611 | int i; | ||
612 | 678 | ||
613 | NCR5380_local_declare(); | 679 | NCR5380_write(hostdata->c400_ctl_status, CSR_BASE); |
614 | NCR5380_setup(instance); | 680 | NCR5380_write(hostdata->c400_blk_cnt, blocks); |
615 | |||
616 | NCR5380_write(C400_CONTROL_STATUS_REG, CSR_BASE); | ||
617 | NCR5380_write(C400_BLOCK_COUNTER_REG, blocks); | ||
618 | while (1) { | 681 | while (1) { |
619 | if (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_GATED_53C80_IRQ) { | 682 | if (NCR5380_read(hostdata->c400_ctl_status) & CSR_GATED_53C80_IRQ) { |
620 | printk(KERN_ERR "53C400w: Got 53C80_IRQ start=%d, blocks=%d\n", start, blocks); | 683 | printk(KERN_ERR "53C400w: Got 53C80_IRQ start=%d, blocks=%d\n", start, blocks); |
621 | return -1; | 684 | return -1; |
622 | } | 685 | } |
623 | 686 | ||
624 | if ((bl = NCR5380_read(C400_BLOCK_COUNTER_REG)) == 0) { | 687 | if (NCR5380_read(hostdata->c400_blk_cnt) == 0) |
625 | break; | 688 | break; |
626 | } | 689 | while (NCR5380_read(hostdata->c400_ctl_status) & CSR_HOST_BUF_NOT_RDY) |
627 | while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_HOST_BUF_NOT_RDY) | ||
628 | ; // FIXME - timeout | 690 | ; // FIXME - timeout |
629 | #ifndef SCSI_G_NCR5380_MEM | 691 | #ifndef SCSI_G_NCR5380_MEM |
630 | { | 692 | if (hostdata->io_width == 2) |
631 | for (i = 0; i < 128; i++) | 693 | outsw(instance->io_port + hostdata->c400_host_buf, |
632 | NCR5380_write(C400_HOST_BUFFER, src[start + i]); | 694 | src + start, 64); |
633 | } | 695 | else |
696 | outsb(instance->io_port + hostdata->c400_host_buf, | ||
697 | src + start, 128); | ||
634 | #else | 698 | #else |
635 | /* implies SCSI_G_NCR5380_MEM */ | 699 | /* implies SCSI_G_NCR5380_MEM */ |
636 | memcpy_toio(iomem + NCR53C400_host_buffer, src + start, 128); | 700 | memcpy_toio(hostdata->iomem + NCR53C400_host_buffer, |
701 | src + start, 128); | ||
637 | #endif | 702 | #endif |
638 | start += 128; | 703 | start += 128; |
639 | blocks--; | 704 | blocks--; |
640 | } | 705 | } |
641 | if (blocks) { | 706 | if (blocks) { |
642 | while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_HOST_BUF_NOT_RDY) | 707 | while (NCR5380_read(hostdata->c400_ctl_status) & CSR_HOST_BUF_NOT_RDY) |
643 | ; // FIXME - no timeout | 708 | ; // FIXME - no timeout |
644 | 709 | ||
645 | #ifndef SCSI_G_NCR5380_MEM | 710 | #ifndef SCSI_G_NCR5380_MEM |
646 | { | 711 | if (hostdata->io_width == 2) |
647 | for (i = 0; i < 128; i++) | 712 | outsw(instance->io_port + hostdata->c400_host_buf, |
648 | NCR5380_write(C400_HOST_BUFFER, src[start + i]); | 713 | src + start, 64); |
649 | } | 714 | else |
715 | outsb(instance->io_port + hostdata->c400_host_buf, | ||
716 | src + start, 128); | ||
650 | #else | 717 | #else |
651 | /* implies SCSI_G_NCR5380_MEM */ | 718 | /* implies SCSI_G_NCR5380_MEM */ |
652 | memcpy_toio(iomem + NCR53C400_host_buffer, src + start, 128); | 719 | memcpy_toio(hostdata->iomem + NCR53C400_host_buffer, |
720 | src + start, 128); | ||
653 | #endif | 721 | #endif |
654 | start += 128; | 722 | start += 128; |
655 | blocks--; | 723 | blocks--; |
656 | } | 724 | } |
657 | 725 | ||
658 | #if 0 | 726 | /* wait for 53C80 registers to be available */ |
659 | printk("53C400w: waiting for registers to be available\n"); | 727 | while (!(NCR5380_read(hostdata->c400_ctl_status) & CSR_53C80_REG)) { |
660 | THEY NEVER DO ! while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_53C80_REG); | 728 | udelay(4); /* DTC436 chip hangs without this */ |
661 | printk("53C400w: Got em\n"); | 729 | /* FIXME - no timeout */ |
662 | #endif | 730 | } |
663 | |||
664 | /* Let's wait for this instead - could be ugly */ | ||
665 | /* All documentation says to check for this. Maybe my hardware is too | ||
666 | * fast. Waiting for it seems to work fine! KLL | ||
667 | */ | ||
668 | while (!(i = NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_GATED_53C80_IRQ)) | ||
669 | ; // FIXME - no timeout | ||
670 | |||
671 | /* | ||
672 | * I know. i is certainly != 0 here but the loop is new. See previous | ||
673 | * comment. | ||
674 | */ | ||
675 | if (i) { | ||
676 | if (!((i = NCR5380_read(BUS_AND_STATUS_REG)) & BASR_END_DMA_TRANSFER)) | ||
677 | printk(KERN_ERR "53C400w: No END OF DMA bit - WHOOPS! BASR=%0x\n", i); | ||
678 | } else | ||
679 | printk(KERN_ERR "53C400w: no 53C80 gated irq after transfer (last block)\n"); | ||
680 | 731 | ||
681 | #if 0 | ||
682 | if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_END_DMA_TRANSFER)) { | 732 | if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_END_DMA_TRANSFER)) { |
683 | printk(KERN_ERR "53C400w: no end dma signal\n"); | 733 | printk(KERN_ERR "53C400w: no end dma signal\n"); |
684 | } | 734 | } |
685 | #endif | 735 | |
686 | while (!(NCR5380_read(TARGET_COMMAND_REG) & TCR_LAST_BYTE_SENT)) | 736 | while (!(NCR5380_read(TARGET_COMMAND_REG) & TCR_LAST_BYTE_SENT)) |
687 | ; // TIMEOUT | 737 | ; // TIMEOUT |
688 | return 0; | 738 | return 0; |
689 | } | 739 | } |
690 | #endif /* PSEUDO_DMA */ | 740 | |
741 | static int generic_NCR5380_dma_xfer_len(struct scsi_cmnd *cmd) | ||
742 | { | ||
743 | int transfersize = cmd->transfersize; | ||
744 | |||
745 | /* Limit transfers to 32K, for xx400 & xx406 | ||
746 | * pseudoDMA that transfers in 128 bytes blocks. | ||
747 | */ | ||
748 | if (transfersize > 32 * 1024 && cmd->SCp.this_residual && | ||
749 | !(cmd->SCp.this_residual % transfersize)) | ||
750 | transfersize = 32 * 1024; | ||
751 | |||
752 | /* 53C400 datasheet: non-modulo-128-byte transfers should use PIO */ | ||
753 | if (transfersize % 128) | ||
754 | transfersize = 0; | ||
755 | |||
756 | return transfersize; | ||
757 | } | ||
758 | |||
759 | #endif /* PSEUDO_DMA */ | ||
691 | 760 | ||
692 | /* | 761 | /* |
693 | * Include the NCR5380 core code that we build our driver around | 762 | * Include the NCR5380 core code that we build our driver around |
@@ -696,22 +765,24 @@ static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src, | |||
696 | #include "NCR5380.c" | 765 | #include "NCR5380.c" |
697 | 766 | ||
698 | static struct scsi_host_template driver_template = { | 767 | static struct scsi_host_template driver_template = { |
699 | .show_info = generic_NCR5380_show_info, | 768 | .proc_name = DRV_MODULE_NAME, |
700 | .name = "Generic NCR5380/NCR53C400 SCSI", | 769 | .name = "Generic NCR5380/NCR53C400 SCSI", |
701 | .detect = generic_NCR5380_detect, | 770 | .detect = generic_NCR5380_detect, |
702 | .release = generic_NCR5380_release_resources, | 771 | .release = generic_NCR5380_release_resources, |
703 | .info = generic_NCR5380_info, | 772 | .info = generic_NCR5380_info, |
704 | .queuecommand = generic_NCR5380_queue_command, | 773 | .queuecommand = generic_NCR5380_queue_command, |
705 | .eh_abort_handler = generic_NCR5380_abort, | 774 | .eh_abort_handler = generic_NCR5380_abort, |
706 | .eh_bus_reset_handler = generic_NCR5380_bus_reset, | 775 | .eh_bus_reset_handler = generic_NCR5380_bus_reset, |
707 | .bios_param = NCR5380_BIOSPARAM, | 776 | .bios_param = NCR5380_BIOSPARAM, |
708 | .can_queue = CAN_QUEUE, | 777 | .can_queue = 16, |
709 | .this_id = 7, | 778 | .this_id = 7, |
710 | .sg_tablesize = SG_ALL, | 779 | .sg_tablesize = SG_ALL, |
711 | .cmd_per_lun = CMD_PER_LUN, | 780 | .cmd_per_lun = 2, |
712 | .use_clustering = DISABLE_CLUSTERING, | 781 | .use_clustering = DISABLE_CLUSTERING, |
782 | .cmd_size = NCR5380_CMD_SIZE, | ||
783 | .max_sectors = 128, | ||
713 | }; | 784 | }; |
714 | #include <linux/module.h> | 785 | |
715 | #include "scsi_module.c" | 786 | #include "scsi_module.c" |
716 | 787 | ||
717 | module_param(ncr_irq, int, 0); | 788 | module_param(ncr_irq, int, 0); |
@@ -721,6 +792,7 @@ module_param(ncr_5380, int, 0); | |||
721 | module_param(ncr_53c400, int, 0); | 792 | module_param(ncr_53c400, int, 0); |
722 | module_param(ncr_53c400a, int, 0); | 793 | module_param(ncr_53c400a, int, 0); |
723 | module_param(dtc_3181e, int, 0); | 794 | module_param(dtc_3181e, int, 0); |
795 | module_param(hp_c2502, int, 0); | ||
724 | MODULE_LICENSE("GPL"); | 796 | MODULE_LICENSE("GPL"); |
725 | 797 | ||
726 | #if !defined(SCSI_G_NCR5380_MEM) && defined(MODULE) | 798 | #if !defined(SCSI_G_NCR5380_MEM) && defined(MODULE) |
diff --git a/drivers/scsi/g_NCR5380.h b/drivers/scsi/g_NCR5380.h index bea1a3b9b862..6f3d2ac4f185 100644 --- a/drivers/scsi/g_NCR5380.h +++ b/drivers/scsi/g_NCR5380.h | |||
@@ -14,81 +14,67 @@ | |||
14 | #ifndef GENERIC_NCR5380_H | 14 | #ifndef GENERIC_NCR5380_H |
15 | #define GENERIC_NCR5380_H | 15 | #define GENERIC_NCR5380_H |
16 | 16 | ||
17 | #ifdef NCR53C400 | 17 | #ifdef CONFIG_SCSI_GENERIC_NCR53C400 |
18 | #define BIOSPARAM | 18 | #define BIOSPARAM |
19 | #define NCR5380_BIOSPARAM generic_NCR5380_biosparam | 19 | #define NCR5380_BIOSPARAM generic_NCR5380_biosparam |
20 | #else | 20 | #else |
21 | #define NCR5380_BIOSPARAM NULL | 21 | #define NCR5380_BIOSPARAM NULL |
22 | #endif | 22 | #endif |
23 | 23 | ||
24 | #ifndef ASM | ||
25 | |||
26 | #ifndef CMD_PER_LUN | ||
27 | #define CMD_PER_LUN 2 | ||
28 | #endif | ||
29 | |||
30 | #ifndef CAN_QUEUE | ||
31 | #define CAN_QUEUE 16 | ||
32 | #endif | ||
33 | |||
34 | #define __STRVAL(x) #x | 24 | #define __STRVAL(x) #x |
35 | #define STRVAL(x) __STRVAL(x) | 25 | #define STRVAL(x) __STRVAL(x) |
36 | 26 | ||
37 | #ifndef SCSI_G_NCR5380_MEM | 27 | #ifndef SCSI_G_NCR5380_MEM |
28 | #define DRV_MODULE_NAME "g_NCR5380" | ||
38 | 29 | ||
39 | #define NCR5380_map_config port | ||
40 | #define NCR5380_map_type int | 30 | #define NCR5380_map_type int |
41 | #define NCR5380_map_name port | 31 | #define NCR5380_map_name port |
42 | #define NCR5380_instance_name io_port | ||
43 | #define NCR53C400_register_offset 0 | ||
44 | #define NCR53C400_address_adjust 8 | ||
45 | 32 | ||
46 | #ifdef NCR53C400 | 33 | #ifdef CONFIG_SCSI_GENERIC_NCR53C400 |
47 | #define NCR5380_region_size 16 | 34 | #define NCR5380_region_size 16 |
48 | #else | 35 | #else |
49 | #define NCR5380_region_size 8 | 36 | #define NCR5380_region_size 8 |
50 | #endif | 37 | #endif |
51 | 38 | ||
52 | #define NCR5380_read(reg) (inb(NCR5380_map_name + (reg))) | 39 | #define NCR5380_read(reg) \ |
53 | #define NCR5380_write(reg, value) (outb((value), (NCR5380_map_name + (reg)))) | 40 | inb(instance->io_port + (reg)) |
41 | #define NCR5380_write(reg, value) \ | ||
42 | outb(value, instance->io_port + (reg)) | ||
54 | 43 | ||
55 | #define NCR5380_implementation_fields \ | 44 | #define NCR5380_implementation_fields \ |
56 | NCR5380_map_type NCR5380_map_name | 45 | int c400_ctl_status; \ |
57 | 46 | int c400_blk_cnt; \ | |
58 | #define NCR5380_local_declare() \ | 47 | int c400_host_buf; \ |
59 | register NCR5380_implementation_fields | 48 | int io_width; |
60 | |||
61 | #define NCR5380_setup(instance) \ | ||
62 | NCR5380_map_name = (NCR5380_map_type)((instance)->NCR5380_instance_name) | ||
63 | 49 | ||
64 | #else | 50 | #else |
65 | /* therefore SCSI_G_NCR5380_MEM */ | 51 | /* therefore SCSI_G_NCR5380_MEM */ |
52 | #define DRV_MODULE_NAME "g_NCR5380_mmio" | ||
66 | 53 | ||
67 | #define NCR5380_map_config memory | ||
68 | #define NCR5380_map_type unsigned long | 54 | #define NCR5380_map_type unsigned long |
69 | #define NCR5380_map_name base | 55 | #define NCR5380_map_name base |
70 | #define NCR5380_instance_name base | ||
71 | #define NCR53C400_register_offset 0x108 | ||
72 | #define NCR53C400_address_adjust 0 | ||
73 | #define NCR53C400_mem_base 0x3880 | 56 | #define NCR53C400_mem_base 0x3880 |
74 | #define NCR53C400_host_buffer 0x3900 | 57 | #define NCR53C400_host_buffer 0x3900 |
75 | #define NCR5380_region_size 0x3a00 | 58 | #define NCR5380_region_size 0x3a00 |
76 | 59 | ||
77 | #define NCR5380_read(reg) readb(iomem + NCR53C400_mem_base + (reg)) | 60 | #define NCR5380_read(reg) \ |
78 | #define NCR5380_write(reg, value) writeb(value, iomem + NCR53C400_mem_base + (reg)) | 61 | readb(((struct NCR5380_hostdata *)shost_priv(instance))->iomem + \ |
62 | NCR53C400_mem_base + (reg)) | ||
63 | #define NCR5380_write(reg, value) \ | ||
64 | writeb(value, ((struct NCR5380_hostdata *)shost_priv(instance))->iomem + \ | ||
65 | NCR53C400_mem_base + (reg)) | ||
79 | 66 | ||
80 | #define NCR5380_implementation_fields \ | 67 | #define NCR5380_implementation_fields \ |
81 | NCR5380_map_type NCR5380_map_name; \ | 68 | void __iomem *iomem; \ |
82 | void __iomem *iomem; | 69 | int c400_ctl_status; \ |
83 | 70 | int c400_blk_cnt; \ | |
84 | #define NCR5380_local_declare() \ | 71 | int c400_host_buf; |
85 | register void __iomem *iomem | ||
86 | |||
87 | #define NCR5380_setup(instance) \ | ||
88 | iomem = (((struct NCR5380_hostdata *)(instance)->hostdata)->iomem) | ||
89 | 72 | ||
90 | #endif | 73 | #endif |
91 | 74 | ||
75 | #define NCR5380_dma_xfer_len(instance, cmd, phase) \ | ||
76 | generic_NCR5380_dma_xfer_len(cmd) | ||
77 | |||
92 | #define NCR5380_intr generic_NCR5380_intr | 78 | #define NCR5380_intr generic_NCR5380_intr |
93 | #define NCR5380_queue_command generic_NCR5380_queue_command | 79 | #define NCR5380_queue_command generic_NCR5380_queue_command |
94 | #define NCR5380_abort generic_NCR5380_abort | 80 | #define NCR5380_abort generic_NCR5380_abort |
@@ -102,7 +88,7 @@ | |||
102 | #define BOARD_NCR53C400 1 | 88 | #define BOARD_NCR53C400 1 |
103 | #define BOARD_NCR53C400A 2 | 89 | #define BOARD_NCR53C400A 2 |
104 | #define BOARD_DTC3181E 3 | 90 | #define BOARD_DTC3181E 3 |
91 | #define BOARD_HP_C2502 4 | ||
105 | 92 | ||
106 | #endif /* ndef ASM */ | ||
107 | #endif /* GENERIC_NCR5380_H */ | 93 | #endif /* GENERIC_NCR5380_H */ |
108 | 94 | ||
diff --git a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c index d54381149c0d..057fdeb720ac 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c | |||
@@ -247,41 +247,36 @@ | |||
247 | /* ITCT header */ | 247 | /* ITCT header */ |
248 | /* qw0 */ | 248 | /* qw0 */ |
249 | #define ITCT_HDR_DEV_TYPE_OFF 0 | 249 | #define ITCT_HDR_DEV_TYPE_OFF 0 |
250 | #define ITCT_HDR_DEV_TYPE_MSK (0x3 << ITCT_HDR_DEV_TYPE_OFF) | 250 | #define ITCT_HDR_DEV_TYPE_MSK (0x3ULL << ITCT_HDR_DEV_TYPE_OFF) |
251 | #define ITCT_HDR_VALID_OFF 2 | 251 | #define ITCT_HDR_VALID_OFF 2 |
252 | #define ITCT_HDR_VALID_MSK (0x1 << ITCT_HDR_VALID_OFF) | 252 | #define ITCT_HDR_VALID_MSK (0x1ULL << ITCT_HDR_VALID_OFF) |
253 | #define ITCT_HDR_BREAK_REPLY_ENA_OFF 3 | ||
254 | #define ITCT_HDR_BREAK_REPLY_ENA_MSK (0x1 << ITCT_HDR_BREAK_REPLY_ENA_OFF) | ||
255 | #define ITCT_HDR_AWT_CONTROL_OFF 4 | 253 | #define ITCT_HDR_AWT_CONTROL_OFF 4 |
256 | #define ITCT_HDR_AWT_CONTROL_MSK (0x1 << ITCT_HDR_AWT_CONTROL_OFF) | 254 | #define ITCT_HDR_AWT_CONTROL_MSK (0x1ULL << ITCT_HDR_AWT_CONTROL_OFF) |
257 | #define ITCT_HDR_MAX_CONN_RATE_OFF 5 | 255 | #define ITCT_HDR_MAX_CONN_RATE_OFF 5 |
258 | #define ITCT_HDR_MAX_CONN_RATE_MSK (0xf << ITCT_HDR_MAX_CONN_RATE_OFF) | 256 | #define ITCT_HDR_MAX_CONN_RATE_MSK (0xfULL << ITCT_HDR_MAX_CONN_RATE_OFF) |
259 | #define ITCT_HDR_VALID_LINK_NUM_OFF 9 | 257 | #define ITCT_HDR_VALID_LINK_NUM_OFF 9 |
260 | #define ITCT_HDR_VALID_LINK_NUM_MSK (0xf << ITCT_HDR_VALID_LINK_NUM_OFF) | 258 | #define ITCT_HDR_VALID_LINK_NUM_MSK (0xfULL << ITCT_HDR_VALID_LINK_NUM_OFF) |
261 | #define ITCT_HDR_PORT_ID_OFF 13 | 259 | #define ITCT_HDR_PORT_ID_OFF 13 |
262 | #define ITCT_HDR_PORT_ID_MSK (0x7 << ITCT_HDR_PORT_ID_OFF) | 260 | #define ITCT_HDR_PORT_ID_MSK (0x7ULL << ITCT_HDR_PORT_ID_OFF) |
263 | #define ITCT_HDR_SMP_TIMEOUT_OFF 16 | 261 | #define ITCT_HDR_SMP_TIMEOUT_OFF 16 |
264 | #define ITCT_HDR_SMP_TIMEOUT_MSK (0xffff << ITCT_HDR_SMP_TIMEOUT_OFF) | 262 | #define ITCT_HDR_SMP_TIMEOUT_MSK (0xffffULL << ITCT_HDR_SMP_TIMEOUT_OFF) |
265 | #define ITCT_HDR_MAX_BURST_BYTES_OFF 16 | ||
266 | #define ITCT_HDR_MAX_BURST_BYTES_MSK (0xffffffff << \ | ||
267 | ITCT_MAX_BURST_BYTES_OFF) | ||
268 | /* qw1 */ | 263 | /* qw1 */ |
269 | #define ITCT_HDR_MAX_SAS_ADDR_OFF 0 | 264 | #define ITCT_HDR_MAX_SAS_ADDR_OFF 0 |
270 | #define ITCT_HDR_MAX_SAS_ADDR_MSK (0xffffffffffffffff << \ | 265 | #define ITCT_HDR_MAX_SAS_ADDR_MSK (0xffffffffffffffff << \ |
271 | ITCT_HDR_MAX_SAS_ADDR_OFF) | 266 | ITCT_HDR_MAX_SAS_ADDR_OFF) |
272 | /* qw2 */ | 267 | /* qw2 */ |
273 | #define ITCT_HDR_IT_NEXUS_LOSS_TL_OFF 0 | 268 | #define ITCT_HDR_IT_NEXUS_LOSS_TL_OFF 0 |
274 | #define ITCT_HDR_IT_NEXUS_LOSS_TL_MSK (0xffff << \ | 269 | #define ITCT_HDR_IT_NEXUS_LOSS_TL_MSK (0xffffULL << \ |
275 | ITCT_HDR_IT_NEXUS_LOSS_TL_OFF) | 270 | ITCT_HDR_IT_NEXUS_LOSS_TL_OFF) |
276 | #define ITCT_HDR_BUS_INACTIVE_TL_OFF 16 | 271 | #define ITCT_HDR_BUS_INACTIVE_TL_OFF 16 |
277 | #define ITCT_HDR_BUS_INACTIVE_TL_MSK (0xffff << \ | 272 | #define ITCT_HDR_BUS_INACTIVE_TL_MSK (0xffffULL << \ |
278 | ITCT_HDR_BUS_INACTIVE_TL_OFF) | 273 | ITCT_HDR_BUS_INACTIVE_TL_OFF) |
279 | #define ITCT_HDR_MAX_CONN_TL_OFF 32 | 274 | #define ITCT_HDR_MAX_CONN_TL_OFF 32 |
280 | #define ITCT_HDR_MAX_CONN_TL_MSK (0xffff << \ | 275 | #define ITCT_HDR_MAX_CONN_TL_MSK (0xffffULL << \ |
281 | ITCT_HDR_MAX_CONN_TL_OFF) | 276 | ITCT_HDR_MAX_CONN_TL_OFF) |
282 | #define ITCT_HDR_REJ_OPEN_TL_OFF 48 | 277 | #define ITCT_HDR_REJ_OPEN_TL_OFF 48 |
283 | #define ITCT_HDR_REJ_OPEN_TL_MSK (0xffff << \ | 278 | #define ITCT_HDR_REJ_OPEN_TL_MSK (0xffffULL << \ |
284 | ITCT_REJ_OPEN_TL_OFF) | 279 | ITCT_HDR_REJ_OPEN_TL_OFF) |
285 | 280 | ||
286 | /* Err record header */ | 281 | /* Err record header */ |
287 | #define ERR_HDR_DMA_TX_ERR_TYPE_OFF 0 | 282 | #define ERR_HDR_DMA_TX_ERR_TYPE_OFF 0 |
@@ -533,10 +528,10 @@ static void setup_itct_v1_hw(struct hisi_hba *hisi_hba, | |||
533 | itct->sas_addr = __swab64(itct->sas_addr); | 528 | itct->sas_addr = __swab64(itct->sas_addr); |
534 | 529 | ||
535 | /* qw2 */ | 530 | /* qw2 */ |
536 | itct->qw2 = cpu_to_le64((500 < ITCT_HDR_IT_NEXUS_LOSS_TL_OFF) | | 531 | itct->qw2 = cpu_to_le64((500ULL << ITCT_HDR_IT_NEXUS_LOSS_TL_OFF) | |
537 | (0xff00 < ITCT_HDR_BUS_INACTIVE_TL_OFF) | | 532 | (0xff00ULL << ITCT_HDR_BUS_INACTIVE_TL_OFF) | |
538 | (0xff00 < ITCT_HDR_MAX_CONN_TL_OFF) | | 533 | (0xff00ULL << ITCT_HDR_MAX_CONN_TL_OFF) | |
539 | (0xff00 < ITCT_HDR_REJ_OPEN_TL_OFF)); | 534 | (0xff00ULL << ITCT_HDR_REJ_OPEN_TL_OFF)); |
540 | } | 535 | } |
541 | 536 | ||
542 | static void free_device_v1_hw(struct hisi_hba *hisi_hba, | 537 | static void free_device_v1_hw(struct hisi_hba *hisi_hba, |
@@ -544,7 +539,8 @@ static void free_device_v1_hw(struct hisi_hba *hisi_hba, | |||
544 | { | 539 | { |
545 | u64 dev_id = sas_dev->device_id; | 540 | u64 dev_id = sas_dev->device_id; |
546 | struct hisi_sas_itct *itct = &hisi_hba->itct[dev_id]; | 541 | struct hisi_sas_itct *itct = &hisi_hba->itct[dev_id]; |
547 | u32 qw0, reg_val = hisi_sas_read32(hisi_hba, CFG_AGING_TIME); | 542 | u64 qw0; |
543 | u32 reg_val = hisi_sas_read32(hisi_hba, CFG_AGING_TIME); | ||
548 | 544 | ||
549 | reg_val |= CFG_AGING_TIME_ITCT_REL_MSK; | 545 | reg_val |= CFG_AGING_TIME_ITCT_REL_MSK; |
550 | hisi_sas_write32(hisi_hba, CFG_AGING_TIME, reg_val); | 546 | hisi_sas_write32(hisi_hba, CFG_AGING_TIME, reg_val); |
diff --git a/drivers/scsi/imm.c b/drivers/scsi/imm.c index 4e1a632ccf16..f8b88fa78e62 100644 --- a/drivers/scsi/imm.c +++ b/drivers/scsi/imm.c | |||
@@ -43,6 +43,7 @@ typedef struct { | |||
43 | unsigned dp:1; /* Data phase present */ | 43 | unsigned dp:1; /* Data phase present */ |
44 | unsigned rd:1; /* Read data in data phase */ | 44 | unsigned rd:1; /* Read data in data phase */ |
45 | unsigned wanted:1; /* Parport sharing busy flag */ | 45 | unsigned wanted:1; /* Parport sharing busy flag */ |
46 | unsigned int dev_no; /* Device number */ | ||
46 | wait_queue_head_t *waiting; | 47 | wait_queue_head_t *waiting; |
47 | struct Scsi_Host *host; | 48 | struct Scsi_Host *host; |
48 | struct list_head list; | 49 | struct list_head list; |
@@ -1120,15 +1121,40 @@ static struct scsi_host_template imm_template = { | |||
1120 | 1121 | ||
1121 | static LIST_HEAD(imm_hosts); | 1122 | static LIST_HEAD(imm_hosts); |
1122 | 1123 | ||
1124 | /* | ||
1125 | * Finds the first available device number that can be alloted to the | ||
1126 | * new imm device and returns the address of the previous node so that | ||
1127 | * we can add to the tail and have a list in the ascending order. | ||
1128 | */ | ||
1129 | |||
1130 | static inline imm_struct *find_parent(void) | ||
1131 | { | ||
1132 | imm_struct *dev, *par = NULL; | ||
1133 | unsigned int cnt = 0; | ||
1134 | |||
1135 | if (list_empty(&imm_hosts)) | ||
1136 | return NULL; | ||
1137 | |||
1138 | list_for_each_entry(dev, &imm_hosts, list) { | ||
1139 | if (dev->dev_no != cnt) | ||
1140 | return par; | ||
1141 | cnt++; | ||
1142 | par = dev; | ||
1143 | } | ||
1144 | |||
1145 | return par; | ||
1146 | } | ||
1147 | |||
1123 | static int __imm_attach(struct parport *pb) | 1148 | static int __imm_attach(struct parport *pb) |
1124 | { | 1149 | { |
1125 | struct Scsi_Host *host; | 1150 | struct Scsi_Host *host; |
1126 | imm_struct *dev; | 1151 | imm_struct *dev, *temp; |
1127 | DECLARE_WAIT_QUEUE_HEAD_ONSTACK(waiting); | 1152 | DECLARE_WAIT_QUEUE_HEAD_ONSTACK(waiting); |
1128 | DEFINE_WAIT(wait); | 1153 | DEFINE_WAIT(wait); |
1129 | int ports; | 1154 | int ports; |
1130 | int modes, ppb; | 1155 | int modes, ppb; |
1131 | int err = -ENOMEM; | 1156 | int err = -ENOMEM; |
1157 | struct pardev_cb imm_cb; | ||
1132 | 1158 | ||
1133 | init_waitqueue_head(&waiting); | 1159 | init_waitqueue_head(&waiting); |
1134 | 1160 | ||
@@ -1141,9 +1167,15 @@ static int __imm_attach(struct parport *pb) | |||
1141 | dev->mode = IMM_AUTODETECT; | 1167 | dev->mode = IMM_AUTODETECT; |
1142 | INIT_LIST_HEAD(&dev->list); | 1168 | INIT_LIST_HEAD(&dev->list); |
1143 | 1169 | ||
1144 | dev->dev = parport_register_device(pb, "imm", NULL, imm_wakeup, | 1170 | temp = find_parent(); |
1145 | NULL, 0, dev); | 1171 | if (temp) |
1172 | dev->dev_no = temp->dev_no + 1; | ||
1173 | |||
1174 | memset(&imm_cb, 0, sizeof(imm_cb)); | ||
1175 | imm_cb.private = dev; | ||
1176 | imm_cb.wakeup = imm_wakeup; | ||
1146 | 1177 | ||
1178 | dev->dev = parport_register_dev_model(pb, "imm", &imm_cb, dev->dev_no); | ||
1147 | if (!dev->dev) | 1179 | if (!dev->dev) |
1148 | goto out; | 1180 | goto out; |
1149 | 1181 | ||
@@ -1207,7 +1239,10 @@ static int __imm_attach(struct parport *pb) | |||
1207 | host->unique_id = pb->number; | 1239 | host->unique_id = pb->number; |
1208 | *(imm_struct **)&host->hostdata = dev; | 1240 | *(imm_struct **)&host->hostdata = dev; |
1209 | dev->host = host; | 1241 | dev->host = host; |
1210 | list_add_tail(&dev->list, &imm_hosts); | 1242 | if (!temp) |
1243 | list_add_tail(&dev->list, &imm_hosts); | ||
1244 | else | ||
1245 | list_add_tail(&dev->list, &temp->list); | ||
1211 | err = scsi_add_host(host, NULL); | 1246 | err = scsi_add_host(host, NULL); |
1212 | if (err) | 1247 | if (err) |
1213 | goto out2; | 1248 | goto out2; |
@@ -1245,9 +1280,10 @@ static void imm_detach(struct parport *pb) | |||
1245 | } | 1280 | } |
1246 | 1281 | ||
1247 | static struct parport_driver imm_driver = { | 1282 | static struct parport_driver imm_driver = { |
1248 | .name = "imm", | 1283 | .name = "imm", |
1249 | .attach = imm_attach, | 1284 | .match_port = imm_attach, |
1250 | .detach = imm_detach, | 1285 | .detach = imm_detach, |
1286 | .devmodel = true, | ||
1251 | }; | 1287 | }; |
1252 | 1288 | ||
1253 | static int __init imm_driver_init(void) | 1289 | static int __init imm_driver_init(void) |
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index 536cd5a80422..1c3759bab80b 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c | |||
@@ -4003,13 +4003,12 @@ static ssize_t ipr_store_update_fw(struct device *dev, | |||
4003 | struct ipr_sglist *sglist; | 4003 | struct ipr_sglist *sglist; |
4004 | char fname[100]; | 4004 | char fname[100]; |
4005 | char *src; | 4005 | char *src; |
4006 | int len, result, dnld_size; | 4006 | int result, dnld_size; |
4007 | 4007 | ||
4008 | if (!capable(CAP_SYS_ADMIN)) | 4008 | if (!capable(CAP_SYS_ADMIN)) |
4009 | return -EACCES; | 4009 | return -EACCES; |
4010 | 4010 | ||
4011 | len = snprintf(fname, 99, "%s", buf); | 4011 | snprintf(fname, sizeof(fname), "%s", buf); |
4012 | fname[len-1] = '\0'; | ||
4013 | 4012 | ||
4014 | if (request_firmware(&fw_entry, fname, &ioa_cfg->pdev->dev)) { | 4013 | if (request_firmware(&fw_entry, fname, &ioa_cfg->pdev->dev)) { |
4015 | dev_err(&ioa_cfg->pdev->dev, "Firmware file %s not found\n", fname); | 4014 | dev_err(&ioa_cfg->pdev->dev, "Firmware file %s not found\n", fname); |
diff --git a/drivers/scsi/mac_scsi.c b/drivers/scsi/mac_scsi.c index d64a769b8155..bb2381314a2b 100644 --- a/drivers/scsi/mac_scsi.c +++ b/drivers/scsi/mac_scsi.c | |||
@@ -12,7 +12,6 @@ | |||
12 | */ | 12 | */ |
13 | 13 | ||
14 | #include <linux/types.h> | 14 | #include <linux/types.h> |
15 | #include <linux/delay.h> | ||
16 | #include <linux/module.h> | 15 | #include <linux/module.h> |
17 | #include <linux/ioport.h> | 16 | #include <linux/ioport.h> |
18 | #include <linux/init.h> | 17 | #include <linux/init.h> |
@@ -32,14 +31,13 @@ | |||
32 | #define PSEUDO_DMA | 31 | #define PSEUDO_DMA |
33 | 32 | ||
34 | #define NCR5380_implementation_fields unsigned char *pdma_base | 33 | #define NCR5380_implementation_fields unsigned char *pdma_base |
35 | #define NCR5380_local_declare() struct Scsi_Host *_instance | ||
36 | #define NCR5380_setup(instance) _instance = instance | ||
37 | 34 | ||
38 | #define NCR5380_read(reg) macscsi_read(_instance, reg) | 35 | #define NCR5380_read(reg) macscsi_read(instance, reg) |
39 | #define NCR5380_write(reg, value) macscsi_write(_instance, reg, value) | 36 | #define NCR5380_write(reg, value) macscsi_write(instance, reg, value) |
40 | 37 | ||
41 | #define NCR5380_pread macscsi_pread | 38 | #define NCR5380_pread macscsi_pread |
42 | #define NCR5380_pwrite macscsi_pwrite | 39 | #define NCR5380_pwrite macscsi_pwrite |
40 | #define NCR5380_dma_xfer_len(instance, cmd, phase) (cmd->transfersize) | ||
43 | 41 | ||
44 | #define NCR5380_intr macscsi_intr | 42 | #define NCR5380_intr macscsi_intr |
45 | #define NCR5380_queue_command macscsi_queue_command | 43 | #define NCR5380_queue_command macscsi_queue_command |
@@ -51,8 +49,6 @@ | |||
51 | 49 | ||
52 | #include "NCR5380.h" | 50 | #include "NCR5380.h" |
53 | 51 | ||
54 | #define RESET_BOOT | ||
55 | |||
56 | static int setup_can_queue = -1; | 52 | static int setup_can_queue = -1; |
57 | module_param(setup_can_queue, int, 0); | 53 | module_param(setup_can_queue, int, 0); |
58 | static int setup_cmd_per_lun = -1; | 54 | static int setup_cmd_per_lun = -1; |
@@ -65,17 +61,8 @@ static int setup_use_tagged_queuing = -1; | |||
65 | module_param(setup_use_tagged_queuing, int, 0); | 61 | module_param(setup_use_tagged_queuing, int, 0); |
66 | static int setup_hostid = -1; | 62 | static int setup_hostid = -1; |
67 | module_param(setup_hostid, int, 0); | 63 | module_param(setup_hostid, int, 0); |
68 | 64 | static int setup_toshiba_delay = -1; | |
69 | /* Time (in jiffies) to wait after a reset; the SCSI standard calls for 250ms, | 65 | module_param(setup_toshiba_delay, int, 0); |
70 | * we usually do 0.5s to be on the safe side. But Toshiba CD-ROMs once more | ||
71 | * need ten times the standard value... */ | ||
72 | #define TOSHIBA_DELAY | ||
73 | |||
74 | #ifdef TOSHIBA_DELAY | ||
75 | #define AFTER_RESET_DELAY (5*HZ/2) | ||
76 | #else | ||
77 | #define AFTER_RESET_DELAY (HZ/2) | ||
78 | #endif | ||
79 | 66 | ||
80 | /* | 67 | /* |
81 | * NCR 5380 register access functions | 68 | * NCR 5380 register access functions |
@@ -94,12 +81,12 @@ static inline void macscsi_write(struct Scsi_Host *instance, int reg, int value) | |||
94 | #ifndef MODULE | 81 | #ifndef MODULE |
95 | static int __init mac_scsi_setup(char *str) | 82 | static int __init mac_scsi_setup(char *str) |
96 | { | 83 | { |
97 | int ints[7]; | 84 | int ints[8]; |
98 | 85 | ||
99 | (void)get_options(str, ARRAY_SIZE(ints), ints); | 86 | (void)get_options(str, ARRAY_SIZE(ints), ints); |
100 | 87 | ||
101 | if (ints[0] < 1 || ints[0] > 6) { | 88 | if (ints[0] < 1) { |
102 | pr_err("Usage: mac5380=<can_queue>[,<cmd_per_lun>[,<sg_tablesize>[,<hostid>[,<use_tags>[,<use_pdma>]]]]]\n"); | 89 | pr_err("Usage: mac5380=<can_queue>[,<cmd_per_lun>[,<sg_tablesize>[,<hostid>[,<use_tags>[,<use_pdma>[,<toshiba_delay>]]]]]]\n"); |
103 | return 0; | 90 | return 0; |
104 | } | 91 | } |
105 | if (ints[0] >= 1) | 92 | if (ints[0] >= 1) |
@@ -114,50 +101,14 @@ static int __init mac_scsi_setup(char *str) | |||
114 | setup_use_tagged_queuing = ints[5]; | 101 | setup_use_tagged_queuing = ints[5]; |
115 | if (ints[0] >= 6) | 102 | if (ints[0] >= 6) |
116 | setup_use_pdma = ints[6]; | 103 | setup_use_pdma = ints[6]; |
104 | if (ints[0] >= 7) | ||
105 | setup_toshiba_delay = ints[7]; | ||
117 | return 1; | 106 | return 1; |
118 | } | 107 | } |
119 | 108 | ||
120 | __setup("mac5380=", mac_scsi_setup); | 109 | __setup("mac5380=", mac_scsi_setup); |
121 | #endif /* !MODULE */ | 110 | #endif /* !MODULE */ |
122 | 111 | ||
123 | #ifdef RESET_BOOT | ||
124 | /* | ||
125 | * Our 'bus reset on boot' function | ||
126 | */ | ||
127 | |||
128 | static void mac_scsi_reset_boot(struct Scsi_Host *instance) | ||
129 | { | ||
130 | unsigned long end; | ||
131 | |||
132 | NCR5380_local_declare(); | ||
133 | NCR5380_setup(instance); | ||
134 | |||
135 | /* | ||
136 | * Do a SCSI reset to clean up the bus during initialization. No messing | ||
137 | * with the queues, interrupts, or locks necessary here. | ||
138 | */ | ||
139 | |||
140 | printk(KERN_INFO "Macintosh SCSI: resetting the SCSI bus..." ); | ||
141 | |||
142 | /* get in phase */ | ||
143 | NCR5380_write( TARGET_COMMAND_REG, | ||
144 | PHASE_SR_TO_TCR( NCR5380_read(STATUS_REG) )); | ||
145 | |||
146 | /* assert RST */ | ||
147 | NCR5380_write( INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_RST ); | ||
148 | /* The min. reset hold time is 25us, so 40us should be enough */ | ||
149 | udelay( 50 ); | ||
150 | /* reset RST and interrupt */ | ||
151 | NCR5380_write( INITIATOR_COMMAND_REG, ICR_BASE ); | ||
152 | NCR5380_read( RESET_PARITY_INTERRUPT_REG ); | ||
153 | |||
154 | for( end = jiffies + AFTER_RESET_DELAY; time_before(jiffies, end); ) | ||
155 | barrier(); | ||
156 | |||
157 | printk(KERN_INFO " done\n" ); | ||
158 | } | ||
159 | #endif | ||
160 | |||
161 | #ifdef PSEUDO_DMA | 112 | #ifdef PSEUDO_DMA |
162 | /* | 113 | /* |
163 | Pseudo-DMA: (Ove Edlund) | 114 | Pseudo-DMA: (Ove Edlund) |
@@ -235,9 +186,6 @@ static int macscsi_pread(struct Scsi_Host *instance, | |||
235 | unsigned char *d; | 186 | unsigned char *d; |
236 | unsigned char *s; | 187 | unsigned char *s; |
237 | 188 | ||
238 | NCR5380_local_declare(); | ||
239 | NCR5380_setup(instance); | ||
240 | |||
241 | s = hostdata->pdma_base + (INPUT_DATA_REG << 4); | 189 | s = hostdata->pdma_base + (INPUT_DATA_REG << 4); |
242 | d = dst; | 190 | d = dst; |
243 | 191 | ||
@@ -329,9 +277,6 @@ static int macscsi_pwrite(struct Scsi_Host *instance, | |||
329 | unsigned char *s; | 277 | unsigned char *s; |
330 | unsigned char *d; | 278 | unsigned char *d; |
331 | 279 | ||
332 | NCR5380_local_declare(); | ||
333 | NCR5380_setup(instance); | ||
334 | |||
335 | s = src; | 280 | s = src; |
336 | d = hostdata->pdma_base + (OUTPUT_DATA_REG << 4); | 281 | d = hostdata->pdma_base + (OUTPUT_DATA_REG << 4); |
337 | 282 | ||
@@ -364,20 +309,22 @@ static int macscsi_pwrite(struct Scsi_Host *instance, | |||
364 | #define PFX DRV_MODULE_NAME ": " | 309 | #define PFX DRV_MODULE_NAME ": " |
365 | 310 | ||
366 | static struct scsi_host_template mac_scsi_template = { | 311 | static struct scsi_host_template mac_scsi_template = { |
367 | .module = THIS_MODULE, | 312 | .module = THIS_MODULE, |
368 | .proc_name = DRV_MODULE_NAME, | 313 | .proc_name = DRV_MODULE_NAME, |
369 | .show_info = macscsi_show_info, | 314 | .show_info = macscsi_show_info, |
370 | .write_info = macscsi_write_info, | 315 | .write_info = macscsi_write_info, |
371 | .name = "Macintosh NCR5380 SCSI", | 316 | .name = "Macintosh NCR5380 SCSI", |
372 | .info = macscsi_info, | 317 | .info = macscsi_info, |
373 | .queuecommand = macscsi_queue_command, | 318 | .queuecommand = macscsi_queue_command, |
374 | .eh_abort_handler = macscsi_abort, | 319 | .eh_abort_handler = macscsi_abort, |
375 | .eh_bus_reset_handler = macscsi_bus_reset, | 320 | .eh_bus_reset_handler = macscsi_bus_reset, |
376 | .can_queue = 16, | 321 | .can_queue = 16, |
377 | .this_id = 7, | 322 | .this_id = 7, |
378 | .sg_tablesize = SG_ALL, | 323 | .sg_tablesize = SG_ALL, |
379 | .cmd_per_lun = 2, | 324 | .cmd_per_lun = 2, |
380 | .use_clustering = DISABLE_CLUSTERING | 325 | .use_clustering = DISABLE_CLUSTERING, |
326 | .cmd_size = NCR5380_CMD_SIZE, | ||
327 | .max_sectors = 128, | ||
381 | }; | 328 | }; |
382 | 329 | ||
383 | static int __init mac_scsi_probe(struct platform_device *pdev) | 330 | static int __init mac_scsi_probe(struct platform_device *pdev) |
@@ -432,15 +379,14 @@ static int __init mac_scsi_probe(struct platform_device *pdev) | |||
432 | } else | 379 | } else |
433 | host_flags |= FLAG_NO_PSEUDO_DMA; | 380 | host_flags |= FLAG_NO_PSEUDO_DMA; |
434 | 381 | ||
435 | #ifdef RESET_BOOT | ||
436 | mac_scsi_reset_boot(instance); | ||
437 | #endif | ||
438 | |||
439 | #ifdef SUPPORT_TAGS | 382 | #ifdef SUPPORT_TAGS |
440 | host_flags |= setup_use_tagged_queuing > 0 ? FLAG_TAGGED_QUEUING : 0; | 383 | host_flags |= setup_use_tagged_queuing > 0 ? FLAG_TAGGED_QUEUING : 0; |
441 | #endif | 384 | #endif |
385 | host_flags |= setup_toshiba_delay > 0 ? FLAG_TOSHIBA_DELAY : 0; | ||
442 | 386 | ||
443 | NCR5380_init(instance, host_flags); | 387 | error = NCR5380_init(instance, host_flags); |
388 | if (error) | ||
389 | goto fail_init; | ||
444 | 390 | ||
445 | if (instance->irq != NO_IRQ) { | 391 | if (instance->irq != NO_IRQ) { |
446 | error = request_irq(instance->irq, macscsi_intr, IRQF_SHARED, | 392 | error = request_irq(instance->irq, macscsi_intr, IRQF_SHARED, |
@@ -449,6 +395,8 @@ static int __init mac_scsi_probe(struct platform_device *pdev) | |||
449 | goto fail_irq; | 395 | goto fail_irq; |
450 | } | 396 | } |
451 | 397 | ||
398 | NCR5380_maybe_reset_bus(instance); | ||
399 | |||
452 | error = scsi_add_host(instance, NULL); | 400 | error = scsi_add_host(instance, NULL); |
453 | if (error) | 401 | if (error) |
454 | goto fail_host; | 402 | goto fail_host; |
@@ -463,6 +411,7 @@ fail_host: | |||
463 | free_irq(instance->irq, instance); | 411 | free_irq(instance->irq, instance); |
464 | fail_irq: | 412 | fail_irq: |
465 | NCR5380_exit(instance); | 413 | NCR5380_exit(instance); |
414 | fail_init: | ||
466 | scsi_host_put(instance); | 415 | scsi_host_put(instance); |
467 | return error; | 416 | return error; |
468 | } | 417 | } |
diff --git a/drivers/scsi/megaraid/megaraid_mm.c b/drivers/scsi/megaraid/megaraid_mm.c index a70692779a16..4cf9ed96414f 100644 --- a/drivers/scsi/megaraid/megaraid_mm.c +++ b/drivers/scsi/megaraid/megaraid_mm.c | |||
@@ -179,8 +179,12 @@ mraid_mm_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) | |||
179 | 179 | ||
180 | /* | 180 | /* |
181 | * The following call will block till a kioc is available | 181 | * The following call will block till a kioc is available |
182 | * or return NULL if the list head is empty for the pointer | ||
183 | * of type mraid_mmapt passed to mraid_mm_alloc_kioc | ||
182 | */ | 184 | */ |
183 | kioc = mraid_mm_alloc_kioc(adp); | 185 | kioc = mraid_mm_alloc_kioc(adp); |
186 | if (!kioc) | ||
187 | return -ENXIO; | ||
184 | 188 | ||
185 | /* | 189 | /* |
186 | * User sent the old mimd_t ioctl packet. Convert it to uioc_t. | 190 | * User sent the old mimd_t ioctl packet. Convert it to uioc_t. |
diff --git a/drivers/scsi/pas16.c b/drivers/scsi/pas16.c index e81eadd08afc..512037e27783 100644 --- a/drivers/scsi/pas16.c +++ b/drivers/scsi/pas16.c | |||
@@ -1,6 +1,4 @@ | |||
1 | #define PSEUDO_DMA | 1 | #define PSEUDO_DMA |
2 | #define UNSAFE /* Not unsafe for PAS16 -- use it */ | ||
3 | #define PDEBUG 0 | ||
4 | 2 | ||
5 | /* | 3 | /* |
6 | * This driver adapted from Drew Eckhardt's Trantor T128 driver | 4 | * This driver adapted from Drew Eckhardt's Trantor T128 driver |
@@ -71,14 +69,10 @@ | |||
71 | 69 | ||
72 | #include <linux/module.h> | 70 | #include <linux/module.h> |
73 | 71 | ||
74 | #include <linux/signal.h> | ||
75 | #include <linux/proc_fs.h> | ||
76 | #include <asm/io.h> | 72 | #include <asm/io.h> |
77 | #include <asm/dma.h> | 73 | #include <asm/dma.h> |
78 | #include <linux/blkdev.h> | 74 | #include <linux/blkdev.h> |
79 | #include <linux/delay.h> | ||
80 | #include <linux/interrupt.h> | 75 | #include <linux/interrupt.h> |
81 | #include <linux/stat.h> | ||
82 | #include <linux/init.h> | 76 | #include <linux/init.h> |
83 | 77 | ||
84 | #include <scsi/scsi_host.h> | 78 | #include <scsi/scsi_host.h> |
@@ -87,8 +81,8 @@ | |||
87 | #include "NCR5380.h" | 81 | #include "NCR5380.h" |
88 | 82 | ||
89 | 83 | ||
90 | static unsigned short pas16_addr = 0; | 84 | static unsigned short pas16_addr; |
91 | static int pas16_irq = 0; | 85 | static int pas16_irq; |
92 | 86 | ||
93 | 87 | ||
94 | static const int scsi_irq_translate[] = | 88 | static const int scsi_irq_translate[] = |
@@ -146,22 +140,6 @@ static const unsigned short pas16_offset[ 8 ] = | |||
146 | * START_DMA_INITIATOR_RECEIVE_REG wo | 140 | * START_DMA_INITIATOR_RECEIVE_REG wo |
147 | */ | 141 | */ |
148 | }; | 142 | }; |
149 | /*----------------------------------------------------------------*/ | ||
150 | /* the following will set the monitor border color (useful to find | ||
151 | where something crashed or gets stuck at */ | ||
152 | /* 1 = blue | ||
153 | 2 = green | ||
154 | 3 = cyan | ||
155 | 4 = red | ||
156 | 5 = magenta | ||
157 | 6 = yellow | ||
158 | 7 = white | ||
159 | */ | ||
160 | #if 1 | ||
161 | #define rtrc(i) {inb(0x3da); outb(0x31, 0x3c0); outb((i), 0x3c0);} | ||
162 | #else | ||
163 | #define rtrc(i) {} | ||
164 | #endif | ||
165 | 143 | ||
166 | 144 | ||
167 | /* | 145 | /* |
@@ -205,7 +183,7 @@ static void __init | |||
205 | outb( 0x01, io_port + P_TIMEOUT_STATUS_REG_OFFSET ); /* Reset TC */ | 183 | outb( 0x01, io_port + P_TIMEOUT_STATUS_REG_OFFSET ); /* Reset TC */ |
206 | outb( 0x01, io_port + WAIT_STATE ); /* 1 Wait state */ | 184 | outb( 0x01, io_port + WAIT_STATE ); /* 1 Wait state */ |
207 | 185 | ||
208 | NCR5380_read( RESET_PARITY_INTERRUPT_REG ); | 186 | inb(io_port + pas16_offset[RESET_PARITY_INTERRUPT_REG]); |
209 | 187 | ||
210 | /* Set the SCSI interrupt pointer without mucking up the sound | 188 | /* Set the SCSI interrupt pointer without mucking up the sound |
211 | * interrupt pointer in the same byte. | 189 | * interrupt pointer in the same byte. |
@@ -280,13 +258,13 @@ static int __init | |||
280 | * put in an additional test to try to weed them out. | 258 | * put in an additional test to try to weed them out. |
281 | */ | 259 | */ |
282 | 260 | ||
283 | outb( 0x01, io_port + WAIT_STATE ); /* 1 Wait state */ | 261 | outb(0x01, io_port + WAIT_STATE); /* 1 Wait state */ |
284 | NCR5380_write( MODE_REG, 0x20 ); /* Is it really SCSI? */ | 262 | outb(0x20, io_port + pas16_offset[MODE_REG]); /* Is it really SCSI? */ |
285 | if( NCR5380_read( MODE_REG ) != 0x20 ) /* Write to a reg. */ | 263 | if (inb(io_port + pas16_offset[MODE_REG]) != 0x20) /* Write to a reg. */ |
286 | return 0; /* and try to read */ | 264 | return 0; /* and try to read */ |
287 | NCR5380_write( MODE_REG, 0x00 ); /* it back. */ | 265 | outb(0x00, io_port + pas16_offset[MODE_REG]); /* it back. */ |
288 | if( NCR5380_read( MODE_REG ) != 0x00 ) | 266 | if (inb(io_port + pas16_offset[MODE_REG]) != 0x00) |
289 | return 0; | 267 | return 0; |
290 | 268 | ||
291 | return 1; | 269 | return 1; |
292 | } | 270 | } |
@@ -305,7 +283,7 @@ static int __init | |||
305 | 283 | ||
306 | static int __init pas16_setup(char *str) | 284 | static int __init pas16_setup(char *str) |
307 | { | 285 | { |
308 | static int commandline_current = 0; | 286 | static int commandline_current; |
309 | int i; | 287 | int i; |
310 | int ints[10]; | 288 | int ints[10]; |
311 | 289 | ||
@@ -344,8 +322,8 @@ __setup("pas16=", pas16_setup); | |||
344 | 322 | ||
345 | static int __init pas16_detect(struct scsi_host_template *tpnt) | 323 | static int __init pas16_detect(struct scsi_host_template *tpnt) |
346 | { | 324 | { |
347 | static int current_override = 0; | 325 | static int current_override; |
348 | static unsigned short current_base = 0; | 326 | static unsigned short current_base; |
349 | struct Scsi_Host *instance; | 327 | struct Scsi_Host *instance; |
350 | unsigned short io_port; | 328 | unsigned short io_port; |
351 | int count; | 329 | int count; |
@@ -377,34 +355,32 @@ static int __init pas16_detect(struct scsi_host_template *tpnt) | |||
377 | } | 355 | } |
378 | else | 356 | else |
379 | for (; !io_port && (current_base < NO_BASES); ++current_base) { | 357 | for (; !io_port && (current_base < NO_BASES); ++current_base) { |
380 | #if (PDEBUG & PDEBUG_INIT) | 358 | dprintk(NDEBUG_INIT, "pas16: probing io_port 0x%04x\n", |
381 | printk("scsi-pas16 : probing io_port %04x\n", (unsigned int) bases[current_base].io_port); | 359 | (unsigned int)bases[current_base].io_port); |
382 | #endif | ||
383 | if ( !bases[current_base].noauto && | 360 | if ( !bases[current_base].noauto && |
384 | pas16_hw_detect( current_base ) ){ | 361 | pas16_hw_detect( current_base ) ){ |
385 | io_port = bases[current_base].io_port; | 362 | io_port = bases[current_base].io_port; |
386 | init_board( io_port, default_irqs[ current_base ], 0 ); | 363 | init_board( io_port, default_irqs[ current_base ], 0 ); |
387 | #if (PDEBUG & PDEBUG_INIT) | 364 | dprintk(NDEBUG_INIT, "pas16: detected board\n"); |
388 | printk("scsi-pas16 : detected board.\n"); | ||
389 | #endif | ||
390 | } | 365 | } |
391 | } | 366 | } |
392 | 367 | ||
393 | 368 | dprintk(NDEBUG_INIT, "pas16: io_port = 0x%04x\n", | |
394 | #if defined(PDEBUG) && (PDEBUG & PDEBUG_INIT) | 369 | (unsigned int)io_port); |
395 | printk("scsi-pas16 : io_port = %04x\n", (unsigned int) io_port); | ||
396 | #endif | ||
397 | 370 | ||
398 | if (!io_port) | 371 | if (!io_port) |
399 | break; | 372 | break; |
400 | 373 | ||
401 | instance = scsi_register (tpnt, sizeof(struct NCR5380_hostdata)); | 374 | instance = scsi_register (tpnt, sizeof(struct NCR5380_hostdata)); |
402 | if(instance == NULL) | 375 | if(instance == NULL) |
403 | break; | 376 | goto out; |
404 | 377 | ||
405 | instance->io_port = io_port; | 378 | instance->io_port = io_port; |
406 | 379 | ||
407 | NCR5380_init(instance, 0); | 380 | if (NCR5380_init(instance, 0)) |
381 | goto out_unregister; | ||
382 | |||
383 | NCR5380_maybe_reset_bus(instance); | ||
408 | 384 | ||
409 | if (overrides[current_override].irq != IRQ_AUTO) | 385 | if (overrides[current_override].irq != IRQ_AUTO) |
410 | instance->irq = overrides[current_override].irq; | 386 | instance->irq = overrides[current_override].irq; |
@@ -431,14 +407,18 @@ static int __init pas16_detect(struct scsi_host_template *tpnt) | |||
431 | outb( (inb(io_port + IO_CONFIG_3) & 0x0f), io_port + IO_CONFIG_3 ); | 407 | outb( (inb(io_port + IO_CONFIG_3) & 0x0f), io_port + IO_CONFIG_3 ); |
432 | } | 408 | } |
433 | 409 | ||
434 | #if defined(PDEBUG) && (PDEBUG & PDEBUG_INIT) | 410 | dprintk(NDEBUG_INIT, "scsi%d : irq = %d\n", |
435 | printk("scsi%d : irq = %d\n", instance->host_no, instance->irq); | 411 | instance->host_no, instance->irq); |
436 | #endif | ||
437 | 412 | ||
438 | ++current_override; | 413 | ++current_override; |
439 | ++count; | 414 | ++count; |
440 | } | 415 | } |
441 | return count; | 416 | return count; |
417 | |||
418 | out_unregister: | ||
419 | scsi_unregister(instance); | ||
420 | out: | ||
421 | return count; | ||
442 | } | 422 | } |
443 | 423 | ||
444 | /* | 424 | /* |
@@ -561,29 +541,29 @@ static int pas16_release(struct Scsi_Host *shost) | |||
561 | if (shost->irq != NO_IRQ) | 541 | if (shost->irq != NO_IRQ) |
562 | free_irq(shost->irq, shost); | 542 | free_irq(shost->irq, shost); |
563 | NCR5380_exit(shost); | 543 | NCR5380_exit(shost); |
564 | if (shost->io_port && shost->n_io_port) | ||
565 | release_region(shost->io_port, shost->n_io_port); | ||
566 | scsi_unregister(shost); | 544 | scsi_unregister(shost); |
567 | return 0; | 545 | return 0; |
568 | } | 546 | } |
569 | 547 | ||
570 | static struct scsi_host_template driver_template = { | 548 | static struct scsi_host_template driver_template = { |
571 | .name = "Pro Audio Spectrum-16 SCSI", | 549 | .name = "Pro Audio Spectrum-16 SCSI", |
572 | .detect = pas16_detect, | 550 | .detect = pas16_detect, |
573 | .release = pas16_release, | 551 | .release = pas16_release, |
574 | .proc_name = "pas16", | 552 | .proc_name = "pas16", |
575 | .show_info = pas16_show_info, | 553 | .show_info = pas16_show_info, |
576 | .write_info = pas16_write_info, | 554 | .write_info = pas16_write_info, |
577 | .info = pas16_info, | 555 | .info = pas16_info, |
578 | .queuecommand = pas16_queue_command, | 556 | .queuecommand = pas16_queue_command, |
579 | .eh_abort_handler = pas16_abort, | 557 | .eh_abort_handler = pas16_abort, |
580 | .eh_bus_reset_handler = pas16_bus_reset, | 558 | .eh_bus_reset_handler = pas16_bus_reset, |
581 | .bios_param = pas16_biosparam, | 559 | .bios_param = pas16_biosparam, |
582 | .can_queue = CAN_QUEUE, | 560 | .can_queue = 32, |
583 | .this_id = 7, | 561 | .this_id = 7, |
584 | .sg_tablesize = SG_ALL, | 562 | .sg_tablesize = SG_ALL, |
585 | .cmd_per_lun = CMD_PER_LUN, | 563 | .cmd_per_lun = 2, |
586 | .use_clustering = DISABLE_CLUSTERING, | 564 | .use_clustering = DISABLE_CLUSTERING, |
565 | .cmd_size = NCR5380_CMD_SIZE, | ||
566 | .max_sectors = 128, | ||
587 | }; | 567 | }; |
588 | #include "scsi_module.c" | 568 | #include "scsi_module.c" |
589 | 569 | ||
diff --git a/drivers/scsi/pas16.h b/drivers/scsi/pas16.h index c6109c80050b..d37527717225 100644 --- a/drivers/scsi/pas16.h +++ b/drivers/scsi/pas16.h | |||
@@ -24,9 +24,6 @@ | |||
24 | #ifndef PAS16_H | 24 | #ifndef PAS16_H |
25 | #define PAS16_H | 25 | #define PAS16_H |
26 | 26 | ||
27 | #define PDEBUG_INIT 0x1 | ||
28 | #define PDEBUG_TRANSFER 0x2 | ||
29 | |||
30 | #define PAS16_DEFAULT_BASE_1 0x388 | 27 | #define PAS16_DEFAULT_BASE_1 0x388 |
31 | #define PAS16_DEFAULT_BASE_2 0x384 | 28 | #define PAS16_DEFAULT_BASE_2 0x384 |
32 | #define PAS16_DEFAULT_BASE_3 0x38c | 29 | #define PAS16_DEFAULT_BASE_3 0x38c |
@@ -98,46 +95,16 @@ | |||
98 | #define OPERATION_MODE_1 0xec03 | 95 | #define OPERATION_MODE_1 0xec03 |
99 | #define IO_CONFIG_3 0xf002 | 96 | #define IO_CONFIG_3 0xf002 |
100 | 97 | ||
98 | #define NCR5380_implementation_fields /* none */ | ||
101 | 99 | ||
102 | #ifndef ASM | 100 | #define PAS16_io_port(reg) (instance->io_port + pas16_offset[(reg)]) |
103 | |||
104 | #ifndef CMD_PER_LUN | ||
105 | #define CMD_PER_LUN 2 | ||
106 | #endif | ||
107 | |||
108 | #ifndef CAN_QUEUE | ||
109 | #define CAN_QUEUE 32 | ||
110 | #endif | ||
111 | |||
112 | #define NCR5380_implementation_fields \ | ||
113 | volatile unsigned short io_port | ||
114 | |||
115 | #define NCR5380_local_declare() \ | ||
116 | volatile unsigned short io_port | ||
117 | 101 | ||
118 | #define NCR5380_setup(instance) \ | ||
119 | io_port = (instance)->io_port | ||
120 | |||
121 | #define PAS16_io_port(reg) ( io_port + pas16_offset[(reg)] ) | ||
122 | |||
123 | #if !(PDEBUG & PDEBUG_TRANSFER) | ||
124 | #define NCR5380_read(reg) ( inb(PAS16_io_port(reg)) ) | 102 | #define NCR5380_read(reg) ( inb(PAS16_io_port(reg)) ) |
125 | #define NCR5380_write(reg, value) ( outb((value),PAS16_io_port(reg)) ) | 103 | #define NCR5380_write(reg, value) ( outb((value),PAS16_io_port(reg)) ) |
126 | #else | ||
127 | #define NCR5380_read(reg) \ | ||
128 | (((unsigned char) printk("scsi%d : read register %d at io_port %04x\n"\ | ||
129 | , instance->hostno, (reg), PAS16_io_port(reg))), inb( PAS16_io_port(reg)) ) | ||
130 | |||
131 | #define NCR5380_write(reg, value) \ | ||
132 | (printk("scsi%d : write %02x to register %d at io_port %04x\n", \ | ||
133 | instance->hostno, (value), (reg), PAS16_io_port(reg)), \ | ||
134 | outb( (value),PAS16_io_port(reg) ) ) | ||
135 | |||
136 | #endif | ||
137 | 104 | ||
105 | #define NCR5380_dma_xfer_len(instance, cmd, phase) (cmd->transfersize) | ||
138 | 106 | ||
139 | #define NCR5380_intr pas16_intr | 107 | #define NCR5380_intr pas16_intr |
140 | #define do_NCR5380_intr do_pas16_intr | ||
141 | #define NCR5380_queue_command pas16_queue_command | 108 | #define NCR5380_queue_command pas16_queue_command |
142 | #define NCR5380_abort pas16_abort | 109 | #define NCR5380_abort pas16_abort |
143 | #define NCR5380_bus_reset pas16_bus_reset | 110 | #define NCR5380_bus_reset pas16_bus_reset |
@@ -150,5 +117,4 @@ | |||
150 | 117 | ||
151 | #define PAS16_IRQS 0xd4a8 | 118 | #define PAS16_IRQS 0xd4a8 |
152 | 119 | ||
153 | #endif /* ndef ASM */ | ||
154 | #endif /* PAS16_H */ | 120 | #endif /* PAS16_H */ |
diff --git a/drivers/scsi/scsi_devinfo.c b/drivers/scsi/scsi_devinfo.c index 2c1160c7ec92..47b9d13f97b8 100644 --- a/drivers/scsi/scsi_devinfo.c +++ b/drivers/scsi/scsi_devinfo.c | |||
@@ -227,6 +227,7 @@ static struct { | |||
227 | {"Promise", "VTrak E610f", NULL, BLIST_SPARSELUN | BLIST_NO_RSOC}, | 227 | {"Promise", "VTrak E610f", NULL, BLIST_SPARSELUN | BLIST_NO_RSOC}, |
228 | {"Promise", "", NULL, BLIST_SPARSELUN}, | 228 | {"Promise", "", NULL, BLIST_SPARSELUN}, |
229 | {"QNAP", "iSCSI Storage", NULL, BLIST_MAX_1024}, | 229 | {"QNAP", "iSCSI Storage", NULL, BLIST_MAX_1024}, |
230 | {"SYNOLOGY", "iSCSI Storage", NULL, BLIST_MAX_1024}, | ||
230 | {"QUANTUM", "XP34301", "1071", BLIST_NOTQ}, | 231 | {"QUANTUM", "XP34301", "1071", BLIST_NOTQ}, |
231 | {"REGAL", "CDC-4X", NULL, BLIST_MAX5LUN | BLIST_SINGLELUN}, | 232 | {"REGAL", "CDC-4X", NULL, BLIST_MAX5LUN | BLIST_SINGLELUN}, |
232 | {"SanDisk", "ImageMate CF-SD1", NULL, BLIST_FORCELUN}, | 233 | {"SanDisk", "ImageMate CF-SD1", NULL, BLIST_FORCELUN}, |
diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c index 41c115c230d9..55627d097873 100644 --- a/drivers/scsi/storvsc_drv.c +++ b/drivers/scsi/storvsc_drv.c | |||
@@ -390,7 +390,7 @@ module_param(storvsc_ringbuffer_size, int, S_IRUGO); | |||
390 | MODULE_PARM_DESC(storvsc_ringbuffer_size, "Ring buffer size (bytes)"); | 390 | MODULE_PARM_DESC(storvsc_ringbuffer_size, "Ring buffer size (bytes)"); |
391 | 391 | ||
392 | module_param(storvsc_vcpus_per_sub_channel, int, S_IRUGO); | 392 | module_param(storvsc_vcpus_per_sub_channel, int, S_IRUGO); |
393 | MODULE_PARM_DESC(vcpus_per_sub_channel, "Ratio of VCPUs to subchannels"); | 393 | MODULE_PARM_DESC(storvsc_vcpus_per_sub_channel, "Ratio of VCPUs to subchannels"); |
394 | /* | 394 | /* |
395 | * Timeout in seconds for all devices managed by this driver. | 395 | * Timeout in seconds for all devices managed by this driver. |
396 | */ | 396 | */ |
diff --git a/drivers/scsi/sun3_scsi.c b/drivers/scsi/sun3_scsi.c index 22a42836d193..b9de487bbd31 100644 --- a/drivers/scsi/sun3_scsi.c +++ b/drivers/scsi/sun3_scsi.c | |||
@@ -53,13 +53,12 @@ | |||
53 | #define NCR5380_queue_command sun3scsi_queue_command | 53 | #define NCR5380_queue_command sun3scsi_queue_command |
54 | #define NCR5380_bus_reset sun3scsi_bus_reset | 54 | #define NCR5380_bus_reset sun3scsi_bus_reset |
55 | #define NCR5380_abort sun3scsi_abort | 55 | #define NCR5380_abort sun3scsi_abort |
56 | #define NCR5380_show_info sun3scsi_show_info | ||
57 | #define NCR5380_info sun3scsi_info | 56 | #define NCR5380_info sun3scsi_info |
58 | 57 | ||
59 | #define NCR5380_dma_read_setup(instance, data, count) \ | 58 | #define NCR5380_dma_read_setup(instance, data, count) \ |
60 | sun3scsi_dma_setup(data, count, 0) | 59 | sun3scsi_dma_setup(instance, data, count, 0) |
61 | #define NCR5380_dma_write_setup(instance, data, count) \ | 60 | #define NCR5380_dma_write_setup(instance, data, count) \ |
62 | sun3scsi_dma_setup(data, count, 1) | 61 | sun3scsi_dma_setup(instance, data, count, 1) |
63 | #define NCR5380_dma_residual(instance) \ | 62 | #define NCR5380_dma_residual(instance) \ |
64 | sun3scsi_dma_residual(instance) | 63 | sun3scsi_dma_residual(instance) |
65 | #define NCR5380_dma_xfer_len(instance, cmd, phase) \ | 64 | #define NCR5380_dma_xfer_len(instance, cmd, phase) \ |
@@ -86,10 +85,6 @@ module_param(setup_use_tagged_queuing, int, 0); | |||
86 | static int setup_hostid = -1; | 85 | static int setup_hostid = -1; |
87 | module_param(setup_hostid, int, 0); | 86 | module_param(setup_hostid, int, 0); |
88 | 87 | ||
89 | /* #define RESET_BOOT */ | ||
90 | |||
91 | #define AFTER_RESET_DELAY (HZ/2) | ||
92 | |||
93 | /* ms to wait after hitting dma regs */ | 88 | /* ms to wait after hitting dma regs */ |
94 | #define SUN3_DMA_DELAY 10 | 89 | #define SUN3_DMA_DELAY 10 |
95 | 90 | ||
@@ -100,11 +95,10 @@ static struct scsi_cmnd *sun3_dma_setup_done; | |||
100 | static unsigned char *sun3_scsi_regp; | 95 | static unsigned char *sun3_scsi_regp; |
101 | static volatile struct sun3_dma_regs *dregs; | 96 | static volatile struct sun3_dma_regs *dregs; |
102 | static struct sun3_udc_regs *udc_regs; | 97 | static struct sun3_udc_regs *udc_regs; |
103 | static unsigned char *sun3_dma_orig_addr = NULL; | 98 | static unsigned char *sun3_dma_orig_addr; |
104 | static unsigned long sun3_dma_orig_count = 0; | 99 | static unsigned long sun3_dma_orig_count; |
105 | static int sun3_dma_active = 0; | 100 | static int sun3_dma_active; |
106 | static unsigned long last_residual = 0; | 101 | static unsigned long last_residual; |
107 | static struct Scsi_Host *default_instance; | ||
108 | 102 | ||
109 | /* | 103 | /* |
110 | * NCR 5380 register access functions | 104 | * NCR 5380 register access functions |
@@ -144,50 +138,12 @@ static inline void sun3_udc_write(unsigned short val, unsigned char reg) | |||
144 | } | 138 | } |
145 | #endif | 139 | #endif |
146 | 140 | ||
147 | #ifdef RESET_BOOT | ||
148 | static void sun3_scsi_reset_boot(struct Scsi_Host *instance) | ||
149 | { | ||
150 | unsigned long end; | ||
151 | |||
152 | /* | ||
153 | * Do a SCSI reset to clean up the bus during initialization. No | ||
154 | * messing with the queues, interrupts, or locks necessary here. | ||
155 | */ | ||
156 | |||
157 | printk( "Sun3 SCSI: resetting the SCSI bus..." ); | ||
158 | |||
159 | /* switch off SCSI IRQ - catch an interrupt without IRQ bit set else */ | ||
160 | // sun3_disable_irq( IRQ_SUN3_SCSI ); | ||
161 | |||
162 | /* get in phase */ | ||
163 | NCR5380_write( TARGET_COMMAND_REG, | ||
164 | PHASE_SR_TO_TCR( NCR5380_read(STATUS_REG) )); | ||
165 | |||
166 | /* assert RST */ | ||
167 | NCR5380_write( INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_RST ); | ||
168 | |||
169 | /* The min. reset hold time is 25us, so 40us should be enough */ | ||
170 | udelay( 50 ); | ||
171 | |||
172 | /* reset RST and interrupt */ | ||
173 | NCR5380_write( INITIATOR_COMMAND_REG, ICR_BASE ); | ||
174 | NCR5380_read( RESET_PARITY_INTERRUPT_REG ); | ||
175 | |||
176 | for( end = jiffies + AFTER_RESET_DELAY; time_before(jiffies, end); ) | ||
177 | barrier(); | ||
178 | |||
179 | /* switch on SCSI IRQ again */ | ||
180 | // sun3_enable_irq( IRQ_SUN3_SCSI ); | ||
181 | |||
182 | printk( " done\n" ); | ||
183 | } | ||
184 | #endif | ||
185 | |||
186 | // safe bits for the CSR | 141 | // safe bits for the CSR |
187 | #define CSR_GOOD 0x060f | 142 | #define CSR_GOOD 0x060f |
188 | 143 | ||
189 | static irqreturn_t scsi_sun3_intr(int irq, void *dummy) | 144 | static irqreturn_t scsi_sun3_intr(int irq, void *dev) |
190 | { | 145 | { |
146 | struct Scsi_Host *instance = dev; | ||
191 | unsigned short csr = dregs->csr; | 147 | unsigned short csr = dregs->csr; |
192 | int handled = 0; | 148 | int handled = 0; |
193 | 149 | ||
@@ -196,46 +152,24 @@ static irqreturn_t scsi_sun3_intr(int irq, void *dummy) | |||
196 | #endif | 152 | #endif |
197 | 153 | ||
198 | if(csr & ~CSR_GOOD) { | 154 | if(csr & ~CSR_GOOD) { |
199 | if(csr & CSR_DMA_BUSERR) { | 155 | if (csr & CSR_DMA_BUSERR) |
200 | printk("scsi%d: bus error in dma\n", default_instance->host_no); | 156 | shost_printk(KERN_ERR, instance, "bus error in DMA\n"); |
201 | } | 157 | if (csr & CSR_DMA_CONFLICT) |
202 | 158 | shost_printk(KERN_ERR, instance, "DMA conflict\n"); | |
203 | if(csr & CSR_DMA_CONFLICT) { | ||
204 | printk("scsi%d: dma conflict\n", default_instance->host_no); | ||
205 | } | ||
206 | handled = 1; | 159 | handled = 1; |
207 | } | 160 | } |
208 | 161 | ||
209 | if(csr & (CSR_SDB_INT | CSR_DMA_INT)) { | 162 | if(csr & (CSR_SDB_INT | CSR_DMA_INT)) { |
210 | NCR5380_intr(irq, dummy); | 163 | NCR5380_intr(irq, dev); |
211 | handled = 1; | 164 | handled = 1; |
212 | } | 165 | } |
213 | 166 | ||
214 | return IRQ_RETVAL(handled); | 167 | return IRQ_RETVAL(handled); |
215 | } | 168 | } |
216 | 169 | ||
217 | /* | ||
218 | * Debug stuff - to be called on NMI, or sysrq key. Use at your own risk; | ||
219 | * reentering NCR5380_print_status seems to have ugly side effects | ||
220 | */ | ||
221 | |||
222 | /* this doesn't seem to get used at all -- sam */ | ||
223 | #if 0 | ||
224 | void sun3_sun3_debug (void) | ||
225 | { | ||
226 | unsigned long flags; | ||
227 | |||
228 | if (default_instance) { | ||
229 | local_irq_save(flags); | ||
230 | NCR5380_print_status(default_instance); | ||
231 | local_irq_restore(flags); | ||
232 | } | ||
233 | } | ||
234 | #endif | ||
235 | |||
236 | |||
237 | /* sun3scsi_dma_setup() -- initialize the dma controller for a read/write */ | 170 | /* sun3scsi_dma_setup() -- initialize the dma controller for a read/write */ |
238 | static unsigned long sun3scsi_dma_setup(void *data, unsigned long count, int write_flag) | 171 | static unsigned long sun3scsi_dma_setup(struct Scsi_Host *instance, |
172 | void *data, unsigned long count, int write_flag) | ||
239 | { | 173 | { |
240 | void *addr; | 174 | void *addr; |
241 | 175 | ||
@@ -287,10 +221,9 @@ static unsigned long sun3scsi_dma_setup(void *data, unsigned long count, int wri | |||
287 | dregs->csr |= CSR_FIFO; | 221 | dregs->csr |= CSR_FIFO; |
288 | 222 | ||
289 | if(dregs->fifo_count != count) { | 223 | if(dregs->fifo_count != count) { |
290 | printk("scsi%d: fifo_mismatch %04x not %04x\n", | 224 | shost_printk(KERN_ERR, instance, "FIFO mismatch %04x not %04x\n", |
291 | default_instance->host_no, dregs->fifo_count, | 225 | dregs->fifo_count, (unsigned int) count); |
292 | (unsigned int) count); | 226 | NCR5380_dprint(NDEBUG_DMA, instance); |
293 | NCR5380_dprint(NDEBUG_DMA, default_instance); | ||
294 | } | 227 | } |
295 | 228 | ||
296 | /* setup udc */ | 229 | /* setup udc */ |
@@ -325,21 +258,6 @@ static unsigned long sun3scsi_dma_setup(void *data, unsigned long count, int wri | |||
325 | 258 | ||
326 | } | 259 | } |
327 | 260 | ||
328 | #ifndef SUN3_SCSI_VME | ||
329 | static inline unsigned long sun3scsi_dma_count(struct Scsi_Host *instance) | ||
330 | { | ||
331 | unsigned short resid; | ||
332 | |||
333 | dregs->udc_addr = 0x32; | ||
334 | udelay(SUN3_DMA_DELAY); | ||
335 | resid = dregs->udc_data; | ||
336 | udelay(SUN3_DMA_DELAY); | ||
337 | resid *= 2; | ||
338 | |||
339 | return (unsigned long) resid; | ||
340 | } | ||
341 | #endif | ||
342 | |||
343 | static inline unsigned long sun3scsi_dma_residual(struct Scsi_Host *instance) | 261 | static inline unsigned long sun3scsi_dma_residual(struct Scsi_Host *instance) |
344 | { | 262 | { |
345 | return last_residual; | 263 | return last_residual; |
@@ -437,7 +355,10 @@ static int sun3scsi_dma_finish(int write_flag) | |||
437 | } | 355 | } |
438 | } | 356 | } |
439 | 357 | ||
440 | count = sun3scsi_dma_count(default_instance); | 358 | dregs->udc_addr = 0x32; |
359 | udelay(SUN3_DMA_DELAY); | ||
360 | count = 2 * dregs->udc_data; | ||
361 | udelay(SUN3_DMA_DELAY); | ||
441 | 362 | ||
442 | fifo = dregs->fifo_count; | 363 | fifo = dregs->fifo_count; |
443 | last_residual = fifo; | 364 | last_residual = fifo; |
@@ -502,17 +423,17 @@ static int sun3scsi_dma_finish(int write_flag) | |||
502 | static struct scsi_host_template sun3_scsi_template = { | 423 | static struct scsi_host_template sun3_scsi_template = { |
503 | .module = THIS_MODULE, | 424 | .module = THIS_MODULE, |
504 | .proc_name = DRV_MODULE_NAME, | 425 | .proc_name = DRV_MODULE_NAME, |
505 | .show_info = sun3scsi_show_info, | ||
506 | .name = SUN3_SCSI_NAME, | 426 | .name = SUN3_SCSI_NAME, |
507 | .info = sun3scsi_info, | 427 | .info = sun3scsi_info, |
508 | .queuecommand = sun3scsi_queue_command, | 428 | .queuecommand = sun3scsi_queue_command, |
509 | .eh_abort_handler = sun3scsi_abort, | 429 | .eh_abort_handler = sun3scsi_abort, |
510 | .eh_bus_reset_handler = sun3scsi_bus_reset, | 430 | .eh_bus_reset_handler = sun3scsi_bus_reset, |
511 | .can_queue = 16, | 431 | .can_queue = 16, |
512 | .this_id = 7, | 432 | .this_id = 7, |
513 | .sg_tablesize = SG_NONE, | 433 | .sg_tablesize = SG_NONE, |
514 | .cmd_per_lun = 2, | 434 | .cmd_per_lun = 2, |
515 | .use_clustering = DISABLE_CLUSTERING | 435 | .use_clustering = DISABLE_CLUSTERING, |
436 | .cmd_size = NCR5380_CMD_SIZE, | ||
516 | }; | 437 | }; |
517 | 438 | ||
518 | static int __init sun3_scsi_probe(struct platform_device *pdev) | 439 | static int __init sun3_scsi_probe(struct platform_device *pdev) |
@@ -591,7 +512,6 @@ static int __init sun3_scsi_probe(struct platform_device *pdev) | |||
591 | error = -ENOMEM; | 512 | error = -ENOMEM; |
592 | goto fail_alloc; | 513 | goto fail_alloc; |
593 | } | 514 | } |
594 | default_instance = instance; | ||
595 | 515 | ||
596 | instance->io_port = (unsigned long)ioaddr; | 516 | instance->io_port = (unsigned long)ioaddr; |
597 | instance->irq = irq->start; | 517 | instance->irq = irq->start; |
@@ -600,7 +520,9 @@ static int __init sun3_scsi_probe(struct platform_device *pdev) | |||
600 | host_flags |= setup_use_tagged_queuing > 0 ? FLAG_TAGGED_QUEUING : 0; | 520 | host_flags |= setup_use_tagged_queuing > 0 ? FLAG_TAGGED_QUEUING : 0; |
601 | #endif | 521 | #endif |
602 | 522 | ||
603 | NCR5380_init(instance, host_flags); | 523 | error = NCR5380_init(instance, host_flags); |
524 | if (error) | ||
525 | goto fail_init; | ||
604 | 526 | ||
605 | error = request_irq(instance->irq, scsi_sun3_intr, 0, | 527 | error = request_irq(instance->irq, scsi_sun3_intr, 0, |
606 | "NCR5380", instance); | 528 | "NCR5380", instance); |
@@ -631,9 +553,7 @@ static int __init sun3_scsi_probe(struct platform_device *pdev) | |||
631 | dregs->ivect = VME_DATA24 | (instance->irq & 0xff); | 553 | dregs->ivect = VME_DATA24 | (instance->irq & 0xff); |
632 | #endif | 554 | #endif |
633 | 555 | ||
634 | #ifdef RESET_BOOT | 556 | NCR5380_maybe_reset_bus(instance); |
635 | sun3_scsi_reset_boot(instance); | ||
636 | #endif | ||
637 | 557 | ||
638 | error = scsi_add_host(instance, NULL); | 558 | error = scsi_add_host(instance, NULL); |
639 | if (error) | 559 | if (error) |
@@ -649,6 +569,7 @@ fail_host: | |||
649 | free_irq(instance->irq, instance); | 569 | free_irq(instance->irq, instance); |
650 | fail_irq: | 570 | fail_irq: |
651 | NCR5380_exit(instance); | 571 | NCR5380_exit(instance); |
572 | fail_init: | ||
652 | scsi_host_put(instance); | 573 | scsi_host_put(instance); |
653 | fail_alloc: | 574 | fail_alloc: |
654 | if (udc_regs) | 575 | if (udc_regs) |
diff --git a/drivers/scsi/t128.c b/drivers/scsi/t128.c index 87828acbf7c6..4615fda60dbd 100644 --- a/drivers/scsi/t128.c +++ b/drivers/scsi/t128.c | |||
@@ -68,14 +68,11 @@ | |||
68 | * 15 9-11 | 68 | * 15 9-11 |
69 | */ | 69 | */ |
70 | 70 | ||
71 | #include <linux/signal.h> | ||
72 | #include <linux/io.h> | 71 | #include <linux/io.h> |
73 | #include <linux/blkdev.h> | 72 | #include <linux/blkdev.h> |
74 | #include <linux/interrupt.h> | 73 | #include <linux/interrupt.h> |
75 | #include <linux/stat.h> | ||
76 | #include <linux/init.h> | 74 | #include <linux/init.h> |
77 | #include <linux/module.h> | 75 | #include <linux/module.h> |
78 | #include <linux/delay.h> | ||
79 | 76 | ||
80 | #include <scsi/scsi_host.h> | 77 | #include <scsi/scsi_host.h> |
81 | #include "t128.h" | 78 | #include "t128.h" |
@@ -126,7 +123,7 @@ static struct signature { | |||
126 | 123 | ||
127 | static int __init t128_setup(char *str) | 124 | static int __init t128_setup(char *str) |
128 | { | 125 | { |
129 | static int commandline_current = 0; | 126 | static int commandline_current; |
130 | int i; | 127 | int i; |
131 | int ints[10]; | 128 | int ints[10]; |
132 | 129 | ||
@@ -165,7 +162,7 @@ __setup("t128=", t128_setup); | |||
165 | 162 | ||
166 | static int __init t128_detect(struct scsi_host_template *tpnt) | 163 | static int __init t128_detect(struct scsi_host_template *tpnt) |
167 | { | 164 | { |
168 | static int current_override = 0, current_base = 0; | 165 | static int current_override, current_base; |
169 | struct Scsi_Host *instance; | 166 | struct Scsi_Host *instance; |
170 | unsigned long base; | 167 | unsigned long base; |
171 | void __iomem *p; | 168 | void __iomem *p; |
@@ -182,9 +179,8 @@ static int __init t128_detect(struct scsi_host_template *tpnt) | |||
182 | base = 0; | 179 | base = 0; |
183 | } else | 180 | } else |
184 | for (; !base && (current_base < NO_BASES); ++current_base) { | 181 | for (; !base && (current_base < NO_BASES); ++current_base) { |
185 | #if (TDEBUG & TDEBUG_INIT) | 182 | dprintk(NDEBUG_INIT, "t128: probing address 0x%08x\n", |
186 | printk("scsi-t128 : probing address %08x\n", bases[current_base].address); | 183 | bases[current_base].address); |
187 | #endif | ||
188 | if (bases[current_base].noauto) | 184 | if (bases[current_base].noauto) |
189 | continue; | 185 | continue; |
190 | p = ioremap(bases[current_base].address, 0x2000); | 186 | p = ioremap(bases[current_base].address, 0x2000); |
@@ -195,17 +191,13 @@ static int __init t128_detect(struct scsi_host_template *tpnt) | |||
195 | signatures[sig].string, | 191 | signatures[sig].string, |
196 | strlen(signatures[sig].string))) { | 192 | strlen(signatures[sig].string))) { |
197 | base = bases[current_base].address; | 193 | base = bases[current_base].address; |
198 | #if (TDEBUG & TDEBUG_INIT) | 194 | dprintk(NDEBUG_INIT, "t128: detected board\n"); |
199 | printk("scsi-t128 : detected board.\n"); | ||
200 | #endif | ||
201 | goto found; | 195 | goto found; |
202 | } | 196 | } |
203 | iounmap(p); | 197 | iounmap(p); |
204 | } | 198 | } |
205 | 199 | ||
206 | #if defined(TDEBUG) && (TDEBUG & TDEBUG_INIT) | 200 | dprintk(NDEBUG_INIT, "t128: base = 0x%08x\n", (unsigned int)base); |
207 | printk("scsi-t128 : base = %08x\n", (unsigned int) base); | ||
208 | #endif | ||
209 | 201 | ||
210 | if (!base) | 202 | if (!base) |
211 | break; | 203 | break; |
@@ -213,12 +205,15 @@ static int __init t128_detect(struct scsi_host_template *tpnt) | |||
213 | found: | 205 | found: |
214 | instance = scsi_register (tpnt, sizeof(struct NCR5380_hostdata)); | 206 | instance = scsi_register (tpnt, sizeof(struct NCR5380_hostdata)); |
215 | if(instance == NULL) | 207 | if(instance == NULL) |
216 | break; | 208 | goto out_unmap; |
217 | 209 | ||
218 | instance->base = base; | 210 | instance->base = base; |
219 | ((struct NCR5380_hostdata *)instance->hostdata)->base = p; | 211 | ((struct NCR5380_hostdata *)instance->hostdata)->base = p; |
220 | 212 | ||
221 | NCR5380_init(instance, 0); | 213 | if (NCR5380_init(instance, 0)) |
214 | goto out_unregister; | ||
215 | |||
216 | NCR5380_maybe_reset_bus(instance); | ||
222 | 217 | ||
223 | if (overrides[current_override].irq != IRQ_AUTO) | 218 | if (overrides[current_override].irq != IRQ_AUTO) |
224 | instance->irq = overrides[current_override].irq; | 219 | instance->irq = overrides[current_override].irq; |
@@ -242,27 +237,30 @@ found: | |||
242 | printk("scsi%d : please jumper the board for a free IRQ.\n", instance->host_no); | 237 | printk("scsi%d : please jumper the board for a free IRQ.\n", instance->host_no); |
243 | } | 238 | } |
244 | 239 | ||
245 | #if defined(TDEBUG) && (TDEBUG & TDEBUG_INIT) | 240 | dprintk(NDEBUG_INIT, "scsi%d: irq = %d\n", |
246 | printk("scsi%d : irq = %d\n", instance->host_no, instance->irq); | 241 | instance->host_no, instance->irq); |
247 | #endif | ||
248 | 242 | ||
249 | ++current_override; | 243 | ++current_override; |
250 | ++count; | 244 | ++count; |
251 | } | 245 | } |
252 | return count; | 246 | return count; |
247 | |||
248 | out_unregister: | ||
249 | scsi_unregister(instance); | ||
250 | out_unmap: | ||
251 | iounmap(p); | ||
252 | return count; | ||
253 | } | 253 | } |
254 | 254 | ||
255 | static int t128_release(struct Scsi_Host *shost) | 255 | static int t128_release(struct Scsi_Host *shost) |
256 | { | 256 | { |
257 | NCR5380_local_declare(); | 257 | struct NCR5380_hostdata *hostdata = shost_priv(shost); |
258 | NCR5380_setup(shost); | 258 | |
259 | if (shost->irq != NO_IRQ) | 259 | if (shost->irq != NO_IRQ) |
260 | free_irq(shost->irq, shost); | 260 | free_irq(shost->irq, shost); |
261 | NCR5380_exit(shost); | 261 | NCR5380_exit(shost); |
262 | if (shost->io_port && shost->n_io_port) | ||
263 | release_region(shost->io_port, shost->n_io_port); | ||
264 | scsi_unregister(shost); | 262 | scsi_unregister(shost); |
265 | iounmap(base); | 263 | iounmap(hostdata->base); |
266 | return 0; | 264 | return 0; |
267 | } | 265 | } |
268 | 266 | ||
@@ -308,14 +306,14 @@ static int t128_biosparam(struct scsi_device *sdev, struct block_device *bdev, | |||
308 | * timeout. | 306 | * timeout. |
309 | */ | 307 | */ |
310 | 308 | ||
311 | static inline int NCR5380_pread (struct Scsi_Host *instance, unsigned char *dst, | 309 | static inline int |
312 | int len) { | 310 | NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst, int len) |
313 | NCR5380_local_declare(); | 311 | { |
314 | void __iomem *reg; | 312 | struct NCR5380_hostdata *hostdata = shost_priv(instance); |
313 | void __iomem *reg, *base = hostdata->base; | ||
315 | unsigned char *d = dst; | 314 | unsigned char *d = dst; |
316 | register int i = len; | 315 | register int i = len; |
317 | 316 | ||
318 | NCR5380_setup(instance); | ||
319 | reg = base + T_DATA_REG_OFFSET; | 317 | reg = base + T_DATA_REG_OFFSET; |
320 | 318 | ||
321 | #if 0 | 319 | #if 0 |
@@ -354,14 +352,14 @@ static inline int NCR5380_pread (struct Scsi_Host *instance, unsigned char *dst, | |||
354 | * timeout. | 352 | * timeout. |
355 | */ | 353 | */ |
356 | 354 | ||
357 | static inline int NCR5380_pwrite (struct Scsi_Host *instance, unsigned char *src, | 355 | static inline int |
358 | int len) { | 356 | NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src, int len) |
359 | NCR5380_local_declare(); | 357 | { |
360 | void __iomem *reg; | 358 | struct NCR5380_hostdata *hostdata = shost_priv(instance); |
359 | void __iomem *reg, *base = hostdata->base; | ||
361 | unsigned char *s = src; | 360 | unsigned char *s = src; |
362 | register int i = len; | 361 | register int i = len; |
363 | 362 | ||
364 | NCR5380_setup(instance); | ||
365 | reg = base + T_DATA_REG_OFFSET; | 363 | reg = base + T_DATA_REG_OFFSET; |
366 | 364 | ||
367 | #if 0 | 365 | #if 0 |
@@ -392,21 +390,23 @@ MODULE_LICENSE("GPL"); | |||
392 | #include "NCR5380.c" | 390 | #include "NCR5380.c" |
393 | 391 | ||
394 | static struct scsi_host_template driver_template = { | 392 | static struct scsi_host_template driver_template = { |
395 | .name = "Trantor T128/T128F/T228", | 393 | .name = "Trantor T128/T128F/T228", |
396 | .detect = t128_detect, | 394 | .detect = t128_detect, |
397 | .release = t128_release, | 395 | .release = t128_release, |
398 | .proc_name = "t128", | 396 | .proc_name = "t128", |
399 | .show_info = t128_show_info, | 397 | .show_info = t128_show_info, |
400 | .write_info = t128_write_info, | 398 | .write_info = t128_write_info, |
401 | .info = t128_info, | 399 | .info = t128_info, |
402 | .queuecommand = t128_queue_command, | 400 | .queuecommand = t128_queue_command, |
403 | .eh_abort_handler = t128_abort, | 401 | .eh_abort_handler = t128_abort, |
404 | .eh_bus_reset_handler = t128_bus_reset, | 402 | .eh_bus_reset_handler = t128_bus_reset, |
405 | .bios_param = t128_biosparam, | 403 | .bios_param = t128_biosparam, |
406 | .can_queue = CAN_QUEUE, | 404 | .can_queue = 32, |
407 | .this_id = 7, | 405 | .this_id = 7, |
408 | .sg_tablesize = SG_ALL, | 406 | .sg_tablesize = SG_ALL, |
409 | .cmd_per_lun = CMD_PER_LUN, | 407 | .cmd_per_lun = 2, |
410 | .use_clustering = DISABLE_CLUSTERING, | 408 | .use_clustering = DISABLE_CLUSTERING, |
409 | .cmd_size = NCR5380_CMD_SIZE, | ||
410 | .max_sectors = 128, | ||
411 | }; | 411 | }; |
412 | #include "scsi_module.c" | 412 | #include "scsi_module.c" |
diff --git a/drivers/scsi/t128.h b/drivers/scsi/t128.h index 2c7371454dfd..dd16d85497e1 100644 --- a/drivers/scsi/t128.h +++ b/drivers/scsi/t128.h | |||
@@ -23,10 +23,6 @@ | |||
23 | #ifndef T128_H | 23 | #ifndef T128_H |
24 | #define T128_H | 24 | #define T128_H |
25 | 25 | ||
26 | #define TDEBUG 0 | ||
27 | #define TDEBUG_INIT 0x1 | ||
28 | #define TDEBUG_TRANSFER 0x2 | ||
29 | |||
30 | /* | 26 | /* |
31 | * The trantor boards are memory mapped. They use an NCR5380 or | 27 | * The trantor boards are memory mapped. They use an NCR5380 or |
32 | * equivalent (my sample board had part second sourced from ZILOG). | 28 | * equivalent (my sample board had part second sourced from ZILOG). |
@@ -71,44 +67,18 @@ | |||
71 | 67 | ||
72 | #define T_DATA_REG_OFFSET 0x1e00 /* rw 512 bytes long */ | 68 | #define T_DATA_REG_OFFSET 0x1e00 /* rw 512 bytes long */ |
73 | 69 | ||
74 | #ifndef ASM | ||
75 | |||
76 | #ifndef CMD_PER_LUN | ||
77 | #define CMD_PER_LUN 2 | ||
78 | #endif | ||
79 | |||
80 | #ifndef CAN_QUEUE | ||
81 | #define CAN_QUEUE 32 | ||
82 | #endif | ||
83 | |||
84 | #define NCR5380_implementation_fields \ | 70 | #define NCR5380_implementation_fields \ |
85 | void __iomem *base | 71 | void __iomem *base |
86 | 72 | ||
87 | #define NCR5380_local_declare() \ | 73 | #define T128_address(reg) \ |
88 | void __iomem *base | 74 | (((struct NCR5380_hostdata *)shost_priv(instance))->base + T_5380_OFFSET + ((reg) * 0x20)) |
89 | |||
90 | #define NCR5380_setup(instance) \ | ||
91 | base = ((struct NCR5380_hostdata *)(instance->hostdata))->base | ||
92 | 75 | ||
93 | #define T128_address(reg) (base + T_5380_OFFSET + ((reg) * 0x20)) | ||
94 | |||
95 | #if !(TDEBUG & TDEBUG_TRANSFER) | ||
96 | #define NCR5380_read(reg) readb(T128_address(reg)) | 76 | #define NCR5380_read(reg) readb(T128_address(reg)) |
97 | #define NCR5380_write(reg, value) writeb((value),(T128_address(reg))) | 77 | #define NCR5380_write(reg, value) writeb((value),(T128_address(reg))) |
98 | #else | 78 | |
99 | #define NCR5380_read(reg) \ | 79 | #define NCR5380_dma_xfer_len(instance, cmd, phase) (cmd->transfersize) |
100 | (((unsigned char) printk("scsi%d : read register %d at address %08x\n"\ | ||
101 | , instance->hostno, (reg), T128_address(reg))), readb(T128_address(reg))) | ||
102 | |||
103 | #define NCR5380_write(reg, value) { \ | ||
104 | printk("scsi%d : write %02x to register %d at address %08x\n", \ | ||
105 | instance->hostno, (value), (reg), T128_address(reg)); \ | ||
106 | writeb((value), (T128_address(reg))); \ | ||
107 | } | ||
108 | #endif | ||
109 | 80 | ||
110 | #define NCR5380_intr t128_intr | 81 | #define NCR5380_intr t128_intr |
111 | #define do_NCR5380_intr do_t128_intr | ||
112 | #define NCR5380_queue_command t128_queue_command | 82 | #define NCR5380_queue_command t128_queue_command |
113 | #define NCR5380_abort t128_abort | 83 | #define NCR5380_abort t128_abort |
114 | #define NCR5380_bus_reset t128_bus_reset | 84 | #define NCR5380_bus_reset t128_bus_reset |
@@ -121,5 +91,4 @@ | |||
121 | 91 | ||
122 | #define T128_IRQS 0xc4a8 | 92 | #define T128_IRQS 0xc4a8 |
123 | 93 | ||
124 | #endif /* ndef ASM */ | ||
125 | #endif /* T128_H */ | 94 | #endif /* T128_H */ |