diff options
Diffstat (limited to 'drivers/scsi/gdth.c')
-rw-r--r-- | drivers/scsi/gdth.c | 2933 |
1 files changed, 1254 insertions, 1679 deletions
diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c index 55e4d2dc2bbe..e8010a702e73 100644 --- a/drivers/scsi/gdth.c +++ b/drivers/scsi/gdth.c | |||
@@ -27,280 +27,8 @@ | |||
27 | * along with this kernel; if not, write to the Free Software * | 27 | * along with this kernel; if not, write to the Free Software * |
28 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * | 28 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * |
29 | * * | 29 | * * |
30 | * Linux kernel 2.4.x, 2.6.x supported * | 30 | * Linux kernel 2.6.x supported * |
31 | * * | 31 | * * |
32 | * $Log: gdth.c,v $ | ||
33 | * Revision 1.74 2006/04/10 13:44:47 achim | ||
34 | * Community changes for 2.6.x | ||
35 | * Kernel 2.2.x no longer supported | ||
36 | * scsi_request interface removed, thanks to Christoph Hellwig | ||
37 | * | ||
38 | * Revision 1.73 2004/03/31 13:33:03 achim | ||
39 | * Special command 0xfd implemented to detect 64-bit DMA support | ||
40 | * | ||
41 | * Revision 1.72 2004/03/17 08:56:04 achim | ||
42 | * 64-bit DMA only enabled if FW >= x.43 | ||
43 | * | ||
44 | * Revision 1.71 2004/03/05 15:51:29 achim | ||
45 | * Screen service: separate message buffer, bugfixes | ||
46 | * | ||
47 | * Revision 1.70 2004/02/27 12:19:07 achim | ||
48 | * Bugfix: Reset bit in config (0xfe) call removed | ||
49 | * | ||
50 | * Revision 1.69 2004/02/20 09:50:24 achim | ||
51 | * Compatibility changes for kernels < 2.4.20 | ||
52 | * Bugfix screen service command size | ||
53 | * pci_set_dma_mask() error handling added | ||
54 | * | ||
55 | * Revision 1.68 2004/02/19 15:46:54 achim | ||
56 | * 64-bit DMA bugfixes | ||
57 | * Drive size bugfix for drives > 1TB | ||
58 | * | ||
59 | * Revision 1.67 2004/01/14 13:11:57 achim | ||
60 | * Tool access over /proc no longer supported | ||
61 | * Bugfixes IOCTLs | ||
62 | * | ||
63 | * Revision 1.66 2003/12/19 15:04:06 achim | ||
64 | * Bugfixes support for drives > 2TB | ||
65 | * | ||
66 | * Revision 1.65 2003/12/15 11:21:56 achim | ||
67 | * 64-bit DMA support added | ||
68 | * Support for drives > 2 TB implemented | ||
69 | * Kernels 2.2.x, 2.4.x, 2.6.x supported | ||
70 | * | ||
71 | * Revision 1.64 2003/09/17 08:30:26 achim | ||
72 | * EISA/ISA controller scan disabled | ||
73 | * Command line switch probe_eisa_isa added | ||
74 | * | ||
75 | * Revision 1.63 2003/07/12 14:01:00 Daniele Bellucci <bellucda@tiscali.it> | ||
76 | * Minor cleanups in gdth_ioctl. | ||
77 | * | ||
78 | * Revision 1.62 2003/02/27 15:01:59 achim | ||
79 | * Dynamic DMA mapping implemented | ||
80 | * New (character device) IOCTL interface added | ||
81 | * Other controller related changes made | ||
82 | * | ||
83 | * Revision 1.61 2002/11/08 13:09:52 boji | ||
84 | * Added support for XSCALE based RAID Controllers | ||
85 | * Fixed SCREENSERVICE initialization in SMP cases | ||
86 | * Added checks for gdth_polling before GDTH_HA_LOCK | ||
87 | * | ||
88 | * Revision 1.60 2002/02/05 09:35:22 achim | ||
89 | * MODULE_LICENSE only if kernel >= 2.4.11 | ||
90 | * | ||
91 | * Revision 1.59 2002/01/30 09:46:33 achim | ||
92 | * Small changes | ||
93 | * | ||
94 | * Revision 1.58 2002/01/29 15:30:02 achim | ||
95 | * Set default value of shared_access to Y | ||
96 | * New status S_CACHE_RESERV for clustering added | ||
97 | * | ||
98 | * Revision 1.57 2001/08/21 11:16:35 achim | ||
99 | * Bugfix free_irq() | ||
100 | * | ||
101 | * Revision 1.56 2001/08/09 11:19:39 achim | ||
102 | * Scsi_Host_Template changes | ||
103 | * | ||
104 | * Revision 1.55 2001/08/09 10:11:28 achim | ||
105 | * Command HOST_UNFREEZE_IO before cache service init. | ||
106 | * | ||
107 | * Revision 1.54 2001/07/20 13:48:12 achim | ||
108 | * Expand: gdth_analyse_hdrive() removed | ||
109 | * | ||
110 | * Revision 1.53 2001/07/17 09:52:49 achim | ||
111 | * Small OEM related change | ||
112 | * | ||
113 | * Revision 1.52 2001/06/19 15:06:20 achim | ||
114 | * New host command GDT_UNFREEZE_IO added | ||
115 | * | ||
116 | * Revision 1.51 2001/05/22 06:42:37 achim | ||
117 | * PCI: Subdevice ID added | ||
118 | * | ||
119 | * Revision 1.50 2001/05/17 13:42:16 achim | ||
120 | * Support for Intel Storage RAID Controllers added | ||
121 | * | ||
122 | * Revision 1.50 2001/05/17 12:12:34 achim | ||
123 | * Support for Intel Storage RAID Controllers added | ||
124 | * | ||
125 | * Revision 1.49 2001/03/15 15:07:17 achim | ||
126 | * New __setup interface for boot command line options added | ||
127 | * | ||
128 | * Revision 1.48 2001/02/06 12:36:28 achim | ||
129 | * Bugfix Cluster protocol | ||
130 | * | ||
131 | * Revision 1.47 2001/01/10 14:42:06 achim | ||
132 | * New switch shared_access added | ||
133 | * | ||
134 | * Revision 1.46 2001/01/09 08:11:35 achim | ||
135 | * gdth_command() removed | ||
136 | * meaning of Scsi_Pointer members changed | ||
137 | * | ||
138 | * Revision 1.45 2000/11/16 12:02:24 achim | ||
139 | * Changes for kernel 2.4 | ||
140 | * | ||
141 | * Revision 1.44 2000/10/11 08:44:10 achim | ||
142 | * Clustering changes: New flag media_changed added | ||
143 | * | ||
144 | * Revision 1.43 2000/09/20 12:59:01 achim | ||
145 | * DPMEM remap functions for all PCI controller types implemented | ||
146 | * Small changes for ia64 platform | ||
147 | * | ||
148 | * Revision 1.42 2000/07/20 09:04:50 achim | ||
149 | * Small changes for kernel 2.4 | ||
150 | * | ||
151 | * Revision 1.41 2000/07/04 14:11:11 achim | ||
152 | * gdth_analyse_hdrive() added to rescan drives after online expansion | ||
153 | * | ||
154 | * Revision 1.40 2000/06/27 11:24:16 achim | ||
155 | * Changes Clustering, Screenservice | ||
156 | * | ||
157 | * Revision 1.39 2000/06/15 13:09:04 achim | ||
158 | * Changes for gdth_do_cmd() | ||
159 | * | ||
160 | * Revision 1.38 2000/06/15 12:08:43 achim | ||
161 | * Bugfix gdth_sync_event(), service SCREENSERVICE | ||
162 | * Data direction for command 0xc2 changed to DOU | ||
163 | * | ||
164 | * Revision 1.37 2000/05/25 13:50:10 achim | ||
165 | * New driver parameter virt_ctr added | ||
166 | * | ||
167 | * Revision 1.36 2000/05/04 08:50:46 achim | ||
168 | * Event buffer now in gdth_ha_str | ||
169 | * | ||
170 | * Revision 1.35 2000/03/03 10:44:08 achim | ||
171 | * New event_string only valid for the RP controller family | ||
172 | * | ||
173 | * Revision 1.34 2000/03/02 14:55:29 achim | ||
174 | * New mechanism for async. event handling implemented | ||
175 | * | ||
176 | * Revision 1.33 2000/02/21 15:37:37 achim | ||
177 | * Bugfix Alpha platform + DPMEM above 4GB | ||
178 | * | ||
179 | * Revision 1.32 2000/02/14 16:17:37 achim | ||
180 | * Bugfix sense_buffer[] + raw devices | ||
181 | * | ||
182 | * Revision 1.31 2000/02/10 10:29:00 achim | ||
183 | * Delete sense_buffer[0], if command OK | ||
184 | * | ||
185 | * Revision 1.30 1999/11/02 13:42:39 achim | ||
186 | * ARRAY_DRV_LIST2 implemented | ||
187 | * Now 255 log. and 100 host drives supported | ||
188 | * | ||
189 | * Revision 1.29 1999/10/05 13:28:47 achim | ||
190 | * GDT_CLUST_RESET added | ||
191 | * | ||
192 | * Revision 1.28 1999/08/12 13:44:54 achim | ||
193 | * MOUNTALL removed | ||
194 | * Cluster drives -> removeable drives | ||
195 | * | ||
196 | * Revision 1.27 1999/06/22 07:22:38 achim | ||
197 | * Small changes | ||
198 | * | ||
199 | * Revision 1.26 1999/06/10 16:09:12 achim | ||
200 | * Cluster Host Drive support: Bugfixes | ||
201 | * | ||
202 | * Revision 1.25 1999/06/01 16:03:56 achim | ||
203 | * gdth_init_pci(): Manipulate config. space to start RP controller | ||
204 | * | ||
205 | * Revision 1.24 1999/05/26 11:53:06 achim | ||
206 | * Cluster Host Drive support added | ||
207 | * | ||
208 | * Revision 1.23 1999/03/26 09:12:31 achim | ||
209 | * Default value for hdr_channel set to 0 | ||
210 | * | ||
211 | * Revision 1.22 1999/03/22 16:27:16 achim | ||
212 | * Bugfix: gdth_store_event() must not be locked with GDTH_LOCK_HA() | ||
213 | * | ||
214 | * Revision 1.21 1999/03/16 13:40:34 achim | ||
215 | * Problems with reserved drives solved | ||
216 | * gdth_eh_bus_reset() implemented | ||
217 | * | ||
218 | * Revision 1.20 1999/03/10 09:08:13 achim | ||
219 | * Bugfix: Corrections in gdth_direction_tab[] made | ||
220 | * Bugfix: Increase command timeout (gdth_update_timeout()) NOT in gdth_putq() | ||
221 | * | ||
222 | * Revision 1.19 1999/03/05 14:38:16 achim | ||
223 | * Bugfix: Heads/Sectors mapping for reserved devices possibly wrong | ||
224 | * -> gdth_eval_mapping() implemented, changes in gdth_bios_param() | ||
225 | * INIT_RETRIES set to 100s to avoid DEINIT-Timeout for controllers | ||
226 | * with BIOS disabled and memory test set to Intensive | ||
227 | * Enhanced /proc support | ||
228 | * | ||
229 | * Revision 1.18 1999/02/24 09:54:33 achim | ||
230 | * Command line parameter hdr_channel implemented | ||
231 | * Bugfix for EISA controllers + Linux 2.2.x | ||
232 | * | ||
233 | * Revision 1.17 1998/12/17 15:58:11 achim | ||
234 | * Command line parameters implemented | ||
235 | * Changes for Alpha platforms | ||
236 | * PCI controller scan changed | ||
237 | * SMP support improved (spin_lock_irqsave(),...) | ||
238 | * New async. events, new scan/reserve commands included | ||
239 | * | ||
240 | * Revision 1.16 1998/09/28 16:08:46 achim | ||
241 | * GDT_PCIMPR: DPMEM remapping, if required | ||
242 | * mdelay() added | ||
243 | * | ||
244 | * Revision 1.15 1998/06/03 14:54:06 achim | ||
245 | * gdth_delay(), gdth_flush() implemented | ||
246 | * Bugfix: gdth_release() changed | ||
247 | * | ||
248 | * Revision 1.14 1998/05/22 10:01:17 achim | ||
249 | * mj: pcibios_strerror() removed | ||
250 | * Improved SMP support (if version >= 2.1.95) | ||
251 | * gdth_halt(): halt_called flag added (if version < 2.1) | ||
252 | * | ||
253 | * Revision 1.13 1998/04/16 09:14:57 achim | ||
254 | * Reserve drives (for raw service) implemented | ||
255 | * New error handling code enabled | ||
256 | * Get controller name from board_info() IOCTL | ||
257 | * Final round of PCI device driver patches by Martin Mares | ||
258 | * | ||
259 | * Revision 1.12 1998/03/03 09:32:37 achim | ||
260 | * Fibre channel controller support added | ||
261 | * | ||
262 | * Revision 1.11 1998/01/27 16:19:14 achim | ||
263 | * SA_SHIRQ added | ||
264 | * add_timer()/del_timer() instead of GDTH_TIMER | ||
265 | * scsi_add_timer()/scsi_del_timer() instead of SCSI_TIMER | ||
266 | * New error handling included | ||
267 | * | ||
268 | * Revision 1.10 1997/10/31 12:29:57 achim | ||
269 | * Read heads/sectors from host drive | ||
270 | * | ||
271 | * Revision 1.9 1997/09/04 10:07:25 achim | ||
272 | * IO-mapping with virt_to_bus(), gdth_readb(), gdth_writeb(), ... | ||
273 | * register_reboot_notifier() to get a notify on shutown used | ||
274 | * | ||
275 | * Revision 1.8 1997/04/02 12:14:30 achim | ||
276 | * Version 1.00 (see gdth.h), tested with kernel 2.0.29 | ||
277 | * | ||
278 | * Revision 1.7 1997/03/12 13:33:37 achim | ||
279 | * gdth_reset() changed, new async. events | ||
280 | * | ||
281 | * Revision 1.6 1997/03/04 14:01:11 achim | ||
282 | * Shutdown routine gdth_halt() implemented | ||
283 | * | ||
284 | * Revision 1.5 1997/02/21 09:08:36 achim | ||
285 | * New controller included (RP, RP1, RP2 series) | ||
286 | * IOCTL interface implemented | ||
287 | * | ||
288 | * Revision 1.4 1996/07/05 12:48:55 achim | ||
289 | * Function gdth_bios_param() implemented | ||
290 | * New constant GDTH_MAXC_P_L inserted | ||
291 | * GDT_WRITE_THR, GDT_EXT_INFO implemented | ||
292 | * Function gdth_reset() changed | ||
293 | * | ||
294 | * Revision 1.3 1996/05/10 09:04:41 achim | ||
295 | * Small changes for Linux 1.2.13 | ||
296 | * | ||
297 | * Revision 1.2 1996/05/09 12:45:27 achim | ||
298 | * Loadable module support implemented | ||
299 | * /proc support corrections made | ||
300 | * | ||
301 | * Revision 1.1 1996/04/11 07:35:57 achim | ||
302 | * Initial revision | ||
303 | * | ||
304 | ************************************************************************/ | 32 | ************************************************************************/ |
305 | 33 | ||
306 | /* All GDT Disk Array Controllers are fully supported by this driver. | 34 | /* All GDT Disk Array Controllers are fully supported by this driver. |
@@ -328,8 +56,6 @@ | |||
328 | * max_ids:x x - target ID count per channel (1..MAXID) | 56 | * max_ids:x x - target ID count per channel (1..MAXID) |
329 | * rescan:Y rescan all channels/IDs | 57 | * rescan:Y rescan all channels/IDs |
330 | * rescan:N use all devices found until now | 58 | * rescan:N use all devices found until now |
331 | * virt_ctr:Y map every channel to a virtual controller | ||
332 | * virt_ctr:N use multi channel support | ||
333 | * hdr_channel:x x - number of virtual bus for host drives | 59 | * hdr_channel:x x - number of virtual bus for host drives |
334 | * shared_access:Y disable driver reserve/release protocol to | 60 | * shared_access:Y disable driver reserve/release protocol to |
335 | * access a shared resource from several nodes, | 61 | * access a shared resource from several nodes, |
@@ -341,7 +67,7 @@ | |||
341 | * force_dma32:N use 64 bit DMA mode, if supported | 67 | * force_dma32:N use 64 bit DMA mode, if supported |
342 | * | 68 | * |
343 | * The default values are: "gdth=disable:N,reserve_mode:1,reverse_scan:N, | 69 | * The default values are: "gdth=disable:N,reserve_mode:1,reverse_scan:N, |
344 | * max_ids:127,rescan:N,virt_ctr:N,hdr_channel:0, | 70 | * max_ids:127,rescan:N,hdr_channel:0, |
345 | * shared_access:Y,probe_eisa_isa:N,force_dma32:N". | 71 | * shared_access:Y,probe_eisa_isa:N,force_dma32:N". |
346 | * Here is another example: "gdth=reserve_list:0,1,2,0,0,1,3,0,rescan:Y". | 72 | * Here is another example: "gdth=reserve_list:0,1,2,0,0,1,3,0,rescan:Y". |
347 | * | 73 | * |
@@ -352,22 +78,22 @@ | |||
352 | * '1' in place of 'Y' and '0' in place of 'N'. | 78 | * '1' in place of 'Y' and '0' in place of 'N'. |
353 | * | 79 | * |
354 | * Default: "modprobe gdth disable=0 reserve_mode=1 reverse_scan=0 | 80 | * Default: "modprobe gdth disable=0 reserve_mode=1 reverse_scan=0 |
355 | * max_ids=127 rescan=0 virt_ctr=0 hdr_channel=0 shared_access=0 | 81 | * max_ids=127 rescan=0 hdr_channel=0 shared_access=0 |
356 | * probe_eisa_isa=0 force_dma32=0" | 82 | * probe_eisa_isa=0 force_dma32=0" |
357 | * The other example: "modprobe gdth reserve_list=0,1,2,0,0,1,3,0 rescan=1". | 83 | * The other example: "modprobe gdth reserve_list=0,1,2,0,0,1,3,0 rescan=1". |
358 | */ | 84 | */ |
359 | 85 | ||
360 | /* The meaning of the Scsi_Pointer members in this driver is as follows: | 86 | /* The meaning of the Scsi_Pointer members in this driver is as follows: |
361 | * ptr: Chaining | 87 | * ptr: Chaining |
362 | * this_residual: Command priority | 88 | * this_residual: gdth_bufflen |
363 | * buffer: phys. DMA sense buffer | 89 | * buffer: gdth_sglist |
364 | * dma_handle: phys. DMA buffer (kernel >= 2.4.0) | 90 | * dma_handle: unused |
365 | * buffers_residual: Timeout value | 91 | * buffers_residual: gdth_sg_count |
366 | * Status: Command status (gdth_do_cmd()), DMA mem. mappings | 92 | * Status: unused |
367 | * Message: Additional info (gdth_do_cmd()), DMA direction | 93 | * Message: unused |
368 | * have_data_in: Flag for gdth_wait_completion() | 94 | * have_data_in: unused |
369 | * sent_command: Opcode special command | 95 | * sent_command: unused |
370 | * phase: Service/parameter/return code special command | 96 | * phase: unused |
371 | */ | 97 | */ |
372 | 98 | ||
373 | 99 | ||
@@ -392,12 +118,8 @@ | |||
392 | #include <linux/proc_fs.h> | 118 | #include <linux/proc_fs.h> |
393 | #include <linux/time.h> | 119 | #include <linux/time.h> |
394 | #include <linux/timer.h> | 120 | #include <linux/timer.h> |
395 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,6) | ||
396 | #include <linux/dma-mapping.h> | 121 | #include <linux/dma-mapping.h> |
397 | #else | 122 | #include <linux/list.h> |
398 | #define DMA_32BIT_MASK 0x00000000ffffffffULL | ||
399 | #define DMA_64BIT_MASK 0xffffffffffffffffULL | ||
400 | #endif | ||
401 | 123 | ||
402 | #ifdef GDTH_RTC | 124 | #ifdef GDTH_RTC |
403 | #include <linux/mc146818rtc.h> | 125 | #include <linux/mc146818rtc.h> |
@@ -409,29 +131,27 @@ | |||
409 | #include <asm/io.h> | 131 | #include <asm/io.h> |
410 | #include <asm/uaccess.h> | 132 | #include <asm/uaccess.h> |
411 | #include <linux/spinlock.h> | 133 | #include <linux/spinlock.h> |
412 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) | ||
413 | #include <linux/blkdev.h> | 134 | #include <linux/blkdev.h> |
414 | #else | 135 | #include <linux/scatterlist.h> |
415 | #include <linux/blk.h> | ||
416 | #include "sd.h" | ||
417 | #endif | ||
418 | 136 | ||
419 | #include "scsi.h" | 137 | #include "scsi.h" |
420 | #include <scsi/scsi_host.h> | 138 | #include <scsi/scsi_host.h> |
421 | #include "gdth_kcompat.h" | ||
422 | #include "gdth.h" | 139 | #include "gdth.h" |
423 | 140 | ||
424 | static void gdth_delay(int milliseconds); | 141 | static void gdth_delay(int milliseconds); |
425 | static void gdth_eval_mapping(ulong32 size, ulong32 *cyls, int *heads, int *secs); | 142 | static void gdth_eval_mapping(ulong32 size, ulong32 *cyls, int *heads, int *secs); |
426 | static irqreturn_t gdth_interrupt(int irq, void *dev_id); | 143 | static irqreturn_t gdth_interrupt(int irq, void *dev_id); |
427 | static int gdth_sync_event(int hanum,int service,unchar index,Scsi_Cmnd *scp); | 144 | static irqreturn_t __gdth_interrupt(gdth_ha_str *ha, int irq, |
428 | static int gdth_async_event(int hanum); | 145 | int gdth_from_wait, int* pIndex); |
146 | static int gdth_sync_event(gdth_ha_str *ha, int service, unchar index, | ||
147 | Scsi_Cmnd *scp); | ||
148 | static int gdth_async_event(gdth_ha_str *ha); | ||
429 | static void gdth_log_event(gdth_evt_data *dvr, char *buffer); | 149 | static void gdth_log_event(gdth_evt_data *dvr, char *buffer); |
430 | 150 | ||
431 | static void gdth_putq(int hanum,Scsi_Cmnd *scp,unchar priority); | 151 | static void gdth_putq(gdth_ha_str *ha, Scsi_Cmnd *scp, unchar priority); |
432 | static void gdth_next(int hanum); | 152 | static void gdth_next(gdth_ha_str *ha); |
433 | static int gdth_fill_raw_cmd(int hanum,Scsi_Cmnd *scp,unchar b); | 153 | static int gdth_fill_raw_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp, unchar b); |
434 | static int gdth_special_cmd(int hanum,Scsi_Cmnd *scp); | 154 | static int gdth_special_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp); |
435 | static gdth_evt_str *gdth_store_event(gdth_ha_str *ha, ushort source, | 155 | static gdth_evt_str *gdth_store_event(gdth_ha_str *ha, ushort source, |
436 | ushort idx, gdth_evt_data *evt); | 156 | ushort idx, gdth_evt_data *evt); |
437 | static int gdth_read_event(gdth_ha_str *ha, int handle, gdth_evt_str *estr); | 157 | static int gdth_read_event(gdth_ha_str *ha, int handle, gdth_evt_str *estr); |
@@ -439,42 +159,34 @@ static void gdth_readapp_event(gdth_ha_str *ha, unchar application, | |||
439 | gdth_evt_str *estr); | 159 | gdth_evt_str *estr); |
440 | static void gdth_clear_events(void); | 160 | static void gdth_clear_events(void); |
441 | 161 | ||
442 | static void gdth_copy_internal_data(int hanum,Scsi_Cmnd *scp, | 162 | static void gdth_copy_internal_data(gdth_ha_str *ha, Scsi_Cmnd *scp, |
443 | char *buffer,ushort count); | 163 | char *buffer, ushort count, int to_buffer); |
444 | static int gdth_internal_cache_cmd(int hanum,Scsi_Cmnd *scp); | 164 | static int gdth_internal_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp); |
445 | static int gdth_fill_cache_cmd(int hanum,Scsi_Cmnd *scp,ushort hdrive); | 165 | static int gdth_fill_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp, ushort hdrive); |
446 | 166 | ||
447 | static int gdth_search_eisa(ushort eisa_adr); | 167 | static void gdth_enable_int(gdth_ha_str *ha); |
448 | static int gdth_search_isa(ulong32 bios_adr); | 168 | static unchar gdth_get_status(gdth_ha_str *ha, int irq); |
449 | static int gdth_search_pci(gdth_pci_str *pcistr); | 169 | static int gdth_test_busy(gdth_ha_str *ha); |
450 | static void gdth_search_dev(gdth_pci_str *pcistr, ushort *cnt, | 170 | static int gdth_get_cmd_index(gdth_ha_str *ha); |
451 | ushort vendor, ushort dev); | 171 | static void gdth_release_event(gdth_ha_str *ha); |
452 | static void gdth_sort_pci(gdth_pci_str *pcistr, int cnt); | 172 | static int gdth_wait(gdth_ha_str *ha, int index,ulong32 time); |
453 | static int gdth_init_eisa(ushort eisa_adr,gdth_ha_str *ha); | 173 | static int gdth_internal_cmd(gdth_ha_str *ha, unchar service, ushort opcode, |
454 | static int gdth_init_isa(ulong32 bios_adr,gdth_ha_str *ha); | 174 | ulong32 p1, ulong64 p2,ulong64 p3); |
455 | static int gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha); | 175 | static int gdth_search_drives(gdth_ha_str *ha); |
456 | 176 | static int gdth_analyse_hdrive(gdth_ha_str *ha, ushort hdrive); | |
457 | static void gdth_enable_int(int hanum); | 177 | |
458 | static int gdth_get_status(unchar *pIStatus,int irq); | 178 | static const char *gdth_ctr_name(gdth_ha_str *ha); |
459 | static int gdth_test_busy(int hanum); | ||
460 | static int gdth_get_cmd_index(int hanum); | ||
461 | static void gdth_release_event(int hanum); | ||
462 | static int gdth_wait(int hanum,int index,ulong32 time); | ||
463 | static int gdth_internal_cmd(int hanum,unchar service,ushort opcode,ulong32 p1, | ||
464 | ulong64 p2,ulong64 p3); | ||
465 | static int gdth_search_drives(int hanum); | ||
466 | static int gdth_analyse_hdrive(int hanum, ushort hdrive); | ||
467 | |||
468 | static const char *gdth_ctr_name(int hanum); | ||
469 | 179 | ||
470 | static int gdth_open(struct inode *inode, struct file *filep); | 180 | static int gdth_open(struct inode *inode, struct file *filep); |
471 | static int gdth_close(struct inode *inode, struct file *filep); | 181 | static int gdth_close(struct inode *inode, struct file *filep); |
472 | static int gdth_ioctl(struct inode *inode, struct file *filep, | 182 | static int gdth_ioctl(struct inode *inode, struct file *filep, |
473 | unsigned int cmd, unsigned long arg); | 183 | unsigned int cmd, unsigned long arg); |
474 | 184 | ||
475 | static void gdth_flush(int hanum); | 185 | static void gdth_flush(gdth_ha_str *ha); |
476 | static int gdth_halt(struct notifier_block *nb, ulong event, void *buf); | 186 | static int gdth_halt(struct notifier_block *nb, ulong event, void *buf); |
477 | static int gdth_queuecommand(Scsi_Cmnd *scp,void (*done)(Scsi_Cmnd *)); | 187 | static int gdth_queuecommand(Scsi_Cmnd *scp,void (*done)(Scsi_Cmnd *)); |
188 | static int __gdth_queuecommand(gdth_ha_str *ha, struct scsi_cmnd *scp, | ||
189 | struct gdth_cmndinfo *cmndinfo); | ||
478 | static void gdth_scsi_done(struct scsi_cmnd *scp); | 190 | static void gdth_scsi_done(struct scsi_cmnd *scp); |
479 | 191 | ||
480 | #ifdef DEBUG_GDTH | 192 | #ifdef DEBUG_GDTH |
@@ -571,29 +283,17 @@ static struct timer_list gdth_timer; | |||
571 | #define GDTOFFSOF(a,b) (size_t)&(((a*)0)->b) | 283 | #define GDTOFFSOF(a,b) (size_t)&(((a*)0)->b) |
572 | #define INDEX_OK(i,t) ((i)<ARRAY_SIZE(t)) | 284 | #define INDEX_OK(i,t) ((i)<ARRAY_SIZE(t)) |
573 | 285 | ||
574 | #define NUMDATA(a) ( (gdth_num_str *)((a)->hostdata)) | ||
575 | #define HADATA(a) (&((gdth_ext_str *)((a)->hostdata))->haext) | ||
576 | #define CMDDATA(a) (&((gdth_ext_str *)((a)->hostdata))->cmdext) | ||
577 | |||
578 | #define BUS_L2P(a,b) ((b)>(a)->virt_bus ? (b-1):(b)) | 286 | #define BUS_L2P(a,b) ((b)>(a)->virt_bus ? (b-1):(b)) |
579 | 287 | ||
580 | #define gdth_readb(addr) readb(addr) | 288 | #ifdef CONFIG_ISA |
581 | #define gdth_readw(addr) readw(addr) | ||
582 | #define gdth_readl(addr) readl(addr) | ||
583 | #define gdth_writeb(b,addr) writeb((b),(addr)) | ||
584 | #define gdth_writew(b,addr) writew((b),(addr)) | ||
585 | #define gdth_writel(b,addr) writel((b),(addr)) | ||
586 | |||
587 | static unchar gdth_drq_tab[4] = {5,6,7,7}; /* DRQ table */ | 289 | static unchar gdth_drq_tab[4] = {5,6,7,7}; /* DRQ table */ |
290 | #endif | ||
291 | #if defined(CONFIG_EISA) || defined(CONFIG_ISA) | ||
588 | static unchar gdth_irq_tab[6] = {0,10,11,12,14,0}; /* IRQ table */ | 292 | static unchar gdth_irq_tab[6] = {0,10,11,12,14,0}; /* IRQ table */ |
293 | #endif | ||
589 | static unchar gdth_polling; /* polling if TRUE */ | 294 | static unchar gdth_polling; /* polling if TRUE */ |
590 | static unchar gdth_from_wait = FALSE; /* gdth_wait() */ | ||
591 | static int wait_index,wait_hanum; /* gdth_wait() */ | ||
592 | static int gdth_ctr_count = 0; /* controller count */ | 295 | static int gdth_ctr_count = 0; /* controller count */ |
593 | static int gdth_ctr_vcount = 0; /* virt. ctr. count */ | 296 | static LIST_HEAD(gdth_instances); /* controller list */ |
594 | static int gdth_ctr_released = 0; /* gdth_release() */ | ||
595 | static struct Scsi_Host *gdth_ctr_tab[MAXHA]; /* controller table */ | ||
596 | static struct Scsi_Host *gdth_ctr_vtab[MAXHA*MAXBUS]; /* virt. ctr. table */ | ||
597 | static unchar gdth_write_through = FALSE; /* write through */ | 297 | static unchar gdth_write_through = FALSE; /* write through */ |
598 | static gdth_evt_str ebuffer[MAX_EVENTS]; /* event buffer */ | 298 | static gdth_evt_str ebuffer[MAX_EVENTS]; /* event buffer */ |
599 | static int elastidx; | 299 | static int elastidx; |
@@ -645,8 +345,6 @@ static int hdr_channel = 0; | |||
645 | static int max_ids = MAXID; | 345 | static int max_ids = MAXID; |
646 | /* rescan all IDs */ | 346 | /* rescan all IDs */ |
647 | static int rescan = 0; | 347 | static int rescan = 0; |
648 | /* map channels to virtual controllers */ | ||
649 | static int virt_ctr = 0; | ||
650 | /* shared access */ | 348 | /* shared access */ |
651 | static int shared_access = 1; | 349 | static int shared_access = 1; |
652 | /* enable support for EISA and ISA controllers */ | 350 | /* enable support for EISA and ISA controllers */ |
@@ -655,7 +353,6 @@ static int probe_eisa_isa = 0; | |||
655 | static int force_dma32 = 0; | 353 | static int force_dma32 = 0; |
656 | 354 | ||
657 | /* parameters for modprobe/insmod */ | 355 | /* parameters for modprobe/insmod */ |
658 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,11) | ||
659 | module_param_array(irq, int, NULL, 0); | 356 | module_param_array(irq, int, NULL, 0); |
660 | module_param(disable, int, 0); | 357 | module_param(disable, int, 0); |
661 | module_param(reserve_mode, int, 0); | 358 | module_param(reserve_mode, int, 0); |
@@ -664,24 +361,9 @@ module_param(reverse_scan, int, 0); | |||
664 | module_param(hdr_channel, int, 0); | 361 | module_param(hdr_channel, int, 0); |
665 | module_param(max_ids, int, 0); | 362 | module_param(max_ids, int, 0); |
666 | module_param(rescan, int, 0); | 363 | module_param(rescan, int, 0); |
667 | module_param(virt_ctr, int, 0); | ||
668 | module_param(shared_access, int, 0); | 364 | module_param(shared_access, int, 0); |
669 | module_param(probe_eisa_isa, int, 0); | 365 | module_param(probe_eisa_isa, int, 0); |
670 | module_param(force_dma32, int, 0); | 366 | module_param(force_dma32, int, 0); |
671 | #else | ||
672 | MODULE_PARM(irq, "i"); | ||
673 | MODULE_PARM(disable, "i"); | ||
674 | MODULE_PARM(reserve_mode, "i"); | ||
675 | MODULE_PARM(reserve_list, "4-" __MODULE_STRING(MAX_RES_ARGS) "i"); | ||
676 | MODULE_PARM(reverse_scan, "i"); | ||
677 | MODULE_PARM(hdr_channel, "i"); | ||
678 | MODULE_PARM(max_ids, "i"); | ||
679 | MODULE_PARM(rescan, "i"); | ||
680 | MODULE_PARM(virt_ctr, "i"); | ||
681 | MODULE_PARM(shared_access, "i"); | ||
682 | MODULE_PARM(probe_eisa_isa, "i"); | ||
683 | MODULE_PARM(force_dma32, "i"); | ||
684 | #endif | ||
685 | MODULE_AUTHOR("Achim Leubner"); | 367 | MODULE_AUTHOR("Achim Leubner"); |
686 | MODULE_LICENSE("GPL"); | 368 | MODULE_LICENSE("GPL"); |
687 | 369 | ||
@@ -692,6 +374,47 @@ static const struct file_operations gdth_fops = { | |||
692 | .release = gdth_close, | 374 | .release = gdth_close, |
693 | }; | 375 | }; |
694 | 376 | ||
377 | /* | ||
378 | * gdth scsi_command access wrappers. | ||
379 | * below 6 functions are used throughout the driver to access scsi_command's | ||
380 | * io parameters. The reason we do not use the regular accessors from | ||
381 | * scsi_cmnd.h is because of gdth_execute(). Since it is unrecommended for | ||
382 | * llds to directly set scsi_cmnd's IO members. This driver will use SCp | ||
383 | * members for IO parameters, and will copy scsi_cmnd's members to Scp | ||
384 | * members in queuecommand. For internal commands through gdth_execute() | ||
385 | * SCp's members will be set directly. | ||
386 | */ | ||
387 | static inline unsigned gdth_bufflen(struct scsi_cmnd *cmd) | ||
388 | { | ||
389 | return (unsigned)cmd->SCp.this_residual; | ||
390 | } | ||
391 | |||
392 | static inline void gdth_set_bufflen(struct scsi_cmnd *cmd, unsigned bufflen) | ||
393 | { | ||
394 | cmd->SCp.this_residual = bufflen; | ||
395 | } | ||
396 | |||
397 | static inline unsigned gdth_sg_count(struct scsi_cmnd *cmd) | ||
398 | { | ||
399 | return (unsigned)cmd->SCp.buffers_residual; | ||
400 | } | ||
401 | |||
402 | static inline void gdth_set_sg_count(struct scsi_cmnd *cmd, unsigned sg_count) | ||
403 | { | ||
404 | cmd->SCp.buffers_residual = sg_count; | ||
405 | } | ||
406 | |||
407 | static inline struct scatterlist *gdth_sglist(struct scsi_cmnd *cmd) | ||
408 | { | ||
409 | return cmd->SCp.buffer; | ||
410 | } | ||
411 | |||
412 | static inline void gdth_set_sglist(struct scsi_cmnd *cmd, | ||
413 | struct scatterlist *sglist) | ||
414 | { | ||
415 | cmd->SCp.buffer = sglist; | ||
416 | } | ||
417 | |||
695 | #include "gdth_proc.h" | 418 | #include "gdth_proc.h" |
696 | #include "gdth_proc.c" | 419 | #include "gdth_proc.c" |
697 | 420 | ||
@@ -701,6 +424,45 @@ static struct notifier_block gdth_notifier = { | |||
701 | }; | 424 | }; |
702 | static int notifier_disabled = 0; | 425 | static int notifier_disabled = 0; |
703 | 426 | ||
427 | static gdth_ha_str *gdth_find_ha(int hanum) | ||
428 | { | ||
429 | gdth_ha_str *ha; | ||
430 | |||
431 | list_for_each_entry(ha, &gdth_instances, list) | ||
432 | if (hanum == ha->hanum) | ||
433 | return ha; | ||
434 | |||
435 | return NULL; | ||
436 | } | ||
437 | |||
438 | static struct gdth_cmndinfo *gdth_get_cmndinfo(gdth_ha_str *ha) | ||
439 | { | ||
440 | struct gdth_cmndinfo *priv = NULL; | ||
441 | ulong flags; | ||
442 | int i; | ||
443 | |||
444 | spin_lock_irqsave(&ha->smp_lock, flags); | ||
445 | |||
446 | for (i=0; i<GDTH_MAXCMDS; ++i) { | ||
447 | if (ha->cmndinfo[i].index == 0) { | ||
448 | priv = &ha->cmndinfo[i]; | ||
449 | priv->index = i+1; | ||
450 | memset(priv, 0, sizeof(*priv)); | ||
451 | break; | ||
452 | } | ||
453 | } | ||
454 | |||
455 | spin_unlock_irqrestore(&ha->smp_lock, flags); | ||
456 | |||
457 | return priv; | ||
458 | } | ||
459 | |||
460 | static void gdth_put_cmndinfo(struct gdth_cmndinfo *priv) | ||
461 | { | ||
462 | BUG_ON(!priv); | ||
463 | priv->index = 0; | ||
464 | } | ||
465 | |||
704 | static void gdth_delay(int milliseconds) | 466 | static void gdth_delay(int milliseconds) |
705 | { | 467 | { |
706 | if (milliseconds == 0) { | 468 | if (milliseconds == 0) { |
@@ -710,80 +472,62 @@ static void gdth_delay(int milliseconds) | |||
710 | } | 472 | } |
711 | } | 473 | } |
712 | 474 | ||
713 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) | ||
714 | static void gdth_scsi_done(struct scsi_cmnd *scp) | 475 | static void gdth_scsi_done(struct scsi_cmnd *scp) |
715 | { | 476 | { |
716 | TRACE2(("gdth_scsi_done()\n")); | 477 | struct gdth_cmndinfo *cmndinfo = gdth_cmnd_priv(scp); |
478 | int internal_command = cmndinfo->internal_command; | ||
479 | |||
480 | TRACE2(("gdth_scsi_done()\n")); | ||
481 | |||
482 | gdth_put_cmndinfo(cmndinfo); | ||
483 | scp->host_scribble = NULL; | ||
717 | 484 | ||
718 | if (scp->request) | 485 | if (internal_command) |
719 | complete((struct completion *)scp->request); | 486 | complete((struct completion *)scp->request); |
487 | else | ||
488 | scp->scsi_done(scp); | ||
720 | } | 489 | } |
721 | 490 | ||
722 | int __gdth_execute(struct scsi_device *sdev, gdth_cmd_str *gdtcmd, char *cmnd, | 491 | int __gdth_execute(struct scsi_device *sdev, gdth_cmd_str *gdtcmd, char *cmnd, |
723 | int timeout, u32 *info) | 492 | int timeout, u32 *info) |
724 | { | 493 | { |
494 | gdth_ha_str *ha = shost_priv(sdev->host); | ||
725 | Scsi_Cmnd *scp; | 495 | Scsi_Cmnd *scp; |
496 | struct gdth_cmndinfo cmndinfo; | ||
497 | struct scatterlist one_sg; | ||
726 | DECLARE_COMPLETION_ONSTACK(wait); | 498 | DECLARE_COMPLETION_ONSTACK(wait); |
727 | int rval; | 499 | int rval; |
728 | 500 | ||
729 | scp = kmalloc(sizeof(*scp), GFP_KERNEL); | 501 | scp = kzalloc(sizeof(*scp), GFP_KERNEL); |
730 | if (!scp) | 502 | if (!scp) |
731 | return -ENOMEM; | 503 | return -ENOMEM; |
732 | memset(scp, 0, sizeof(*scp)); | 504 | |
733 | scp->device = sdev; | 505 | scp->device = sdev; |
506 | memset(&cmndinfo, 0, sizeof(cmndinfo)); | ||
507 | |||
734 | /* use request field to save the ptr. to completion struct. */ | 508 | /* use request field to save the ptr. to completion struct. */ |
735 | scp->request = (struct request *)&wait; | 509 | scp->request = (struct request *)&wait; |
736 | scp->timeout_per_command = timeout*HZ; | 510 | scp->timeout_per_command = timeout*HZ; |
737 | scp->request_buffer = gdtcmd; | 511 | sg_init_one(&one_sg, gdtcmd, sizeof(*gdtcmd)); |
512 | gdth_set_sglist(scp, &one_sg); | ||
513 | gdth_set_sg_count(scp, 1); | ||
514 | gdth_set_bufflen(scp, sizeof(*gdtcmd)); | ||
738 | scp->cmd_len = 12; | 515 | scp->cmd_len = 12; |
739 | memcpy(scp->cmnd, cmnd, 12); | 516 | memcpy(scp->cmnd, cmnd, 12); |
740 | scp->SCp.this_residual = IOCTL_PRI; /* priority */ | 517 | cmndinfo.priority = IOCTL_PRI; |
741 | scp->done = gdth_scsi_done; /* some fn. test this */ | 518 | cmndinfo.internal_command = 1; |
742 | gdth_queuecommand(scp, gdth_scsi_done); | ||
743 | wait_for_completion(&wait); | ||
744 | |||
745 | rval = scp->SCp.Status; | ||
746 | if (info) | ||
747 | *info = scp->SCp.Message; | ||
748 | kfree(scp); | ||
749 | return rval; | ||
750 | } | ||
751 | #else | ||
752 | static void gdth_scsi_done(Scsi_Cmnd *scp) | ||
753 | { | ||
754 | TRACE2(("gdth_scsi_done()\n")); | ||
755 | |||
756 | scp->request.rq_status = RQ_SCSI_DONE; | ||
757 | if (scp->request.waiting) | ||
758 | complete(scp->request.waiting); | ||
759 | } | ||
760 | 519 | ||
761 | int __gdth_execute(struct scsi_device *sdev, gdth_cmd_str *gdtcmd, char *cmnd, | 520 | TRACE(("__gdth_execute() cmd 0x%x\n", scp->cmnd[0])); |
762 | int timeout, u32 *info) | 521 | __gdth_queuecommand(ha, scp, &cmndinfo); |
763 | { | ||
764 | Scsi_Cmnd *scp = scsi_allocate_device(sdev, 1, FALSE); | ||
765 | unsigned bufflen = gdtcmd ? sizeof(gdth_cmd_str) : 0; | ||
766 | DECLARE_COMPLETION_ONSTACK(wait); | ||
767 | int rval; | ||
768 | 522 | ||
769 | if (!scp) | ||
770 | return -ENOMEM; | ||
771 | scp->cmd_len = 12; | ||
772 | scp->use_sg = 0; | ||
773 | scp->SCp.this_residual = IOCTL_PRI; /* priority */ | ||
774 | scp->request.rq_status = RQ_SCSI_BUSY; | ||
775 | scp->request.waiting = &wait; | ||
776 | scsi_do_cmd(scp, cmnd, gdtcmd, bufflen, gdth_scsi_done, timeout*HZ, 1); | ||
777 | wait_for_completion(&wait); | 523 | wait_for_completion(&wait); |
778 | 524 | ||
779 | rval = scp->SCp.Status; | 525 | rval = cmndinfo.status; |
780 | if (info) | 526 | if (info) |
781 | *info = scp->SCp.Message; | 527 | *info = cmndinfo.info; |
782 | 528 | kfree(scp); | |
783 | scsi_release_command(scp); | ||
784 | return rval; | 529 | return rval; |
785 | } | 530 | } |
786 | #endif | ||
787 | 531 | ||
788 | int gdth_execute(struct Scsi_Host *shost, gdth_cmd_str *gdtcmd, char *cmnd, | 532 | int gdth_execute(struct Scsi_Host *shost, gdth_cmd_str *gdtcmd, char *cmnd, |
789 | int timeout, u32 *info) | 533 | int timeout, u32 *info) |
@@ -815,7 +559,7 @@ static void gdth_eval_mapping(ulong32 size, ulong32 *cyls, int *heads, int *secs | |||
815 | } | 559 | } |
816 | 560 | ||
817 | /* controller search and initialization functions */ | 561 | /* controller search and initialization functions */ |
818 | 562 | #ifdef CONFIG_EISA | |
819 | static int __init gdth_search_eisa(ushort eisa_adr) | 563 | static int __init gdth_search_eisa(ushort eisa_adr) |
820 | { | 564 | { |
821 | ulong32 id; | 565 | ulong32 id; |
@@ -832,8 +576,9 @@ static int __init gdth_search_eisa(ushort eisa_adr) | |||
832 | 576 | ||
833 | return 0; | 577 | return 0; |
834 | } | 578 | } |
579 | #endif /* CONFIG_EISA */ | ||
835 | 580 | ||
836 | 581 | #ifdef CONFIG_ISA | |
837 | static int __init gdth_search_isa(ulong32 bios_adr) | 582 | static int __init gdth_search_isa(ulong32 bios_adr) |
838 | { | 583 | { |
839 | void __iomem *addr; | 584 | void __iomem *addr; |
@@ -841,14 +586,18 @@ static int __init gdth_search_isa(ulong32 bios_adr) | |||
841 | 586 | ||
842 | TRACE(("gdth_search_isa() bios adr. %x\n",bios_adr)); | 587 | TRACE(("gdth_search_isa() bios adr. %x\n",bios_adr)); |
843 | if ((addr = ioremap(bios_adr+BIOS_ID_OFFS, sizeof(ulong32))) != NULL) { | 588 | if ((addr = ioremap(bios_adr+BIOS_ID_OFFS, sizeof(ulong32))) != NULL) { |
844 | id = gdth_readl(addr); | 589 | id = readl(addr); |
845 | iounmap(addr); | 590 | iounmap(addr); |
846 | if (id == GDT2_ID) /* GDT2000 */ | 591 | if (id == GDT2_ID) /* GDT2000 */ |
847 | return 1; | 592 | return 1; |
848 | } | 593 | } |
849 | return 0; | 594 | return 0; |
850 | } | 595 | } |
596 | #endif /* CONFIG_ISA */ | ||
851 | 597 | ||
598 | #ifdef CONFIG_PCI | ||
599 | static void gdth_search_dev(gdth_pci_str *pcistr, ushort *cnt, | ||
600 | ushort vendor, ushort dev); | ||
852 | 601 | ||
853 | static int __init gdth_search_pci(gdth_pci_str *pcistr) | 602 | static int __init gdth_search_pci(gdth_pci_str *pcistr) |
854 | { | 603 | { |
@@ -928,7 +677,6 @@ static void __init gdth_search_dev(gdth_pci_str *pcistr, ushort *cnt, | |||
928 | } | 677 | } |
929 | } | 678 | } |
930 | 679 | ||
931 | |||
932 | static void __init gdth_sort_pci(gdth_pci_str *pcistr, int cnt) | 680 | static void __init gdth_sort_pci(gdth_pci_str *pcistr, int cnt) |
933 | { | 681 | { |
934 | gdth_pci_str temp; | 682 | gdth_pci_str temp; |
@@ -965,8 +713,9 @@ static void __init gdth_sort_pci(gdth_pci_str *pcistr, int cnt) | |||
965 | } | 713 | } |
966 | } while (changed); | 714 | } while (changed); |
967 | } | 715 | } |
716 | #endif /* CONFIG_PCI */ | ||
968 | 717 | ||
969 | 718 | #ifdef CONFIG_EISA | |
970 | static int __init gdth_init_eisa(ushort eisa_adr,gdth_ha_str *ha) | 719 | static int __init gdth_init_eisa(ushort eisa_adr,gdth_ha_str *ha) |
971 | { | 720 | { |
972 | ulong32 retries,id; | 721 | ulong32 retries,id; |
@@ -1058,8 +807,9 @@ static int __init gdth_init_eisa(ushort eisa_adr,gdth_ha_str *ha) | |||
1058 | ha->dma64_support = 0; | 807 | ha->dma64_support = 0; |
1059 | return 1; | 808 | return 1; |
1060 | } | 809 | } |
810 | #endif /* CONFIG_EISA */ | ||
1061 | 811 | ||
1062 | 812 | #ifdef CONFIG_ISA | |
1063 | static int __init gdth_init_isa(ulong32 bios_adr,gdth_ha_str *ha) | 813 | static int __init gdth_init_isa(ulong32 bios_adr,gdth_ha_str *ha) |
1064 | { | 814 | { |
1065 | register gdt2_dpram_str __iomem *dp2_ptr; | 815 | register gdt2_dpram_str __iomem *dp2_ptr; |
@@ -1075,22 +825,22 @@ static int __init gdth_init_isa(ulong32 bios_adr,gdth_ha_str *ha) | |||
1075 | return 0; | 825 | return 0; |
1076 | } | 826 | } |
1077 | dp2_ptr = ha->brd; | 827 | dp2_ptr = ha->brd; |
1078 | gdth_writeb(1, &dp2_ptr->io.memlock); /* switch off write protection */ | 828 | writeb(1, &dp2_ptr->io.memlock); /* switch off write protection */ |
1079 | /* reset interface area */ | 829 | /* reset interface area */ |
1080 | memset_io(&dp2_ptr->u, 0, sizeof(dp2_ptr->u)); | 830 | memset_io(&dp2_ptr->u, 0, sizeof(dp2_ptr->u)); |
1081 | if (gdth_readl(&dp2_ptr->u) != 0) { | 831 | if (readl(&dp2_ptr->u) != 0) { |
1082 | printk("GDT-ISA: Initialization error (DPMEM write error)\n"); | 832 | printk("GDT-ISA: Initialization error (DPMEM write error)\n"); |
1083 | iounmap(ha->brd); | 833 | iounmap(ha->brd); |
1084 | return 0; | 834 | return 0; |
1085 | } | 835 | } |
1086 | 836 | ||
1087 | /* disable board interrupts, read DRQ and IRQ */ | 837 | /* disable board interrupts, read DRQ and IRQ */ |
1088 | gdth_writeb(0xff, &dp2_ptr->io.irqdel); | 838 | writeb(0xff, &dp2_ptr->io.irqdel); |
1089 | gdth_writeb(0x00, &dp2_ptr->io.irqen); | 839 | writeb(0x00, &dp2_ptr->io.irqen); |
1090 | gdth_writeb(0x00, &dp2_ptr->u.ic.S_Status); | 840 | writeb(0x00, &dp2_ptr->u.ic.S_Status); |
1091 | gdth_writeb(0x00, &dp2_ptr->u.ic.Cmd_Index); | 841 | writeb(0x00, &dp2_ptr->u.ic.Cmd_Index); |
1092 | 842 | ||
1093 | irq_drq = gdth_readb(&dp2_ptr->io.rq); | 843 | irq_drq = readb(&dp2_ptr->io.rq); |
1094 | for (i=0; i<3; ++i) { | 844 | for (i=0; i<3; ++i) { |
1095 | if ((irq_drq & 1)==0) | 845 | if ((irq_drq & 1)==0) |
1096 | break; | 846 | break; |
@@ -1098,7 +848,7 @@ static int __init gdth_init_isa(ulong32 bios_adr,gdth_ha_str *ha) | |||
1098 | } | 848 | } |
1099 | ha->drq = gdth_drq_tab[i]; | 849 | ha->drq = gdth_drq_tab[i]; |
1100 | 850 | ||
1101 | irq_drq = gdth_readb(&dp2_ptr->io.rq) >> 3; | 851 | irq_drq = readb(&dp2_ptr->io.rq) >> 3; |
1102 | for (i=1; i<5; ++i) { | 852 | for (i=1; i<5; ++i) { |
1103 | if ((irq_drq & 1)==0) | 853 | if ((irq_drq & 1)==0) |
1104 | break; | 854 | break; |
@@ -1107,12 +857,12 @@ static int __init gdth_init_isa(ulong32 bios_adr,gdth_ha_str *ha) | |||
1107 | ha->irq = gdth_irq_tab[i]; | 857 | ha->irq = gdth_irq_tab[i]; |
1108 | 858 | ||
1109 | /* deinitialize services */ | 859 | /* deinitialize services */ |
1110 | gdth_writel(bios_adr, &dp2_ptr->u.ic.S_Info[0]); | 860 | writel(bios_adr, &dp2_ptr->u.ic.S_Info[0]); |
1111 | gdth_writeb(0xff, &dp2_ptr->u.ic.S_Cmd_Indx); | 861 | writeb(0xff, &dp2_ptr->u.ic.S_Cmd_Indx); |
1112 | gdth_writeb(0, &dp2_ptr->io.event); | 862 | writeb(0, &dp2_ptr->io.event); |
1113 | retries = INIT_RETRIES; | 863 | retries = INIT_RETRIES; |
1114 | gdth_delay(20); | 864 | gdth_delay(20); |
1115 | while (gdth_readb(&dp2_ptr->u.ic.S_Status) != 0xff) { | 865 | while (readb(&dp2_ptr->u.ic.S_Status) != 0xff) { |
1116 | if (--retries == 0) { | 866 | if (--retries == 0) { |
1117 | printk("GDT-ISA: Initialization error (DEINIT failed)\n"); | 867 | printk("GDT-ISA: Initialization error (DEINIT failed)\n"); |
1118 | iounmap(ha->brd); | 868 | iounmap(ha->brd); |
@@ -1120,9 +870,9 @@ static int __init gdth_init_isa(ulong32 bios_adr,gdth_ha_str *ha) | |||
1120 | } | 870 | } |
1121 | gdth_delay(1); | 871 | gdth_delay(1); |
1122 | } | 872 | } |
1123 | prot_ver = (unchar)gdth_readl(&dp2_ptr->u.ic.S_Info[0]); | 873 | prot_ver = (unchar)readl(&dp2_ptr->u.ic.S_Info[0]); |
1124 | gdth_writeb(0, &dp2_ptr->u.ic.Status); | 874 | writeb(0, &dp2_ptr->u.ic.Status); |
1125 | gdth_writeb(0xff, &dp2_ptr->io.irqdel); | 875 | writeb(0xff, &dp2_ptr->io.irqdel); |
1126 | if (prot_ver != PROTOCOL_VERSION) { | 876 | if (prot_ver != PROTOCOL_VERSION) { |
1127 | printk("GDT-ISA: Illegal protocol version\n"); | 877 | printk("GDT-ISA: Illegal protocol version\n"); |
1128 | iounmap(ha->brd); | 878 | iounmap(ha->brd); |
@@ -1136,15 +886,15 @@ static int __init gdth_init_isa(ulong32 bios_adr,gdth_ha_str *ha) | |||
1136 | ha->brd_phys = bios_adr >> 4; | 886 | ha->brd_phys = bios_adr >> 4; |
1137 | 887 | ||
1138 | /* special request to controller BIOS */ | 888 | /* special request to controller BIOS */ |
1139 | gdth_writel(0x00, &dp2_ptr->u.ic.S_Info[0]); | 889 | writel(0x00, &dp2_ptr->u.ic.S_Info[0]); |
1140 | gdth_writel(0x00, &dp2_ptr->u.ic.S_Info[1]); | 890 | writel(0x00, &dp2_ptr->u.ic.S_Info[1]); |
1141 | gdth_writel(0x01, &dp2_ptr->u.ic.S_Info[2]); | 891 | writel(0x01, &dp2_ptr->u.ic.S_Info[2]); |
1142 | gdth_writel(0x00, &dp2_ptr->u.ic.S_Info[3]); | 892 | writel(0x00, &dp2_ptr->u.ic.S_Info[3]); |
1143 | gdth_writeb(0xfe, &dp2_ptr->u.ic.S_Cmd_Indx); | 893 | writeb(0xfe, &dp2_ptr->u.ic.S_Cmd_Indx); |
1144 | gdth_writeb(0, &dp2_ptr->io.event); | 894 | writeb(0, &dp2_ptr->io.event); |
1145 | retries = INIT_RETRIES; | 895 | retries = INIT_RETRIES; |
1146 | gdth_delay(20); | 896 | gdth_delay(20); |
1147 | while (gdth_readb(&dp2_ptr->u.ic.S_Status) != 0xfe) { | 897 | while (readb(&dp2_ptr->u.ic.S_Status) != 0xfe) { |
1148 | if (--retries == 0) { | 898 | if (--retries == 0) { |
1149 | printk("GDT-ISA: Initialization error\n"); | 899 | printk("GDT-ISA: Initialization error\n"); |
1150 | iounmap(ha->brd); | 900 | iounmap(ha->brd); |
@@ -1152,14 +902,15 @@ static int __init gdth_init_isa(ulong32 bios_adr,gdth_ha_str *ha) | |||
1152 | } | 902 | } |
1153 | gdth_delay(1); | 903 | gdth_delay(1); |
1154 | } | 904 | } |
1155 | gdth_writeb(0, &dp2_ptr->u.ic.Status); | 905 | writeb(0, &dp2_ptr->u.ic.Status); |
1156 | gdth_writeb(0xff, &dp2_ptr->io.irqdel); | 906 | writeb(0xff, &dp2_ptr->io.irqdel); |
1157 | 907 | ||
1158 | ha->dma64_support = 0; | 908 | ha->dma64_support = 0; |
1159 | return 1; | 909 | return 1; |
1160 | } | 910 | } |
911 | #endif /* CONFIG_ISA */ | ||
1161 | 912 | ||
1162 | 913 | #ifdef CONFIG_PCI | |
1163 | static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha) | 914 | static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha) |
1164 | { | 915 | { |
1165 | register gdt6_dpram_str __iomem *dp6_ptr; | 916 | register gdt6_dpram_str __iomem *dp6_ptr; |
@@ -1190,8 +941,8 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha) | |||
1190 | } | 941 | } |
1191 | /* check and reset interface area */ | 942 | /* check and reset interface area */ |
1192 | dp6_ptr = ha->brd; | 943 | dp6_ptr = ha->brd; |
1193 | gdth_writel(DPMEM_MAGIC, &dp6_ptr->u); | 944 | writel(DPMEM_MAGIC, &dp6_ptr->u); |
1194 | if (gdth_readl(&dp6_ptr->u) != DPMEM_MAGIC) { | 945 | if (readl(&dp6_ptr->u) != DPMEM_MAGIC) { |
1195 | printk("GDT-PCI: Cannot access DPMEM at 0x%lx (shadowed?)\n", | 946 | printk("GDT-PCI: Cannot access DPMEM at 0x%lx (shadowed?)\n", |
1196 | pcistr->dpmem); | 947 | pcistr->dpmem); |
1197 | found = FALSE; | 948 | found = FALSE; |
@@ -1202,7 +953,7 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha) | |||
1202 | printk("GDT-PCI: Initialization error (DPMEM remap error)\n"); | 953 | printk("GDT-PCI: Initialization error (DPMEM remap error)\n"); |
1203 | return 0; | 954 | return 0; |
1204 | } | 955 | } |
1205 | if (gdth_readw(ha->brd) != 0xffff) { | 956 | if (readw(ha->brd) != 0xffff) { |
1206 | TRACE2(("init_pci_old() address 0x%x busy\n", i)); | 957 | TRACE2(("init_pci_old() address 0x%x busy\n", i)); |
1207 | continue; | 958 | continue; |
1208 | } | 959 | } |
@@ -1215,8 +966,8 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha) | |||
1215 | return 0; | 966 | return 0; |
1216 | } | 967 | } |
1217 | dp6_ptr = ha->brd; | 968 | dp6_ptr = ha->brd; |
1218 | gdth_writel(DPMEM_MAGIC, &dp6_ptr->u); | 969 | writel(DPMEM_MAGIC, &dp6_ptr->u); |
1219 | if (gdth_readl(&dp6_ptr->u) == DPMEM_MAGIC) { | 970 | if (readl(&dp6_ptr->u) == DPMEM_MAGIC) { |
1220 | printk("GDT-PCI: Use free address at 0x%x\n", i); | 971 | printk("GDT-PCI: Use free address at 0x%x\n", i); |
1221 | found = TRUE; | 972 | found = TRUE; |
1222 | break; | 973 | break; |
@@ -1229,24 +980,24 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha) | |||
1229 | } | 980 | } |
1230 | } | 981 | } |
1231 | memset_io(&dp6_ptr->u, 0, sizeof(dp6_ptr->u)); | 982 | memset_io(&dp6_ptr->u, 0, sizeof(dp6_ptr->u)); |
1232 | if (gdth_readl(&dp6_ptr->u) != 0) { | 983 | if (readl(&dp6_ptr->u) != 0) { |
1233 | printk("GDT-PCI: Initialization error (DPMEM write error)\n"); | 984 | printk("GDT-PCI: Initialization error (DPMEM write error)\n"); |
1234 | iounmap(ha->brd); | 985 | iounmap(ha->brd); |
1235 | return 0; | 986 | return 0; |
1236 | } | 987 | } |
1237 | 988 | ||
1238 | /* disable board interrupts, deinit services */ | 989 | /* disable board interrupts, deinit services */ |
1239 | gdth_writeb(0xff, &dp6_ptr->io.irqdel); | 990 | writeb(0xff, &dp6_ptr->io.irqdel); |
1240 | gdth_writeb(0x00, &dp6_ptr->io.irqen); | 991 | writeb(0x00, &dp6_ptr->io.irqen); |
1241 | gdth_writeb(0x00, &dp6_ptr->u.ic.S_Status); | 992 | writeb(0x00, &dp6_ptr->u.ic.S_Status); |
1242 | gdth_writeb(0x00, &dp6_ptr->u.ic.Cmd_Index); | 993 | writeb(0x00, &dp6_ptr->u.ic.Cmd_Index); |
1243 | 994 | ||
1244 | gdth_writel(pcistr->dpmem, &dp6_ptr->u.ic.S_Info[0]); | 995 | writel(pcistr->dpmem, &dp6_ptr->u.ic.S_Info[0]); |
1245 | gdth_writeb(0xff, &dp6_ptr->u.ic.S_Cmd_Indx); | 996 | writeb(0xff, &dp6_ptr->u.ic.S_Cmd_Indx); |
1246 | gdth_writeb(0, &dp6_ptr->io.event); | 997 | writeb(0, &dp6_ptr->io.event); |
1247 | retries = INIT_RETRIES; | 998 | retries = INIT_RETRIES; |
1248 | gdth_delay(20); | 999 | gdth_delay(20); |
1249 | while (gdth_readb(&dp6_ptr->u.ic.S_Status) != 0xff) { | 1000 | while (readb(&dp6_ptr->u.ic.S_Status) != 0xff) { |
1250 | if (--retries == 0) { | 1001 | if (--retries == 0) { |
1251 | printk("GDT-PCI: Initialization error (DEINIT failed)\n"); | 1002 | printk("GDT-PCI: Initialization error (DEINIT failed)\n"); |
1252 | iounmap(ha->brd); | 1003 | iounmap(ha->brd); |
@@ -1254,9 +1005,9 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha) | |||
1254 | } | 1005 | } |
1255 | gdth_delay(1); | 1006 | gdth_delay(1); |
1256 | } | 1007 | } |
1257 | prot_ver = (unchar)gdth_readl(&dp6_ptr->u.ic.S_Info[0]); | 1008 | prot_ver = (unchar)readl(&dp6_ptr->u.ic.S_Info[0]); |
1258 | gdth_writeb(0, &dp6_ptr->u.ic.S_Status); | 1009 | writeb(0, &dp6_ptr->u.ic.S_Status); |
1259 | gdth_writeb(0xff, &dp6_ptr->io.irqdel); | 1010 | writeb(0xff, &dp6_ptr->io.irqdel); |
1260 | if (prot_ver != PROTOCOL_VERSION) { | 1011 | if (prot_ver != PROTOCOL_VERSION) { |
1261 | printk("GDT-PCI: Illegal protocol version\n"); | 1012 | printk("GDT-PCI: Illegal protocol version\n"); |
1262 | iounmap(ha->brd); | 1013 | iounmap(ha->brd); |
@@ -1267,15 +1018,15 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha) | |||
1267 | ha->ic_all_size = sizeof(dp6_ptr->u); | 1018 | ha->ic_all_size = sizeof(dp6_ptr->u); |
1268 | 1019 | ||
1269 | /* special command to controller BIOS */ | 1020 | /* special command to controller BIOS */ |
1270 | gdth_writel(0x00, &dp6_ptr->u.ic.S_Info[0]); | 1021 | writel(0x00, &dp6_ptr->u.ic.S_Info[0]); |
1271 | gdth_writel(0x00, &dp6_ptr->u.ic.S_Info[1]); | 1022 | writel(0x00, &dp6_ptr->u.ic.S_Info[1]); |
1272 | gdth_writel(0x00, &dp6_ptr->u.ic.S_Info[2]); | 1023 | writel(0x00, &dp6_ptr->u.ic.S_Info[2]); |
1273 | gdth_writel(0x00, &dp6_ptr->u.ic.S_Info[3]); | 1024 | writel(0x00, &dp6_ptr->u.ic.S_Info[3]); |
1274 | gdth_writeb(0xfe, &dp6_ptr->u.ic.S_Cmd_Indx); | 1025 | writeb(0xfe, &dp6_ptr->u.ic.S_Cmd_Indx); |
1275 | gdth_writeb(0, &dp6_ptr->io.event); | 1026 | writeb(0, &dp6_ptr->io.event); |
1276 | retries = INIT_RETRIES; | 1027 | retries = INIT_RETRIES; |
1277 | gdth_delay(20); | 1028 | gdth_delay(20); |
1278 | while (gdth_readb(&dp6_ptr->u.ic.S_Status) != 0xfe) { | 1029 | while (readb(&dp6_ptr->u.ic.S_Status) != 0xfe) { |
1279 | if (--retries == 0) { | 1030 | if (--retries == 0) { |
1280 | printk("GDT-PCI: Initialization error\n"); | 1031 | printk("GDT-PCI: Initialization error\n"); |
1281 | iounmap(ha->brd); | 1032 | iounmap(ha->brd); |
@@ -1283,8 +1034,8 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha) | |||
1283 | } | 1034 | } |
1284 | gdth_delay(1); | 1035 | gdth_delay(1); |
1285 | } | 1036 | } |
1286 | gdth_writeb(0, &dp6_ptr->u.ic.S_Status); | 1037 | writeb(0, &dp6_ptr->u.ic.S_Status); |
1287 | gdth_writeb(0xff, &dp6_ptr->io.irqdel); | 1038 | writeb(0xff, &dp6_ptr->io.irqdel); |
1288 | 1039 | ||
1289 | ha->dma64_support = 0; | 1040 | ha->dma64_support = 0; |
1290 | 1041 | ||
@@ -1300,8 +1051,8 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha) | |||
1300 | } | 1051 | } |
1301 | /* check and reset interface area */ | 1052 | /* check and reset interface area */ |
1302 | dp6c_ptr = ha->brd; | 1053 | dp6c_ptr = ha->brd; |
1303 | gdth_writel(DPMEM_MAGIC, &dp6c_ptr->u); | 1054 | writel(DPMEM_MAGIC, &dp6c_ptr->u); |
1304 | if (gdth_readl(&dp6c_ptr->u) != DPMEM_MAGIC) { | 1055 | if (readl(&dp6c_ptr->u) != DPMEM_MAGIC) { |
1305 | printk("GDT-PCI: Cannot access DPMEM at 0x%lx (shadowed?)\n", | 1056 | printk("GDT-PCI: Cannot access DPMEM at 0x%lx (shadowed?)\n", |
1306 | pcistr->dpmem); | 1057 | pcistr->dpmem); |
1307 | found = FALSE; | 1058 | found = FALSE; |
@@ -1312,7 +1063,7 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha) | |||
1312 | printk("GDT-PCI: Initialization error (DPMEM remap error)\n"); | 1063 | printk("GDT-PCI: Initialization error (DPMEM remap error)\n"); |
1313 | return 0; | 1064 | return 0; |
1314 | } | 1065 | } |
1315 | if (gdth_readw(ha->brd) != 0xffff) { | 1066 | if (readw(ha->brd) != 0xffff) { |
1316 | TRACE2(("init_pci_plx() address 0x%x busy\n", i)); | 1067 | TRACE2(("init_pci_plx() address 0x%x busy\n", i)); |
1317 | continue; | 1068 | continue; |
1318 | } | 1069 | } |
@@ -1325,8 +1076,8 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha) | |||
1325 | return 0; | 1076 | return 0; |
1326 | } | 1077 | } |
1327 | dp6c_ptr = ha->brd; | 1078 | dp6c_ptr = ha->brd; |
1328 | gdth_writel(DPMEM_MAGIC, &dp6c_ptr->u); | 1079 | writel(DPMEM_MAGIC, &dp6c_ptr->u); |
1329 | if (gdth_readl(&dp6c_ptr->u) == DPMEM_MAGIC) { | 1080 | if (readl(&dp6c_ptr->u) == DPMEM_MAGIC) { |
1330 | printk("GDT-PCI: Use free address at 0x%x\n", i); | 1081 | printk("GDT-PCI: Use free address at 0x%x\n", i); |
1331 | found = TRUE; | 1082 | found = TRUE; |
1332 | break; | 1083 | break; |
@@ -1339,7 +1090,7 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha) | |||
1339 | } | 1090 | } |
1340 | } | 1091 | } |
1341 | memset_io(&dp6c_ptr->u, 0, sizeof(dp6c_ptr->u)); | 1092 | memset_io(&dp6c_ptr->u, 0, sizeof(dp6c_ptr->u)); |
1342 | if (gdth_readl(&dp6c_ptr->u) != 0) { | 1093 | if (readl(&dp6c_ptr->u) != 0) { |
1343 | printk("GDT-PCI: Initialization error (DPMEM write error)\n"); | 1094 | printk("GDT-PCI: Initialization error (DPMEM write error)\n"); |
1344 | iounmap(ha->brd); | 1095 | iounmap(ha->brd); |
1345 | return 0; | 1096 | return 0; |
@@ -1349,17 +1100,17 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha) | |||
1349 | outb(0x00,PTR2USHORT(&ha->plx->control1)); | 1100 | outb(0x00,PTR2USHORT(&ha->plx->control1)); |
1350 | outb(0xff,PTR2USHORT(&ha->plx->edoor_reg)); | 1101 | outb(0xff,PTR2USHORT(&ha->plx->edoor_reg)); |
1351 | 1102 | ||
1352 | gdth_writeb(0x00, &dp6c_ptr->u.ic.S_Status); | 1103 | writeb(0x00, &dp6c_ptr->u.ic.S_Status); |
1353 | gdth_writeb(0x00, &dp6c_ptr->u.ic.Cmd_Index); | 1104 | writeb(0x00, &dp6c_ptr->u.ic.Cmd_Index); |
1354 | 1105 | ||
1355 | gdth_writel(pcistr->dpmem, &dp6c_ptr->u.ic.S_Info[0]); | 1106 | writel(pcistr->dpmem, &dp6c_ptr->u.ic.S_Info[0]); |
1356 | gdth_writeb(0xff, &dp6c_ptr->u.ic.S_Cmd_Indx); | 1107 | writeb(0xff, &dp6c_ptr->u.ic.S_Cmd_Indx); |
1357 | 1108 | ||
1358 | outb(1,PTR2USHORT(&ha->plx->ldoor_reg)); | 1109 | outb(1,PTR2USHORT(&ha->plx->ldoor_reg)); |
1359 | 1110 | ||
1360 | retries = INIT_RETRIES; | 1111 | retries = INIT_RETRIES; |
1361 | gdth_delay(20); | 1112 | gdth_delay(20); |
1362 | while (gdth_readb(&dp6c_ptr->u.ic.S_Status) != 0xff) { | 1113 | while (readb(&dp6c_ptr->u.ic.S_Status) != 0xff) { |
1363 | if (--retries == 0) { | 1114 | if (--retries == 0) { |
1364 | printk("GDT-PCI: Initialization error (DEINIT failed)\n"); | 1115 | printk("GDT-PCI: Initialization error (DEINIT failed)\n"); |
1365 | iounmap(ha->brd); | 1116 | iounmap(ha->brd); |
@@ -1367,8 +1118,8 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha) | |||
1367 | } | 1118 | } |
1368 | gdth_delay(1); | 1119 | gdth_delay(1); |
1369 | } | 1120 | } |
1370 | prot_ver = (unchar)gdth_readl(&dp6c_ptr->u.ic.S_Info[0]); | 1121 | prot_ver = (unchar)readl(&dp6c_ptr->u.ic.S_Info[0]); |
1371 | gdth_writeb(0, &dp6c_ptr->u.ic.Status); | 1122 | writeb(0, &dp6c_ptr->u.ic.Status); |
1372 | if (prot_ver != PROTOCOL_VERSION) { | 1123 | if (prot_ver != PROTOCOL_VERSION) { |
1373 | printk("GDT-PCI: Illegal protocol version\n"); | 1124 | printk("GDT-PCI: Illegal protocol version\n"); |
1374 | iounmap(ha->brd); | 1125 | iounmap(ha->brd); |
@@ -1379,17 +1130,17 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha) | |||
1379 | ha->ic_all_size = sizeof(dp6c_ptr->u); | 1130 | ha->ic_all_size = sizeof(dp6c_ptr->u); |
1380 | 1131 | ||
1381 | /* special command to controller BIOS */ | 1132 | /* special command to controller BIOS */ |
1382 | gdth_writel(0x00, &dp6c_ptr->u.ic.S_Info[0]); | 1133 | writel(0x00, &dp6c_ptr->u.ic.S_Info[0]); |
1383 | gdth_writel(0x00, &dp6c_ptr->u.ic.S_Info[1]); | 1134 | writel(0x00, &dp6c_ptr->u.ic.S_Info[1]); |
1384 | gdth_writel(0x00, &dp6c_ptr->u.ic.S_Info[2]); | 1135 | writel(0x00, &dp6c_ptr->u.ic.S_Info[2]); |
1385 | gdth_writel(0x00, &dp6c_ptr->u.ic.S_Info[3]); | 1136 | writel(0x00, &dp6c_ptr->u.ic.S_Info[3]); |
1386 | gdth_writeb(0xfe, &dp6c_ptr->u.ic.S_Cmd_Indx); | 1137 | writeb(0xfe, &dp6c_ptr->u.ic.S_Cmd_Indx); |
1387 | 1138 | ||
1388 | outb(1,PTR2USHORT(&ha->plx->ldoor_reg)); | 1139 | outb(1,PTR2USHORT(&ha->plx->ldoor_reg)); |
1389 | 1140 | ||
1390 | retries = INIT_RETRIES; | 1141 | retries = INIT_RETRIES; |
1391 | gdth_delay(20); | 1142 | gdth_delay(20); |
1392 | while (gdth_readb(&dp6c_ptr->u.ic.S_Status) != 0xfe) { | 1143 | while (readb(&dp6c_ptr->u.ic.S_Status) != 0xfe) { |
1393 | if (--retries == 0) { | 1144 | if (--retries == 0) { |
1394 | printk("GDT-PCI: Initialization error\n"); | 1145 | printk("GDT-PCI: Initialization error\n"); |
1395 | iounmap(ha->brd); | 1146 | iounmap(ha->brd); |
@@ -1397,7 +1148,7 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha) | |||
1397 | } | 1148 | } |
1398 | gdth_delay(1); | 1149 | gdth_delay(1); |
1399 | } | 1150 | } |
1400 | gdth_writeb(0, &dp6c_ptr->u.ic.S_Status); | 1151 | writeb(0, &dp6c_ptr->u.ic.S_Status); |
1401 | 1152 | ||
1402 | ha->dma64_support = 0; | 1153 | ha->dma64_support = 0; |
1403 | 1154 | ||
@@ -1425,12 +1176,12 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha) | |||
1425 | 1176 | ||
1426 | /* Ensure that it is safe to access the non HW portions of DPMEM. | 1177 | /* Ensure that it is safe to access the non HW portions of DPMEM. |
1427 | * Aditional check needed for Xscale based RAID controllers */ | 1178 | * Aditional check needed for Xscale based RAID controllers */ |
1428 | while( ((int)gdth_readb(&dp6m_ptr->i960r.sema0_reg) ) & 3 ) | 1179 | while( ((int)readb(&dp6m_ptr->i960r.sema0_reg) ) & 3 ) |
1429 | gdth_delay(1); | 1180 | gdth_delay(1); |
1430 | 1181 | ||
1431 | /* check and reset interface area */ | 1182 | /* check and reset interface area */ |
1432 | gdth_writel(DPMEM_MAGIC, &dp6m_ptr->u); | 1183 | writel(DPMEM_MAGIC, &dp6m_ptr->u); |
1433 | if (gdth_readl(&dp6m_ptr->u) != DPMEM_MAGIC) { | 1184 | if (readl(&dp6m_ptr->u) != DPMEM_MAGIC) { |
1434 | printk("GDT-PCI: Cannot access DPMEM at 0x%lx (shadowed?)\n", | 1185 | printk("GDT-PCI: Cannot access DPMEM at 0x%lx (shadowed?)\n", |
1435 | pcistr->dpmem); | 1186 | pcistr->dpmem); |
1436 | found = FALSE; | 1187 | found = FALSE; |
@@ -1441,7 +1192,7 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha) | |||
1441 | printk("GDT-PCI: Initialization error (DPMEM remap error)\n"); | 1192 | printk("GDT-PCI: Initialization error (DPMEM remap error)\n"); |
1442 | return 0; | 1193 | return 0; |
1443 | } | 1194 | } |
1444 | if (gdth_readw(ha->brd) != 0xffff) { | 1195 | if (readw(ha->brd) != 0xffff) { |
1445 | TRACE2(("init_pci_mpr() address 0x%x busy\n", i)); | 1196 | TRACE2(("init_pci_mpr() address 0x%x busy\n", i)); |
1446 | continue; | 1197 | continue; |
1447 | } | 1198 | } |
@@ -1454,8 +1205,8 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha) | |||
1454 | return 0; | 1205 | return 0; |
1455 | } | 1206 | } |
1456 | dp6m_ptr = ha->brd; | 1207 | dp6m_ptr = ha->brd; |
1457 | gdth_writel(DPMEM_MAGIC, &dp6m_ptr->u); | 1208 | writel(DPMEM_MAGIC, &dp6m_ptr->u); |
1458 | if (gdth_readl(&dp6m_ptr->u) == DPMEM_MAGIC) { | 1209 | if (readl(&dp6m_ptr->u) == DPMEM_MAGIC) { |
1459 | printk("GDT-PCI: Use free address at 0x%x\n", i); | 1210 | printk("GDT-PCI: Use free address at 0x%x\n", i); |
1460 | found = TRUE; | 1211 | found = TRUE; |
1461 | break; | 1212 | break; |
@@ -1470,18 +1221,18 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha) | |||
1470 | memset_io(&dp6m_ptr->u, 0, sizeof(dp6m_ptr->u)); | 1221 | memset_io(&dp6m_ptr->u, 0, sizeof(dp6m_ptr->u)); |
1471 | 1222 | ||
1472 | /* disable board interrupts, deinit services */ | 1223 | /* disable board interrupts, deinit services */ |
1473 | gdth_writeb(gdth_readb(&dp6m_ptr->i960r.edoor_en_reg) | 4, | 1224 | writeb(readb(&dp6m_ptr->i960r.edoor_en_reg) | 4, |
1474 | &dp6m_ptr->i960r.edoor_en_reg); | 1225 | &dp6m_ptr->i960r.edoor_en_reg); |
1475 | gdth_writeb(0xff, &dp6m_ptr->i960r.edoor_reg); | 1226 | writeb(0xff, &dp6m_ptr->i960r.edoor_reg); |
1476 | gdth_writeb(0x00, &dp6m_ptr->u.ic.S_Status); | 1227 | writeb(0x00, &dp6m_ptr->u.ic.S_Status); |
1477 | gdth_writeb(0x00, &dp6m_ptr->u.ic.Cmd_Index); | 1228 | writeb(0x00, &dp6m_ptr->u.ic.Cmd_Index); |
1478 | 1229 | ||
1479 | gdth_writel(pcistr->dpmem, &dp6m_ptr->u.ic.S_Info[0]); | 1230 | writel(pcistr->dpmem, &dp6m_ptr->u.ic.S_Info[0]); |
1480 | gdth_writeb(0xff, &dp6m_ptr->u.ic.S_Cmd_Indx); | 1231 | writeb(0xff, &dp6m_ptr->u.ic.S_Cmd_Indx); |
1481 | gdth_writeb(1, &dp6m_ptr->i960r.ldoor_reg); | 1232 | writeb(1, &dp6m_ptr->i960r.ldoor_reg); |
1482 | retries = INIT_RETRIES; | 1233 | retries = INIT_RETRIES; |
1483 | gdth_delay(20); | 1234 | gdth_delay(20); |
1484 | while (gdth_readb(&dp6m_ptr->u.ic.S_Status) != 0xff) { | 1235 | while (readb(&dp6m_ptr->u.ic.S_Status) != 0xff) { |
1485 | if (--retries == 0) { | 1236 | if (--retries == 0) { |
1486 | printk("GDT-PCI: Initialization error (DEINIT failed)\n"); | 1237 | printk("GDT-PCI: Initialization error (DEINIT failed)\n"); |
1487 | iounmap(ha->brd); | 1238 | iounmap(ha->brd); |
@@ -1489,8 +1240,8 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha) | |||
1489 | } | 1240 | } |
1490 | gdth_delay(1); | 1241 | gdth_delay(1); |
1491 | } | 1242 | } |
1492 | prot_ver = (unchar)gdth_readl(&dp6m_ptr->u.ic.S_Info[0]); | 1243 | prot_ver = (unchar)readl(&dp6m_ptr->u.ic.S_Info[0]); |
1493 | gdth_writeb(0, &dp6m_ptr->u.ic.S_Status); | 1244 | writeb(0, &dp6m_ptr->u.ic.S_Status); |
1494 | if (prot_ver != PROTOCOL_VERSION) { | 1245 | if (prot_ver != PROTOCOL_VERSION) { |
1495 | printk("GDT-PCI: Illegal protocol version\n"); | 1246 | printk("GDT-PCI: Illegal protocol version\n"); |
1496 | iounmap(ha->brd); | 1247 | iounmap(ha->brd); |
@@ -1501,15 +1252,15 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha) | |||
1501 | ha->ic_all_size = sizeof(dp6m_ptr->u); | 1252 | ha->ic_all_size = sizeof(dp6m_ptr->u); |
1502 | 1253 | ||
1503 | /* special command to controller BIOS */ | 1254 | /* special command to controller BIOS */ |
1504 | gdth_writel(0x00, &dp6m_ptr->u.ic.S_Info[0]); | 1255 | writel(0x00, &dp6m_ptr->u.ic.S_Info[0]); |
1505 | gdth_writel(0x00, &dp6m_ptr->u.ic.S_Info[1]); | 1256 | writel(0x00, &dp6m_ptr->u.ic.S_Info[1]); |
1506 | gdth_writel(0x00, &dp6m_ptr->u.ic.S_Info[2]); | 1257 | writel(0x00, &dp6m_ptr->u.ic.S_Info[2]); |
1507 | gdth_writel(0x00, &dp6m_ptr->u.ic.S_Info[3]); | 1258 | writel(0x00, &dp6m_ptr->u.ic.S_Info[3]); |
1508 | gdth_writeb(0xfe, &dp6m_ptr->u.ic.S_Cmd_Indx); | 1259 | writeb(0xfe, &dp6m_ptr->u.ic.S_Cmd_Indx); |
1509 | gdth_writeb(1, &dp6m_ptr->i960r.ldoor_reg); | 1260 | writeb(1, &dp6m_ptr->i960r.ldoor_reg); |
1510 | retries = INIT_RETRIES; | 1261 | retries = INIT_RETRIES; |
1511 | gdth_delay(20); | 1262 | gdth_delay(20); |
1512 | while (gdth_readb(&dp6m_ptr->u.ic.S_Status) != 0xfe) { | 1263 | while (readb(&dp6m_ptr->u.ic.S_Status) != 0xfe) { |
1513 | if (--retries == 0) { | 1264 | if (--retries == 0) { |
1514 | printk("GDT-PCI: Initialization error\n"); | 1265 | printk("GDT-PCI: Initialization error\n"); |
1515 | iounmap(ha->brd); | 1266 | iounmap(ha->brd); |
@@ -1517,14 +1268,14 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha) | |||
1517 | } | 1268 | } |
1518 | gdth_delay(1); | 1269 | gdth_delay(1); |
1519 | } | 1270 | } |
1520 | gdth_writeb(0, &dp6m_ptr->u.ic.S_Status); | 1271 | writeb(0, &dp6m_ptr->u.ic.S_Status); |
1521 | 1272 | ||
1522 | /* read FW version to detect 64-bit DMA support */ | 1273 | /* read FW version to detect 64-bit DMA support */ |
1523 | gdth_writeb(0xfd, &dp6m_ptr->u.ic.S_Cmd_Indx); | 1274 | writeb(0xfd, &dp6m_ptr->u.ic.S_Cmd_Indx); |
1524 | gdth_writeb(1, &dp6m_ptr->i960r.ldoor_reg); | 1275 | writeb(1, &dp6m_ptr->i960r.ldoor_reg); |
1525 | retries = INIT_RETRIES; | 1276 | retries = INIT_RETRIES; |
1526 | gdth_delay(20); | 1277 | gdth_delay(20); |
1527 | while (gdth_readb(&dp6m_ptr->u.ic.S_Status) != 0xfd) { | 1278 | while (readb(&dp6m_ptr->u.ic.S_Status) != 0xfd) { |
1528 | if (--retries == 0) { | 1279 | if (--retries == 0) { |
1529 | printk("GDT-PCI: Initialization error (DEINIT failed)\n"); | 1280 | printk("GDT-PCI: Initialization error (DEINIT failed)\n"); |
1530 | iounmap(ha->brd); | 1281 | iounmap(ha->brd); |
@@ -1532,8 +1283,8 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha) | |||
1532 | } | 1283 | } |
1533 | gdth_delay(1); | 1284 | gdth_delay(1); |
1534 | } | 1285 | } |
1535 | prot_ver = (unchar)(gdth_readl(&dp6m_ptr->u.ic.S_Info[0]) >> 16); | 1286 | prot_ver = (unchar)(readl(&dp6m_ptr->u.ic.S_Info[0]) >> 16); |
1536 | gdth_writeb(0, &dp6m_ptr->u.ic.S_Status); | 1287 | writeb(0, &dp6m_ptr->u.ic.S_Status); |
1537 | if (prot_ver < 0x2b) /* FW < x.43: no 64-bit DMA support */ | 1288 | if (prot_ver < 0x2b) /* FW < x.43: no 64-bit DMA support */ |
1538 | ha->dma64_support = 0; | 1289 | ha->dma64_support = 0; |
1539 | else | 1290 | else |
@@ -1542,20 +1293,18 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha) | |||
1542 | 1293 | ||
1543 | return 1; | 1294 | return 1; |
1544 | } | 1295 | } |
1545 | 1296 | #endif /* CONFIG_PCI */ | |
1546 | 1297 | ||
1547 | /* controller protocol functions */ | 1298 | /* controller protocol functions */ |
1548 | 1299 | ||
1549 | static void __init gdth_enable_int(int hanum) | 1300 | static void __init gdth_enable_int(gdth_ha_str *ha) |
1550 | { | 1301 | { |
1551 | gdth_ha_str *ha; | ||
1552 | ulong flags; | 1302 | ulong flags; |
1553 | gdt2_dpram_str __iomem *dp2_ptr; | 1303 | gdt2_dpram_str __iomem *dp2_ptr; |
1554 | gdt6_dpram_str __iomem *dp6_ptr; | 1304 | gdt6_dpram_str __iomem *dp6_ptr; |
1555 | gdt6m_dpram_str __iomem *dp6m_ptr; | 1305 | gdt6m_dpram_str __iomem *dp6m_ptr; |
1556 | 1306 | ||
1557 | TRACE(("gdth_enable_int() hanum %d\n",hanum)); | 1307 | TRACE(("gdth_enable_int() hanum %d\n",ha->hanum)); |
1558 | ha = HADATA(gdth_ctr_tab[hanum]); | ||
1559 | spin_lock_irqsave(&ha->smp_lock, flags); | 1308 | spin_lock_irqsave(&ha->smp_lock, flags); |
1560 | 1309 | ||
1561 | if (ha->type == GDT_EISA) { | 1310 | if (ha->type == GDT_EISA) { |
@@ -1564,93 +1313,80 @@ static void __init gdth_enable_int(int hanum) | |||
1564 | outb(0x01, ha->bmic + EINTENABREG); | 1313 | outb(0x01, ha->bmic + EINTENABREG); |
1565 | } else if (ha->type == GDT_ISA) { | 1314 | } else if (ha->type == GDT_ISA) { |
1566 | dp2_ptr = ha->brd; | 1315 | dp2_ptr = ha->brd; |
1567 | gdth_writeb(1, &dp2_ptr->io.irqdel); | 1316 | writeb(1, &dp2_ptr->io.irqdel); |
1568 | gdth_writeb(0, &dp2_ptr->u.ic.Cmd_Index); | 1317 | writeb(0, &dp2_ptr->u.ic.Cmd_Index); |
1569 | gdth_writeb(1, &dp2_ptr->io.irqen); | 1318 | writeb(1, &dp2_ptr->io.irqen); |
1570 | } else if (ha->type == GDT_PCI) { | 1319 | } else if (ha->type == GDT_PCI) { |
1571 | dp6_ptr = ha->brd; | 1320 | dp6_ptr = ha->brd; |
1572 | gdth_writeb(1, &dp6_ptr->io.irqdel); | 1321 | writeb(1, &dp6_ptr->io.irqdel); |
1573 | gdth_writeb(0, &dp6_ptr->u.ic.Cmd_Index); | 1322 | writeb(0, &dp6_ptr->u.ic.Cmd_Index); |
1574 | gdth_writeb(1, &dp6_ptr->io.irqen); | 1323 | writeb(1, &dp6_ptr->io.irqen); |
1575 | } else if (ha->type == GDT_PCINEW) { | 1324 | } else if (ha->type == GDT_PCINEW) { |
1576 | outb(0xff, PTR2USHORT(&ha->plx->edoor_reg)); | 1325 | outb(0xff, PTR2USHORT(&ha->plx->edoor_reg)); |
1577 | outb(0x03, PTR2USHORT(&ha->plx->control1)); | 1326 | outb(0x03, PTR2USHORT(&ha->plx->control1)); |
1578 | } else if (ha->type == GDT_PCIMPR) { | 1327 | } else if (ha->type == GDT_PCIMPR) { |
1579 | dp6m_ptr = ha->brd; | 1328 | dp6m_ptr = ha->brd; |
1580 | gdth_writeb(0xff, &dp6m_ptr->i960r.edoor_reg); | 1329 | writeb(0xff, &dp6m_ptr->i960r.edoor_reg); |
1581 | gdth_writeb(gdth_readb(&dp6m_ptr->i960r.edoor_en_reg) & ~4, | 1330 | writeb(readb(&dp6m_ptr->i960r.edoor_en_reg) & ~4, |
1582 | &dp6m_ptr->i960r.edoor_en_reg); | 1331 | &dp6m_ptr->i960r.edoor_en_reg); |
1583 | } | 1332 | } |
1584 | spin_unlock_irqrestore(&ha->smp_lock, flags); | 1333 | spin_unlock_irqrestore(&ha->smp_lock, flags); |
1585 | } | 1334 | } |
1586 | 1335 | ||
1587 | 1336 | /* return IStatus if interrupt was from this card else 0 */ | |
1588 | static int gdth_get_status(unchar *pIStatus,int irq) | 1337 | static unchar gdth_get_status(gdth_ha_str *ha, int irq) |
1589 | { | 1338 | { |
1590 | register gdth_ha_str *ha; | 1339 | unchar IStatus = 0; |
1591 | int i; | 1340 | |
1341 | TRACE(("gdth_get_status() irq %d ctr_count %d\n", irq, gdth_ctr_count)); | ||
1592 | 1342 | ||
1593 | TRACE(("gdth_get_status() irq %d ctr_count %d\n", | ||
1594 | irq,gdth_ctr_count)); | ||
1595 | |||
1596 | *pIStatus = 0; | ||
1597 | for (i=0; i<gdth_ctr_count; ++i) { | ||
1598 | ha = HADATA(gdth_ctr_tab[i]); | ||
1599 | if (ha->irq != (unchar)irq) /* check IRQ */ | 1343 | if (ha->irq != (unchar)irq) /* check IRQ */ |
1600 | continue; | 1344 | return false; |
1601 | if (ha->type == GDT_EISA) | 1345 | if (ha->type == GDT_EISA) |
1602 | *pIStatus = inb((ushort)ha->bmic + EDOORREG); | 1346 | IStatus = inb((ushort)ha->bmic + EDOORREG); |
1603 | else if (ha->type == GDT_ISA) | 1347 | else if (ha->type == GDT_ISA) |
1604 | *pIStatus = | 1348 | IStatus = |
1605 | gdth_readb(&((gdt2_dpram_str __iomem *)ha->brd)->u.ic.Cmd_Index); | 1349 | readb(&((gdt2_dpram_str __iomem *)ha->brd)->u.ic.Cmd_Index); |
1606 | else if (ha->type == GDT_PCI) | 1350 | else if (ha->type == GDT_PCI) |
1607 | *pIStatus = | 1351 | IStatus = |
1608 | gdth_readb(&((gdt6_dpram_str __iomem *)ha->brd)->u.ic.Cmd_Index); | 1352 | readb(&((gdt6_dpram_str __iomem *)ha->brd)->u.ic.Cmd_Index); |
1609 | else if (ha->type == GDT_PCINEW) | 1353 | else if (ha->type == GDT_PCINEW) |
1610 | *pIStatus = inb(PTR2USHORT(&ha->plx->edoor_reg)); | 1354 | IStatus = inb(PTR2USHORT(&ha->plx->edoor_reg)); |
1611 | else if (ha->type == GDT_PCIMPR) | 1355 | else if (ha->type == GDT_PCIMPR) |
1612 | *pIStatus = | 1356 | IStatus = |
1613 | gdth_readb(&((gdt6m_dpram_str __iomem *)ha->brd)->i960r.edoor_reg); | 1357 | readb(&((gdt6m_dpram_str __iomem *)ha->brd)->i960r.edoor_reg); |
1614 | 1358 | ||
1615 | if (*pIStatus) | 1359 | return IStatus; |
1616 | return i; /* board found */ | ||
1617 | } | ||
1618 | return -1; | ||
1619 | } | 1360 | } |
1620 | 1361 | ||
1621 | 1362 | static int gdth_test_busy(gdth_ha_str *ha) | |
1622 | static int gdth_test_busy(int hanum) | ||
1623 | { | 1363 | { |
1624 | register gdth_ha_str *ha; | ||
1625 | register int gdtsema0 = 0; | 1364 | register int gdtsema0 = 0; |
1626 | 1365 | ||
1627 | TRACE(("gdth_test_busy() hanum %d\n",hanum)); | 1366 | TRACE(("gdth_test_busy() hanum %d\n", ha->hanum)); |
1628 | 1367 | ||
1629 | ha = HADATA(gdth_ctr_tab[hanum]); | ||
1630 | if (ha->type == GDT_EISA) | 1368 | if (ha->type == GDT_EISA) |
1631 | gdtsema0 = (int)inb(ha->bmic + SEMA0REG); | 1369 | gdtsema0 = (int)inb(ha->bmic + SEMA0REG); |
1632 | else if (ha->type == GDT_ISA) | 1370 | else if (ha->type == GDT_ISA) |
1633 | gdtsema0 = (int)gdth_readb(&((gdt2_dpram_str __iomem *)ha->brd)->u.ic.Sema0); | 1371 | gdtsema0 = (int)readb(&((gdt2_dpram_str __iomem *)ha->brd)->u.ic.Sema0); |
1634 | else if (ha->type == GDT_PCI) | 1372 | else if (ha->type == GDT_PCI) |
1635 | gdtsema0 = (int)gdth_readb(&((gdt6_dpram_str __iomem *)ha->brd)->u.ic.Sema0); | 1373 | gdtsema0 = (int)readb(&((gdt6_dpram_str __iomem *)ha->brd)->u.ic.Sema0); |
1636 | else if (ha->type == GDT_PCINEW) | 1374 | else if (ha->type == GDT_PCINEW) |
1637 | gdtsema0 = (int)inb(PTR2USHORT(&ha->plx->sema0_reg)); | 1375 | gdtsema0 = (int)inb(PTR2USHORT(&ha->plx->sema0_reg)); |
1638 | else if (ha->type == GDT_PCIMPR) | 1376 | else if (ha->type == GDT_PCIMPR) |
1639 | gdtsema0 = | 1377 | gdtsema0 = |
1640 | (int)gdth_readb(&((gdt6m_dpram_str __iomem *)ha->brd)->i960r.sema0_reg); | 1378 | (int)readb(&((gdt6m_dpram_str __iomem *)ha->brd)->i960r.sema0_reg); |
1641 | 1379 | ||
1642 | return (gdtsema0 & 1); | 1380 | return (gdtsema0 & 1); |
1643 | } | 1381 | } |
1644 | 1382 | ||
1645 | 1383 | ||
1646 | static int gdth_get_cmd_index(int hanum) | 1384 | static int gdth_get_cmd_index(gdth_ha_str *ha) |
1647 | { | 1385 | { |
1648 | register gdth_ha_str *ha; | ||
1649 | int i; | 1386 | int i; |
1650 | 1387 | ||
1651 | TRACE(("gdth_get_cmd_index() hanum %d\n",hanum)); | 1388 | TRACE(("gdth_get_cmd_index() hanum %d\n", ha->hanum)); |
1652 | 1389 | ||
1653 | ha = HADATA(gdth_ctr_tab[hanum]); | ||
1654 | for (i=0; i<GDTH_MAXCMDS; ++i) { | 1390 | for (i=0; i<GDTH_MAXCMDS; ++i) { |
1655 | if (ha->cmd_tab[i].cmnd == UNUSED_CMND) { | 1391 | if (ha->cmd_tab[i].cmnd == UNUSED_CMND) { |
1656 | ha->cmd_tab[i].cmnd = ha->pccb->RequestBuffer; | 1392 | ha->cmd_tab[i].cmnd = ha->pccb->RequestBuffer; |
@@ -1663,30 +1399,26 @@ static int gdth_get_cmd_index(int hanum) | |||
1663 | } | 1399 | } |
1664 | 1400 | ||
1665 | 1401 | ||
1666 | static void gdth_set_sema0(int hanum) | 1402 | static void gdth_set_sema0(gdth_ha_str *ha) |
1667 | { | 1403 | { |
1668 | register gdth_ha_str *ha; | 1404 | TRACE(("gdth_set_sema0() hanum %d\n", ha->hanum)); |
1669 | 1405 | ||
1670 | TRACE(("gdth_set_sema0() hanum %d\n",hanum)); | ||
1671 | |||
1672 | ha = HADATA(gdth_ctr_tab[hanum]); | ||
1673 | if (ha->type == GDT_EISA) { | 1406 | if (ha->type == GDT_EISA) { |
1674 | outb(1, ha->bmic + SEMA0REG); | 1407 | outb(1, ha->bmic + SEMA0REG); |
1675 | } else if (ha->type == GDT_ISA) { | 1408 | } else if (ha->type == GDT_ISA) { |
1676 | gdth_writeb(1, &((gdt2_dpram_str __iomem *)ha->brd)->u.ic.Sema0); | 1409 | writeb(1, &((gdt2_dpram_str __iomem *)ha->brd)->u.ic.Sema0); |
1677 | } else if (ha->type == GDT_PCI) { | 1410 | } else if (ha->type == GDT_PCI) { |
1678 | gdth_writeb(1, &((gdt6_dpram_str __iomem *)ha->brd)->u.ic.Sema0); | 1411 | writeb(1, &((gdt6_dpram_str __iomem *)ha->brd)->u.ic.Sema0); |
1679 | } else if (ha->type == GDT_PCINEW) { | 1412 | } else if (ha->type == GDT_PCINEW) { |
1680 | outb(1, PTR2USHORT(&ha->plx->sema0_reg)); | 1413 | outb(1, PTR2USHORT(&ha->plx->sema0_reg)); |
1681 | } else if (ha->type == GDT_PCIMPR) { | 1414 | } else if (ha->type == GDT_PCIMPR) { |
1682 | gdth_writeb(1, &((gdt6m_dpram_str __iomem *)ha->brd)->i960r.sema0_reg); | 1415 | writeb(1, &((gdt6m_dpram_str __iomem *)ha->brd)->i960r.sema0_reg); |
1683 | } | 1416 | } |
1684 | } | 1417 | } |
1685 | 1418 | ||
1686 | 1419 | ||
1687 | static void gdth_copy_command(int hanum) | 1420 | static void gdth_copy_command(gdth_ha_str *ha) |
1688 | { | 1421 | { |
1689 | register gdth_ha_str *ha; | ||
1690 | register gdth_cmd_str *cmd_ptr; | 1422 | register gdth_cmd_str *cmd_ptr; |
1691 | register gdt6m_dpram_str __iomem *dp6m_ptr; | 1423 | register gdt6m_dpram_str __iomem *dp6m_ptr; |
1692 | register gdt6c_dpram_str __iomem *dp6c_ptr; | 1424 | register gdt6c_dpram_str __iomem *dp6c_ptr; |
@@ -1694,9 +1426,8 @@ static void gdth_copy_command(int hanum) | |||
1694 | gdt2_dpram_str __iomem *dp2_ptr; | 1426 | gdt2_dpram_str __iomem *dp2_ptr; |
1695 | ushort cp_count,dp_offset,cmd_no; | 1427 | ushort cp_count,dp_offset,cmd_no; |
1696 | 1428 | ||
1697 | TRACE(("gdth_copy_command() hanum %d\n",hanum)); | 1429 | TRACE(("gdth_copy_command() hanum %d\n", ha->hanum)); |
1698 | 1430 | ||
1699 | ha = HADATA(gdth_ctr_tab[hanum]); | ||
1700 | cp_count = ha->cmd_len; | 1431 | cp_count = ha->cmd_len; |
1701 | dp_offset= ha->cmd_offs_dpmem; | 1432 | dp_offset= ha->cmd_offs_dpmem; |
1702 | cmd_no = ha->cmd_cnt; | 1433 | cmd_no = ha->cmd_cnt; |
@@ -1715,42 +1446,39 @@ static void gdth_copy_command(int hanum) | |||
1715 | /* set offset and service, copy command to DPMEM */ | 1446 | /* set offset and service, copy command to DPMEM */ |
1716 | if (ha->type == GDT_ISA) { | 1447 | if (ha->type == GDT_ISA) { |
1717 | dp2_ptr = ha->brd; | 1448 | dp2_ptr = ha->brd; |
1718 | gdth_writew(dp_offset + DPMEM_COMMAND_OFFSET, | 1449 | writew(dp_offset + DPMEM_COMMAND_OFFSET, |
1719 | &dp2_ptr->u.ic.comm_queue[cmd_no].offset); | 1450 | &dp2_ptr->u.ic.comm_queue[cmd_no].offset); |
1720 | gdth_writew((ushort)cmd_ptr->Service, | 1451 | writew((ushort)cmd_ptr->Service, |
1721 | &dp2_ptr->u.ic.comm_queue[cmd_no].serv_id); | 1452 | &dp2_ptr->u.ic.comm_queue[cmd_no].serv_id); |
1722 | memcpy_toio(&dp2_ptr->u.ic.gdt_dpr_cmd[dp_offset],cmd_ptr,cp_count); | 1453 | memcpy_toio(&dp2_ptr->u.ic.gdt_dpr_cmd[dp_offset],cmd_ptr,cp_count); |
1723 | } else if (ha->type == GDT_PCI) { | 1454 | } else if (ha->type == GDT_PCI) { |
1724 | dp6_ptr = ha->brd; | 1455 | dp6_ptr = ha->brd; |
1725 | gdth_writew(dp_offset + DPMEM_COMMAND_OFFSET, | 1456 | writew(dp_offset + DPMEM_COMMAND_OFFSET, |
1726 | &dp6_ptr->u.ic.comm_queue[cmd_no].offset); | 1457 | &dp6_ptr->u.ic.comm_queue[cmd_no].offset); |
1727 | gdth_writew((ushort)cmd_ptr->Service, | 1458 | writew((ushort)cmd_ptr->Service, |
1728 | &dp6_ptr->u.ic.comm_queue[cmd_no].serv_id); | 1459 | &dp6_ptr->u.ic.comm_queue[cmd_no].serv_id); |
1729 | memcpy_toio(&dp6_ptr->u.ic.gdt_dpr_cmd[dp_offset],cmd_ptr,cp_count); | 1460 | memcpy_toio(&dp6_ptr->u.ic.gdt_dpr_cmd[dp_offset],cmd_ptr,cp_count); |
1730 | } else if (ha->type == GDT_PCINEW) { | 1461 | } else if (ha->type == GDT_PCINEW) { |
1731 | dp6c_ptr = ha->brd; | 1462 | dp6c_ptr = ha->brd; |
1732 | gdth_writew(dp_offset + DPMEM_COMMAND_OFFSET, | 1463 | writew(dp_offset + DPMEM_COMMAND_OFFSET, |
1733 | &dp6c_ptr->u.ic.comm_queue[cmd_no].offset); | 1464 | &dp6c_ptr->u.ic.comm_queue[cmd_no].offset); |
1734 | gdth_writew((ushort)cmd_ptr->Service, | 1465 | writew((ushort)cmd_ptr->Service, |
1735 | &dp6c_ptr->u.ic.comm_queue[cmd_no].serv_id); | 1466 | &dp6c_ptr->u.ic.comm_queue[cmd_no].serv_id); |
1736 | memcpy_toio(&dp6c_ptr->u.ic.gdt_dpr_cmd[dp_offset],cmd_ptr,cp_count); | 1467 | memcpy_toio(&dp6c_ptr->u.ic.gdt_dpr_cmd[dp_offset],cmd_ptr,cp_count); |
1737 | } else if (ha->type == GDT_PCIMPR) { | 1468 | } else if (ha->type == GDT_PCIMPR) { |
1738 | dp6m_ptr = ha->brd; | 1469 | dp6m_ptr = ha->brd; |
1739 | gdth_writew(dp_offset + DPMEM_COMMAND_OFFSET, | 1470 | writew(dp_offset + DPMEM_COMMAND_OFFSET, |
1740 | &dp6m_ptr->u.ic.comm_queue[cmd_no].offset); | 1471 | &dp6m_ptr->u.ic.comm_queue[cmd_no].offset); |
1741 | gdth_writew((ushort)cmd_ptr->Service, | 1472 | writew((ushort)cmd_ptr->Service, |
1742 | &dp6m_ptr->u.ic.comm_queue[cmd_no].serv_id); | 1473 | &dp6m_ptr->u.ic.comm_queue[cmd_no].serv_id); |
1743 | memcpy_toio(&dp6m_ptr->u.ic.gdt_dpr_cmd[dp_offset],cmd_ptr,cp_count); | 1474 | memcpy_toio(&dp6m_ptr->u.ic.gdt_dpr_cmd[dp_offset],cmd_ptr,cp_count); |
1744 | } | 1475 | } |
1745 | } | 1476 | } |
1746 | 1477 | ||
1747 | 1478 | ||
1748 | static void gdth_release_event(int hanum) | 1479 | static void gdth_release_event(gdth_ha_str *ha) |
1749 | { | 1480 | { |
1750 | register gdth_ha_str *ha; | 1481 | TRACE(("gdth_release_event() hanum %d\n", ha->hanum)); |
1751 | |||
1752 | TRACE(("gdth_release_event() hanum %d\n",hanum)); | ||
1753 | ha = HADATA(gdth_ctr_tab[hanum]); | ||
1754 | 1482 | ||
1755 | #ifdef GDTH_STATISTICS | 1483 | #ifdef GDTH_STATISTICS |
1756 | { | 1484 | { |
@@ -1774,56 +1502,50 @@ static void gdth_release_event(int hanum) | |||
1774 | outl(ha->ccb_phys, ha->bmic + MAILBOXREG); | 1502 | outl(ha->ccb_phys, ha->bmic + MAILBOXREG); |
1775 | outb(ha->pccb->Service, ha->bmic + LDOORREG); | 1503 | outb(ha->pccb->Service, ha->bmic + LDOORREG); |
1776 | } else if (ha->type == GDT_ISA) { | 1504 | } else if (ha->type == GDT_ISA) { |
1777 | gdth_writeb(0, &((gdt2_dpram_str __iomem *)ha->brd)->io.event); | 1505 | writeb(0, &((gdt2_dpram_str __iomem *)ha->brd)->io.event); |
1778 | } else if (ha->type == GDT_PCI) { | 1506 | } else if (ha->type == GDT_PCI) { |
1779 | gdth_writeb(0, &((gdt6_dpram_str __iomem *)ha->brd)->io.event); | 1507 | writeb(0, &((gdt6_dpram_str __iomem *)ha->brd)->io.event); |
1780 | } else if (ha->type == GDT_PCINEW) { | 1508 | } else if (ha->type == GDT_PCINEW) { |
1781 | outb(1, PTR2USHORT(&ha->plx->ldoor_reg)); | 1509 | outb(1, PTR2USHORT(&ha->plx->ldoor_reg)); |
1782 | } else if (ha->type == GDT_PCIMPR) { | 1510 | } else if (ha->type == GDT_PCIMPR) { |
1783 | gdth_writeb(1, &((gdt6m_dpram_str __iomem *)ha->brd)->i960r.ldoor_reg); | 1511 | writeb(1, &((gdt6m_dpram_str __iomem *)ha->brd)->i960r.ldoor_reg); |
1784 | } | 1512 | } |
1785 | } | 1513 | } |
1786 | 1514 | ||
1787 | 1515 | static int gdth_wait(gdth_ha_str *ha, int index, ulong32 time) | |
1788 | static int gdth_wait(int hanum,int index,ulong32 time) | ||
1789 | { | 1516 | { |
1790 | gdth_ha_str *ha; | ||
1791 | int answer_found = FALSE; | 1517 | int answer_found = FALSE; |
1518 | int wait_index = 0; | ||
1792 | 1519 | ||
1793 | TRACE(("gdth_wait() hanum %d index %d time %d\n",hanum,index,time)); | 1520 | TRACE(("gdth_wait() hanum %d index %d time %d\n", ha->hanum, index, time)); |
1794 | 1521 | ||
1795 | ha = HADATA(gdth_ctr_tab[hanum]); | ||
1796 | if (index == 0) | 1522 | if (index == 0) |
1797 | return 1; /* no wait required */ | 1523 | return 1; /* no wait required */ |
1798 | 1524 | ||
1799 | gdth_from_wait = TRUE; | ||
1800 | do { | 1525 | do { |
1801 | gdth_interrupt((int)ha->irq,ha); | 1526 | __gdth_interrupt(ha, (int)ha->irq, true, &wait_index); |
1802 | if (wait_hanum==hanum && wait_index==index) { | 1527 | if (wait_index == index) { |
1803 | answer_found = TRUE; | 1528 | answer_found = TRUE; |
1804 | break; | 1529 | break; |
1805 | } | 1530 | } |
1806 | gdth_delay(1); | 1531 | gdth_delay(1); |
1807 | } while (--time); | 1532 | } while (--time); |
1808 | gdth_from_wait = FALSE; | 1533 | |
1809 | 1534 | while (gdth_test_busy(ha)) | |
1810 | while (gdth_test_busy(hanum)) | ||
1811 | gdth_delay(0); | 1535 | gdth_delay(0); |
1812 | 1536 | ||
1813 | return (answer_found); | 1537 | return (answer_found); |
1814 | } | 1538 | } |
1815 | 1539 | ||
1816 | 1540 | ||
1817 | static int gdth_internal_cmd(int hanum,unchar service,ushort opcode,ulong32 p1, | 1541 | static int gdth_internal_cmd(gdth_ha_str *ha, unchar service, ushort opcode, |
1818 | ulong64 p2,ulong64 p3) | 1542 | ulong32 p1, ulong64 p2, ulong64 p3) |
1819 | { | 1543 | { |
1820 | register gdth_ha_str *ha; | ||
1821 | register gdth_cmd_str *cmd_ptr; | 1544 | register gdth_cmd_str *cmd_ptr; |
1822 | int retries,index; | 1545 | int retries,index; |
1823 | 1546 | ||
1824 | TRACE2(("gdth_internal_cmd() service %d opcode %d\n",service,opcode)); | 1547 | TRACE2(("gdth_internal_cmd() service %d opcode %d\n",service,opcode)); |
1825 | 1548 | ||
1826 | ha = HADATA(gdth_ctr_tab[hanum]); | ||
1827 | cmd_ptr = ha->pccb; | 1549 | cmd_ptr = ha->pccb; |
1828 | memset((char*)cmd_ptr,0,sizeof(gdth_cmd_str)); | 1550 | memset((char*)cmd_ptr,0,sizeof(gdth_cmd_str)); |
1829 | 1551 | ||
@@ -1831,11 +1553,11 @@ static int gdth_internal_cmd(int hanum,unchar service,ushort opcode,ulong32 p1, | |||
1831 | for (retries = INIT_RETRIES;;) { | 1553 | for (retries = INIT_RETRIES;;) { |
1832 | cmd_ptr->Service = service; | 1554 | cmd_ptr->Service = service; |
1833 | cmd_ptr->RequestBuffer = INTERNAL_CMND; | 1555 | cmd_ptr->RequestBuffer = INTERNAL_CMND; |
1834 | if (!(index=gdth_get_cmd_index(hanum))) { | 1556 | if (!(index=gdth_get_cmd_index(ha))) { |
1835 | TRACE(("GDT: No free command index found\n")); | 1557 | TRACE(("GDT: No free command index found\n")); |
1836 | return 0; | 1558 | return 0; |
1837 | } | 1559 | } |
1838 | gdth_set_sema0(hanum); | 1560 | gdth_set_sema0(ha); |
1839 | cmd_ptr->OpCode = opcode; | 1561 | cmd_ptr->OpCode = opcode; |
1840 | cmd_ptr->BoardNode = LOCALBOARD; | 1562 | cmd_ptr->BoardNode = LOCALBOARD; |
1841 | if (service == CACHESERVICE) { | 1563 | if (service == CACHESERVICE) { |
@@ -1875,10 +1597,10 @@ static int gdth_internal_cmd(int hanum,unchar service,ushort opcode,ulong32 p1, | |||
1875 | ha->cmd_len = sizeof(gdth_cmd_str); | 1597 | ha->cmd_len = sizeof(gdth_cmd_str); |
1876 | ha->cmd_offs_dpmem = 0; | 1598 | ha->cmd_offs_dpmem = 0; |
1877 | ha->cmd_cnt = 0; | 1599 | ha->cmd_cnt = 0; |
1878 | gdth_copy_command(hanum); | 1600 | gdth_copy_command(ha); |
1879 | gdth_release_event(hanum); | 1601 | gdth_release_event(ha); |
1880 | gdth_delay(20); | 1602 | gdth_delay(20); |
1881 | if (!gdth_wait(hanum,index,INIT_TIMEOUT)) { | 1603 | if (!gdth_wait(ha, index, INIT_TIMEOUT)) { |
1882 | printk("GDT: Initialization error (timeout service %d)\n",service); | 1604 | printk("GDT: Initialization error (timeout service %d)\n",service); |
1883 | return 0; | 1605 | return 0; |
1884 | } | 1606 | } |
@@ -1893,9 +1615,8 @@ static int gdth_internal_cmd(int hanum,unchar service,ushort opcode,ulong32 p1, | |||
1893 | 1615 | ||
1894 | /* search for devices */ | 1616 | /* search for devices */ |
1895 | 1617 | ||
1896 | static int __init gdth_search_drives(int hanum) | 1618 | static int __init gdth_search_drives(gdth_ha_str *ha) |
1897 | { | 1619 | { |
1898 | register gdth_ha_str *ha; | ||
1899 | ushort cdev_cnt, i; | 1620 | ushort cdev_cnt, i; |
1900 | int ok; | 1621 | int ok; |
1901 | ulong32 bus_no, drv_cnt, drv_no, j; | 1622 | ulong32 bus_no, drv_cnt, drv_no, j; |
@@ -1915,22 +1636,21 @@ static int __init gdth_search_drives(int hanum) | |||
1915 | ulong flags; | 1636 | ulong flags; |
1916 | #endif | 1637 | #endif |
1917 | 1638 | ||
1918 | TRACE(("gdth_search_drives() hanum %d\n",hanum)); | 1639 | TRACE(("gdth_search_drives() hanum %d\n", ha->hanum)); |
1919 | ha = HADATA(gdth_ctr_tab[hanum]); | ||
1920 | ok = 0; | 1640 | ok = 0; |
1921 | 1641 | ||
1922 | /* initialize controller services, at first: screen service */ | 1642 | /* initialize controller services, at first: screen service */ |
1923 | ha->screen_feat = 0; | 1643 | ha->screen_feat = 0; |
1924 | if (!force_dma32) { | 1644 | if (!force_dma32) { |
1925 | ok = gdth_internal_cmd(hanum,SCREENSERVICE,GDT_X_INIT_SCR,0,0,0); | 1645 | ok = gdth_internal_cmd(ha, SCREENSERVICE, GDT_X_INIT_SCR, 0, 0, 0); |
1926 | if (ok) | 1646 | if (ok) |
1927 | ha->screen_feat = GDT_64BIT; | 1647 | ha->screen_feat = GDT_64BIT; |
1928 | } | 1648 | } |
1929 | if (force_dma32 || (!ok && ha->status == (ushort)S_NOFUNC)) | 1649 | if (force_dma32 || (!ok && ha->status == (ushort)S_NOFUNC)) |
1930 | ok = gdth_internal_cmd(hanum,SCREENSERVICE,GDT_INIT,0,0,0); | 1650 | ok = gdth_internal_cmd(ha, SCREENSERVICE, GDT_INIT, 0, 0, 0); |
1931 | if (!ok) { | 1651 | if (!ok) { |
1932 | printk("GDT-HA %d: Initialization error screen service (code %d)\n", | 1652 | printk("GDT-HA %d: Initialization error screen service (code %d)\n", |
1933 | hanum, ha->status); | 1653 | ha->hanum, ha->status); |
1934 | return 0; | 1654 | return 0; |
1935 | } | 1655 | } |
1936 | TRACE2(("gdth_search_drives(): SCREENSERVICE initialized\n")); | 1656 | TRACE2(("gdth_search_drives(): SCREENSERVICE initialized\n")); |
@@ -1954,25 +1674,26 @@ static int __init gdth_search_drives(int hanum) | |||
1954 | TRACE2(("gdth_search_drives(): RTC: %x/%x/%x\n",*(ulong32 *)&rtc[0], | 1674 | TRACE2(("gdth_search_drives(): RTC: %x/%x/%x\n",*(ulong32 *)&rtc[0], |
1955 | *(ulong32 *)&rtc[4], *(ulong32 *)&rtc[8])); | 1675 | *(ulong32 *)&rtc[4], *(ulong32 *)&rtc[8])); |
1956 | /* 3. send to controller firmware */ | 1676 | /* 3. send to controller firmware */ |
1957 | gdth_internal_cmd(hanum,SCREENSERVICE,GDT_REALTIME, *(ulong32 *)&rtc[0], | 1677 | gdth_internal_cmd(ha, SCREENSERVICE, GDT_REALTIME, *(ulong32 *)&rtc[0], |
1958 | *(ulong32 *)&rtc[4], *(ulong32 *)&rtc[8]); | 1678 | *(ulong32 *)&rtc[4], *(ulong32 *)&rtc[8]); |
1959 | #endif | 1679 | #endif |
1960 | 1680 | ||
1961 | /* unfreeze all IOs */ | 1681 | /* unfreeze all IOs */ |
1962 | gdth_internal_cmd(hanum,CACHESERVICE,GDT_UNFREEZE_IO,0,0,0); | 1682 | gdth_internal_cmd(ha, CACHESERVICE, GDT_UNFREEZE_IO, 0, 0, 0); |
1963 | 1683 | ||
1964 | /* initialize cache service */ | 1684 | /* initialize cache service */ |
1965 | ha->cache_feat = 0; | 1685 | ha->cache_feat = 0; |
1966 | if (!force_dma32) { | 1686 | if (!force_dma32) { |
1967 | ok = gdth_internal_cmd(hanum,CACHESERVICE,GDT_X_INIT_HOST,LINUX_OS,0,0); | 1687 | ok = gdth_internal_cmd(ha, CACHESERVICE, GDT_X_INIT_HOST, LINUX_OS, |
1688 | 0, 0); | ||
1968 | if (ok) | 1689 | if (ok) |
1969 | ha->cache_feat = GDT_64BIT; | 1690 | ha->cache_feat = GDT_64BIT; |
1970 | } | 1691 | } |
1971 | if (force_dma32 || (!ok && ha->status == (ushort)S_NOFUNC)) | 1692 | if (force_dma32 || (!ok && ha->status == (ushort)S_NOFUNC)) |
1972 | ok = gdth_internal_cmd(hanum,CACHESERVICE,GDT_INIT,LINUX_OS,0,0); | 1693 | ok = gdth_internal_cmd(ha, CACHESERVICE, GDT_INIT, LINUX_OS, 0, 0); |
1973 | if (!ok) { | 1694 | if (!ok) { |
1974 | printk("GDT-HA %d: Initialization error cache service (code %d)\n", | 1695 | printk("GDT-HA %d: Initialization error cache service (code %d)\n", |
1975 | hanum, ha->status); | 1696 | ha->hanum, ha->status); |
1976 | return 0; | 1697 | return 0; |
1977 | } | 1698 | } |
1978 | TRACE2(("gdth_search_drives(): CACHESERVICE initialized\n")); | 1699 | TRACE2(("gdth_search_drives(): CACHESERVICE initialized\n")); |
@@ -2001,9 +1722,9 @@ static int __init gdth_search_drives(int hanum) | |||
2001 | pmod->cmd_buff_size = 0; | 1722 | pmod->cmd_buff_size = 0; |
2002 | pmod->reserved1 = 0; | 1723 | pmod->reserved1 = 0; |
2003 | pmod->reserved2 = 0; | 1724 | pmod->reserved2 = 0; |
2004 | if (gdth_internal_cmd(hanum,CACHESERVICE,GDT_IOCTL,SET_PERF_MODES, | 1725 | if (gdth_internal_cmd(ha, CACHESERVICE, GDT_IOCTL, SET_PERF_MODES, |
2005 | INVALID_CHANNEL,sizeof(gdth_perf_modes))) { | 1726 | INVALID_CHANNEL,sizeof(gdth_perf_modes))) { |
2006 | printk("GDT-HA %d: Interrupt coalescing activated\n", hanum); | 1727 | printk("GDT-HA %d: Interrupt coalescing activated\n", ha->hanum); |
2007 | } | 1728 | } |
2008 | } | 1729 | } |
2009 | #endif | 1730 | #endif |
@@ -2015,7 +1736,7 @@ static int __init gdth_search_drives(int hanum) | |||
2015 | iocr->hdr.first_chan = 0; | 1736 | iocr->hdr.first_chan = 0; |
2016 | iocr->hdr.last_chan = MAXBUS-1; | 1737 | iocr->hdr.last_chan = MAXBUS-1; |
2017 | iocr->hdr.list_offset = GDTOFFSOF(gdth_raw_iochan_str, list[0]); | 1738 | iocr->hdr.list_offset = GDTOFFSOF(gdth_raw_iochan_str, list[0]); |
2018 | if (gdth_internal_cmd(hanum,CACHESERVICE,GDT_IOCTL,IOCHAN_RAW_DESC, | 1739 | if (gdth_internal_cmd(ha, CACHESERVICE, GDT_IOCTL, IOCHAN_RAW_DESC, |
2019 | INVALID_CHANNEL,sizeof(gdth_raw_iochan_str))) { | 1740 | INVALID_CHANNEL,sizeof(gdth_raw_iochan_str))) { |
2020 | TRACE2(("IOCHAN_RAW_DESC supported!\n")); | 1741 | TRACE2(("IOCHAN_RAW_DESC supported!\n")); |
2021 | ha->bus_cnt = iocr->hdr.chan_count; | 1742 | ha->bus_cnt = iocr->hdr.chan_count; |
@@ -2030,13 +1751,13 @@ static int __init gdth_search_drives(int hanum) | |||
2030 | chn = (gdth_getch_str *)ha->pscratch; | 1751 | chn = (gdth_getch_str *)ha->pscratch; |
2031 | for (bus_no = 0; bus_no < MAXBUS; ++bus_no) { | 1752 | for (bus_no = 0; bus_no < MAXBUS; ++bus_no) { |
2032 | chn->channel_no = bus_no; | 1753 | chn->channel_no = bus_no; |
2033 | if (!gdth_internal_cmd(hanum,CACHESERVICE,GDT_IOCTL, | 1754 | if (!gdth_internal_cmd(ha, CACHESERVICE, GDT_IOCTL, |
2034 | SCSI_CHAN_CNT | L_CTRL_PATTERN, | 1755 | SCSI_CHAN_CNT | L_CTRL_PATTERN, |
2035 | IO_CHANNEL | INVALID_CHANNEL, | 1756 | IO_CHANNEL | INVALID_CHANNEL, |
2036 | sizeof(gdth_getch_str))) { | 1757 | sizeof(gdth_getch_str))) { |
2037 | if (bus_no == 0) { | 1758 | if (bus_no == 0) { |
2038 | printk("GDT-HA %d: Error detecting channel count (0x%x)\n", | 1759 | printk("GDT-HA %d: Error detecting channel count (0x%x)\n", |
2039 | hanum, ha->status); | 1760 | ha->hanum, ha->status); |
2040 | return 0; | 1761 | return 0; |
2041 | } | 1762 | } |
2042 | break; | 1763 | break; |
@@ -2051,10 +1772,10 @@ static int __init gdth_search_drives(int hanum) | |||
2051 | TRACE2(("gdth_search_drives() %d channels\n",ha->bus_cnt)); | 1772 | TRACE2(("gdth_search_drives() %d channels\n",ha->bus_cnt)); |
2052 | 1773 | ||
2053 | /* read cache configuration */ | 1774 | /* read cache configuration */ |
2054 | if (!gdth_internal_cmd(hanum,CACHESERVICE,GDT_IOCTL,CACHE_INFO, | 1775 | if (!gdth_internal_cmd(ha, CACHESERVICE, GDT_IOCTL, CACHE_INFO, |
2055 | INVALID_CHANNEL,sizeof(gdth_cinfo_str))) { | 1776 | INVALID_CHANNEL,sizeof(gdth_cinfo_str))) { |
2056 | printk("GDT-HA %d: Initialization error cache service (code %d)\n", | 1777 | printk("GDT-HA %d: Initialization error cache service (code %d)\n", |
2057 | hanum, ha->status); | 1778 | ha->hanum, ha->status); |
2058 | return 0; | 1779 | return 0; |
2059 | } | 1780 | } |
2060 | ha->cpar = ((gdth_cinfo_str *)ha->pscratch)->cpar; | 1781 | ha->cpar = ((gdth_cinfo_str *)ha->pscratch)->cpar; |
@@ -2064,11 +1785,11 @@ static int __init gdth_search_drives(int hanum) | |||
2064 | 1785 | ||
2065 | /* read board info and features */ | 1786 | /* read board info and features */ |
2066 | ha->more_proc = FALSE; | 1787 | ha->more_proc = FALSE; |
2067 | if (gdth_internal_cmd(hanum,CACHESERVICE,GDT_IOCTL,BOARD_INFO, | 1788 | if (gdth_internal_cmd(ha, CACHESERVICE, GDT_IOCTL, BOARD_INFO, |
2068 | INVALID_CHANNEL,sizeof(gdth_binfo_str))) { | 1789 | INVALID_CHANNEL,sizeof(gdth_binfo_str))) { |
2069 | memcpy(&ha->binfo, (gdth_binfo_str *)ha->pscratch, | 1790 | memcpy(&ha->binfo, (gdth_binfo_str *)ha->pscratch, |
2070 | sizeof(gdth_binfo_str)); | 1791 | sizeof(gdth_binfo_str)); |
2071 | if (gdth_internal_cmd(hanum,CACHESERVICE,GDT_IOCTL,BOARD_FEATURES, | 1792 | if (gdth_internal_cmd(ha, CACHESERVICE, GDT_IOCTL, BOARD_FEATURES, |
2072 | INVALID_CHANNEL,sizeof(gdth_bfeat_str))) { | 1793 | INVALID_CHANNEL,sizeof(gdth_bfeat_str))) { |
2073 | TRACE2(("BOARD_INFO/BOARD_FEATURES supported\n")); | 1794 | TRACE2(("BOARD_INFO/BOARD_FEATURES supported\n")); |
2074 | ha->bfeat = *(gdth_bfeat_str *)ha->pscratch; | 1795 | ha->bfeat = *(gdth_bfeat_str *)ha->pscratch; |
@@ -2076,7 +1797,7 @@ static int __init gdth_search_drives(int hanum) | |||
2076 | } | 1797 | } |
2077 | } else { | 1798 | } else { |
2078 | TRACE2(("BOARD_INFO requires firmware >= 1.10/2.08\n")); | 1799 | TRACE2(("BOARD_INFO requires firmware >= 1.10/2.08\n")); |
2079 | strcpy(ha->binfo.type_string, gdth_ctr_name(hanum)); | 1800 | strcpy(ha->binfo.type_string, gdth_ctr_name(ha)); |
2080 | } | 1801 | } |
2081 | TRACE2(("Controller name: %s\n",ha->binfo.type_string)); | 1802 | TRACE2(("Controller name: %s\n",ha->binfo.type_string)); |
2082 | 1803 | ||
@@ -2089,7 +1810,7 @@ static int __init gdth_search_drives(int hanum) | |||
2089 | ioc->hdr.first_chan = 0; | 1810 | ioc->hdr.first_chan = 0; |
2090 | ioc->hdr.last_chan = MAXBUS-1; | 1811 | ioc->hdr.last_chan = MAXBUS-1; |
2091 | ioc->hdr.list_offset = GDTOFFSOF(gdth_iochan_str, list[0]); | 1812 | ioc->hdr.list_offset = GDTOFFSOF(gdth_iochan_str, list[0]); |
2092 | if (gdth_internal_cmd(hanum,CACHESERVICE,GDT_IOCTL,IOCHAN_DESC, | 1813 | if (gdth_internal_cmd(ha, CACHESERVICE, GDT_IOCTL, IOCHAN_DESC, |
2093 | INVALID_CHANNEL,sizeof(gdth_iochan_str))) { | 1814 | INVALID_CHANNEL,sizeof(gdth_iochan_str))) { |
2094 | for (bus_no = 0; bus_no < ha->bus_cnt; ++bus_no) { | 1815 | for (bus_no = 0; bus_no < ha->bus_cnt; ++bus_no) { |
2095 | ha->raw[bus_no].address = ioc->list[bus_no].address; | 1816 | ha->raw[bus_no].address = ioc->list[bus_no].address; |
@@ -2104,7 +1825,7 @@ static int __init gdth_search_drives(int hanum) | |||
2104 | for (bus_no = 0; bus_no < ha->bus_cnt; ++bus_no) { | 1825 | for (bus_no = 0; bus_no < ha->bus_cnt; ++bus_no) { |
2105 | chn = (gdth_getch_str *)ha->pscratch; | 1826 | chn = (gdth_getch_str *)ha->pscratch; |
2106 | chn->channel_no = ha->raw[bus_no].local_no; | 1827 | chn->channel_no = ha->raw[bus_no].local_no; |
2107 | if (gdth_internal_cmd(hanum,CACHESERVICE,GDT_IOCTL, | 1828 | if (gdth_internal_cmd(ha, CACHESERVICE, GDT_IOCTL, |
2108 | SCSI_CHAN_CNT | L_CTRL_PATTERN, | 1829 | SCSI_CHAN_CNT | L_CTRL_PATTERN, |
2109 | ha->raw[bus_no].address | INVALID_CHANNEL, | 1830 | ha->raw[bus_no].address | INVALID_CHANNEL, |
2110 | sizeof(gdth_getch_str))) { | 1831 | sizeof(gdth_getch_str))) { |
@@ -2116,7 +1837,7 @@ static int __init gdth_search_drives(int hanum) | |||
2116 | drl = (gdth_drlist_str *)ha->pscratch; | 1837 | drl = (gdth_drlist_str *)ha->pscratch; |
2117 | drl->sc_no = ha->raw[bus_no].local_no; | 1838 | drl->sc_no = ha->raw[bus_no].local_no; |
2118 | drl->sc_cnt = ha->raw[bus_no].pdev_cnt; | 1839 | drl->sc_cnt = ha->raw[bus_no].pdev_cnt; |
2119 | if (gdth_internal_cmd(hanum,CACHESERVICE,GDT_IOCTL, | 1840 | if (gdth_internal_cmd(ha, CACHESERVICE, GDT_IOCTL, |
2120 | SCSI_DR_LIST | L_CTRL_PATTERN, | 1841 | SCSI_DR_LIST | L_CTRL_PATTERN, |
2121 | ha->raw[bus_no].address | INVALID_CHANNEL, | 1842 | ha->raw[bus_no].address | INVALID_CHANNEL, |
2122 | sizeof(gdth_drlist_str))) { | 1843 | sizeof(gdth_drlist_str))) { |
@@ -2129,10 +1850,10 @@ static int __init gdth_search_drives(int hanum) | |||
2129 | } | 1850 | } |
2130 | 1851 | ||
2131 | /* logical drives */ | 1852 | /* logical drives */ |
2132 | if (gdth_internal_cmd(hanum,CACHESERVICE,GDT_IOCTL,CACHE_DRV_CNT, | 1853 | if (gdth_internal_cmd(ha, CACHESERVICE, GDT_IOCTL, CACHE_DRV_CNT, |
2133 | INVALID_CHANNEL,sizeof(ulong32))) { | 1854 | INVALID_CHANNEL,sizeof(ulong32))) { |
2134 | drv_cnt = *(ulong32 *)ha->pscratch; | 1855 | drv_cnt = *(ulong32 *)ha->pscratch; |
2135 | if (gdth_internal_cmd(hanum,CACHESERVICE,GDT_IOCTL,CACHE_DRV_LIST, | 1856 | if (gdth_internal_cmd(ha, CACHESERVICE, GDT_IOCTL, CACHE_DRV_LIST, |
2136 | INVALID_CHANNEL,drv_cnt * sizeof(ulong32))) { | 1857 | INVALID_CHANNEL,drv_cnt * sizeof(ulong32))) { |
2137 | for (j = 0; j < drv_cnt; ++j) { | 1858 | for (j = 0; j < drv_cnt; ++j) { |
2138 | drv_no = ((ulong32 *)ha->pscratch)[j]; | 1859 | drv_no = ((ulong32 *)ha->pscratch)[j]; |
@@ -2146,7 +1867,7 @@ static int __init gdth_search_drives(int hanum) | |||
2146 | alst->entries_avail = MAX_LDRIVES; | 1867 | alst->entries_avail = MAX_LDRIVES; |
2147 | alst->first_entry = 0; | 1868 | alst->first_entry = 0; |
2148 | alst->list_offset = GDTOFFSOF(gdth_arcdl_str, list[0]); | 1869 | alst->list_offset = GDTOFFSOF(gdth_arcdl_str, list[0]); |
2149 | if (gdth_internal_cmd(hanum,CACHESERVICE,GDT_IOCTL, | 1870 | if (gdth_internal_cmd(ha, CACHESERVICE, GDT_IOCTL, |
2150 | ARRAY_DRV_LIST2 | LA_CTRL_PATTERN, | 1871 | ARRAY_DRV_LIST2 | LA_CTRL_PATTERN, |
2151 | INVALID_CHANNEL, sizeof(gdth_arcdl_str) + | 1872 | INVALID_CHANNEL, sizeof(gdth_arcdl_str) + |
2152 | (alst->entries_avail-1) * sizeof(gdth_alist_str))) { | 1873 | (alst->entries_avail-1) * sizeof(gdth_alist_str))) { |
@@ -2157,7 +1878,7 @@ static int __init gdth_search_drives(int hanum) | |||
2157 | ha->hdr[j].is_hotfix = alst->list[j].is_hotfix; | 1878 | ha->hdr[j].is_hotfix = alst->list[j].is_hotfix; |
2158 | ha->hdr[j].master_no = alst->list[j].cd_handle; | 1879 | ha->hdr[j].master_no = alst->list[j].cd_handle; |
2159 | } | 1880 | } |
2160 | } else if (gdth_internal_cmd(hanum,CACHESERVICE,GDT_IOCTL, | 1881 | } else if (gdth_internal_cmd(ha, CACHESERVICE, GDT_IOCTL, |
2161 | ARRAY_DRV_LIST | LA_CTRL_PATTERN, | 1882 | ARRAY_DRV_LIST | LA_CTRL_PATTERN, |
2162 | 0, 35 * sizeof(gdth_alist_str))) { | 1883 | 0, 35 * sizeof(gdth_alist_str))) { |
2163 | for (j = 0; j < 35; ++j) { | 1884 | for (j = 0; j < 35; ++j) { |
@@ -2175,24 +1896,24 @@ static int __init gdth_search_drives(int hanum) | |||
2175 | /* initialize raw service */ | 1896 | /* initialize raw service */ |
2176 | ha->raw_feat = 0; | 1897 | ha->raw_feat = 0; |
2177 | if (!force_dma32) { | 1898 | if (!force_dma32) { |
2178 | ok = gdth_internal_cmd(hanum,SCSIRAWSERVICE,GDT_X_INIT_RAW,0,0,0); | 1899 | ok = gdth_internal_cmd(ha, SCSIRAWSERVICE, GDT_X_INIT_RAW, 0, 0, 0); |
2179 | if (ok) | 1900 | if (ok) |
2180 | ha->raw_feat = GDT_64BIT; | 1901 | ha->raw_feat = GDT_64BIT; |
2181 | } | 1902 | } |
2182 | if (force_dma32 || (!ok && ha->status == (ushort)S_NOFUNC)) | 1903 | if (force_dma32 || (!ok && ha->status == (ushort)S_NOFUNC)) |
2183 | ok = gdth_internal_cmd(hanum,SCSIRAWSERVICE,GDT_INIT,0,0,0); | 1904 | ok = gdth_internal_cmd(ha, SCSIRAWSERVICE, GDT_INIT, 0, 0, 0); |
2184 | if (!ok) { | 1905 | if (!ok) { |
2185 | printk("GDT-HA %d: Initialization error raw service (code %d)\n", | 1906 | printk("GDT-HA %d: Initialization error raw service (code %d)\n", |
2186 | hanum, ha->status); | 1907 | ha->hanum, ha->status); |
2187 | return 0; | 1908 | return 0; |
2188 | } | 1909 | } |
2189 | TRACE2(("gdth_search_drives(): RAWSERVICE initialized\n")); | 1910 | TRACE2(("gdth_search_drives(): RAWSERVICE initialized\n")); |
2190 | 1911 | ||
2191 | /* set/get features raw service (scatter/gather) */ | 1912 | /* set/get features raw service (scatter/gather) */ |
2192 | if (gdth_internal_cmd(hanum,SCSIRAWSERVICE,GDT_SET_FEAT,SCATTER_GATHER, | 1913 | if (gdth_internal_cmd(ha, SCSIRAWSERVICE, GDT_SET_FEAT, SCATTER_GATHER, |
2193 | 0,0)) { | 1914 | 0, 0)) { |
2194 | TRACE2(("gdth_search_drives(): set features RAWSERVICE OK\n")); | 1915 | TRACE2(("gdth_search_drives(): set features RAWSERVICE OK\n")); |
2195 | if (gdth_internal_cmd(hanum,SCSIRAWSERVICE,GDT_GET_FEAT,0,0,0)) { | 1916 | if (gdth_internal_cmd(ha, SCSIRAWSERVICE, GDT_GET_FEAT, 0, 0, 0)) { |
2196 | TRACE2(("gdth_search_dr(): get feat RAWSERVICE %d\n", | 1917 | TRACE2(("gdth_search_dr(): get feat RAWSERVICE %d\n", |
2197 | ha->info)); | 1918 | ha->info)); |
2198 | ha->raw_feat |= (ushort)ha->info; | 1919 | ha->raw_feat |= (ushort)ha->info; |
@@ -2200,10 +1921,10 @@ static int __init gdth_search_drives(int hanum) | |||
2200 | } | 1921 | } |
2201 | 1922 | ||
2202 | /* set/get features cache service (equal to raw service) */ | 1923 | /* set/get features cache service (equal to raw service) */ |
2203 | if (gdth_internal_cmd(hanum,CACHESERVICE,GDT_SET_FEAT,0, | 1924 | if (gdth_internal_cmd(ha, CACHESERVICE, GDT_SET_FEAT, 0, |
2204 | SCATTER_GATHER,0)) { | 1925 | SCATTER_GATHER,0)) { |
2205 | TRACE2(("gdth_search_drives(): set features CACHESERVICE OK\n")); | 1926 | TRACE2(("gdth_search_drives(): set features CACHESERVICE OK\n")); |
2206 | if (gdth_internal_cmd(hanum,CACHESERVICE,GDT_GET_FEAT,0,0,0)) { | 1927 | if (gdth_internal_cmd(ha, CACHESERVICE, GDT_GET_FEAT, 0, 0, 0)) { |
2207 | TRACE2(("gdth_search_dr(): get feat CACHESERV. %d\n", | 1928 | TRACE2(("gdth_search_dr(): get feat CACHESERV. %d\n", |
2208 | ha->info)); | 1929 | ha->info)); |
2209 | ha->cache_feat |= (ushort)ha->info; | 1930 | ha->cache_feat |= (ushort)ha->info; |
@@ -2212,22 +1933,22 @@ static int __init gdth_search_drives(int hanum) | |||
2212 | 1933 | ||
2213 | /* reserve drives for raw service */ | 1934 | /* reserve drives for raw service */ |
2214 | if (reserve_mode != 0) { | 1935 | if (reserve_mode != 0) { |
2215 | gdth_internal_cmd(hanum,SCSIRAWSERVICE,GDT_RESERVE_ALL, | 1936 | gdth_internal_cmd(ha, SCSIRAWSERVICE, GDT_RESERVE_ALL, |
2216 | reserve_mode == 1 ? 1 : 3, 0, 0); | 1937 | reserve_mode == 1 ? 1 : 3, 0, 0); |
2217 | TRACE2(("gdth_search_drives(): RESERVE_ALL code %d\n", | 1938 | TRACE2(("gdth_search_drives(): RESERVE_ALL code %d\n", |
2218 | ha->status)); | 1939 | ha->status)); |
2219 | } | 1940 | } |
2220 | for (i = 0; i < MAX_RES_ARGS; i += 4) { | 1941 | for (i = 0; i < MAX_RES_ARGS; i += 4) { |
2221 | if (reserve_list[i] == hanum && reserve_list[i+1] < ha->bus_cnt && | 1942 | if (reserve_list[i] == ha->hanum && reserve_list[i+1] < ha->bus_cnt && |
2222 | reserve_list[i+2] < ha->tid_cnt && reserve_list[i+3] < MAXLUN) { | 1943 | reserve_list[i+2] < ha->tid_cnt && reserve_list[i+3] < MAXLUN) { |
2223 | TRACE2(("gdth_search_drives(): reserve ha %d bus %d id %d lun %d\n", | 1944 | TRACE2(("gdth_search_drives(): reserve ha %d bus %d id %d lun %d\n", |
2224 | reserve_list[i], reserve_list[i+1], | 1945 | reserve_list[i], reserve_list[i+1], |
2225 | reserve_list[i+2], reserve_list[i+3])); | 1946 | reserve_list[i+2], reserve_list[i+3])); |
2226 | if (!gdth_internal_cmd(hanum,SCSIRAWSERVICE,GDT_RESERVE,0, | 1947 | if (!gdth_internal_cmd(ha, SCSIRAWSERVICE, GDT_RESERVE, 0, |
2227 | reserve_list[i+1], reserve_list[i+2] | | 1948 | reserve_list[i+1], reserve_list[i+2] | |
2228 | (reserve_list[i+3] << 8))) { | 1949 | (reserve_list[i+3] << 8))) { |
2229 | printk("GDT-HA %d: Error raw service (RESERVE, code %d)\n", | 1950 | printk("GDT-HA %d: Error raw service (RESERVE, code %d)\n", |
2230 | hanum, ha->status); | 1951 | ha->hanum, ha->status); |
2231 | } | 1952 | } |
2232 | } | 1953 | } |
2233 | } | 1954 | } |
@@ -2236,58 +1957,44 @@ static int __init gdth_search_drives(int hanum) | |||
2236 | oemstr = (gdth_oem_str_ioctl *)ha->pscratch; | 1957 | oemstr = (gdth_oem_str_ioctl *)ha->pscratch; |
2237 | oemstr->params.ctl_version = 0x01; | 1958 | oemstr->params.ctl_version = 0x01; |
2238 | oemstr->params.buffer_size = sizeof(oemstr->text); | 1959 | oemstr->params.buffer_size = sizeof(oemstr->text); |
2239 | if (gdth_internal_cmd(hanum,CACHESERVICE,GDT_IOCTL, | 1960 | if (gdth_internal_cmd(ha, CACHESERVICE, GDT_IOCTL, |
2240 | CACHE_READ_OEM_STRING_RECORD,INVALID_CHANNEL, | 1961 | CACHE_READ_OEM_STRING_RECORD,INVALID_CHANNEL, |
2241 | sizeof(gdth_oem_str_ioctl))) { | 1962 | sizeof(gdth_oem_str_ioctl))) { |
2242 | TRACE2(("gdth_search_drives(): CACHE_READ_OEM_STRING_RECORD OK\n")); | 1963 | TRACE2(("gdth_search_drives(): CACHE_READ_OEM_STRING_RECORD OK\n")); |
2243 | printk("GDT-HA %d: Vendor: %s Name: %s\n", | 1964 | printk("GDT-HA %d: Vendor: %s Name: %s\n", |
2244 | hanum,oemstr->text.oem_company_name,ha->binfo.type_string); | 1965 | ha->hanum, oemstr->text.oem_company_name, ha->binfo.type_string); |
2245 | /* Save the Host Drive inquiry data */ | 1966 | /* Save the Host Drive inquiry data */ |
2246 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) | ||
2247 | strlcpy(ha->oem_name,oemstr->text.scsi_host_drive_inquiry_vendor_id, | 1967 | strlcpy(ha->oem_name,oemstr->text.scsi_host_drive_inquiry_vendor_id, |
2248 | sizeof(ha->oem_name)); | 1968 | sizeof(ha->oem_name)); |
2249 | #else | ||
2250 | strncpy(ha->oem_name,oemstr->text.scsi_host_drive_inquiry_vendor_id,7); | ||
2251 | ha->oem_name[7] = '\0'; | ||
2252 | #endif | ||
2253 | } else { | 1969 | } else { |
2254 | /* Old method, based on PCI ID */ | 1970 | /* Old method, based on PCI ID */ |
2255 | TRACE2(("gdth_search_drives(): CACHE_READ_OEM_STRING_RECORD failed\n")); | 1971 | TRACE2(("gdth_search_drives(): CACHE_READ_OEM_STRING_RECORD failed\n")); |
2256 | printk("GDT-HA %d: Name: %s\n", | 1972 | printk("GDT-HA %d: Name: %s\n", |
2257 | hanum,ha->binfo.type_string); | 1973 | ha->hanum, ha->binfo.type_string); |
2258 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) | ||
2259 | if (ha->oem_id == OEM_ID_INTEL) | 1974 | if (ha->oem_id == OEM_ID_INTEL) |
2260 | strlcpy(ha->oem_name,"Intel ", sizeof(ha->oem_name)); | 1975 | strlcpy(ha->oem_name,"Intel ", sizeof(ha->oem_name)); |
2261 | else | 1976 | else |
2262 | strlcpy(ha->oem_name,"ICP ", sizeof(ha->oem_name)); | 1977 | strlcpy(ha->oem_name,"ICP ", sizeof(ha->oem_name)); |
2263 | #else | ||
2264 | if (ha->oem_id == OEM_ID_INTEL) | ||
2265 | strcpy(ha->oem_name,"Intel "); | ||
2266 | else | ||
2267 | strcpy(ha->oem_name,"ICP "); | ||
2268 | #endif | ||
2269 | } | 1978 | } |
2270 | 1979 | ||
2271 | /* scanning for host drives */ | 1980 | /* scanning for host drives */ |
2272 | for (i = 0; i < cdev_cnt; ++i) | 1981 | for (i = 0; i < cdev_cnt; ++i) |
2273 | gdth_analyse_hdrive(hanum,i); | 1982 | gdth_analyse_hdrive(ha, i); |
2274 | 1983 | ||
2275 | TRACE(("gdth_search_drives() OK\n")); | 1984 | TRACE(("gdth_search_drives() OK\n")); |
2276 | return 1; | 1985 | return 1; |
2277 | } | 1986 | } |
2278 | 1987 | ||
2279 | static int gdth_analyse_hdrive(int hanum,ushort hdrive) | 1988 | static int gdth_analyse_hdrive(gdth_ha_str *ha, ushort hdrive) |
2280 | { | 1989 | { |
2281 | register gdth_ha_str *ha; | ||
2282 | ulong32 drv_cyls; | 1990 | ulong32 drv_cyls; |
2283 | int drv_hds, drv_secs; | 1991 | int drv_hds, drv_secs; |
2284 | 1992 | ||
2285 | TRACE(("gdth_analyse_hdrive() hanum %d drive %d\n",hanum,hdrive)); | 1993 | TRACE(("gdth_analyse_hdrive() hanum %d drive %d\n", ha->hanum, hdrive)); |
2286 | if (hdrive >= MAX_HDRIVES) | 1994 | if (hdrive >= MAX_HDRIVES) |
2287 | return 0; | 1995 | return 0; |
2288 | ha = HADATA(gdth_ctr_tab[hanum]); | ||
2289 | 1996 | ||
2290 | if (!gdth_internal_cmd(hanum,CACHESERVICE,GDT_INFO,hdrive,0,0)) | 1997 | if (!gdth_internal_cmd(ha, CACHESERVICE, GDT_INFO, hdrive, 0, 0)) |
2291 | return 0; | 1998 | return 0; |
2292 | ha->hdr[hdrive].present = TRUE; | 1999 | ha->hdr[hdrive].present = TRUE; |
2293 | ha->hdr[hdrive].size = ha->info; | 2000 | ha->hdr[hdrive].size = ha->info; |
@@ -2307,7 +2014,7 @@ static int gdth_analyse_hdrive(int hanum,ushort hdrive) | |||
2307 | ha->hdr[hdrive].size = drv_cyls * drv_hds * drv_secs; | 2014 | ha->hdr[hdrive].size = drv_cyls * drv_hds * drv_secs; |
2308 | 2015 | ||
2309 | if (ha->cache_feat & GDT_64BIT) { | 2016 | if (ha->cache_feat & GDT_64BIT) { |
2310 | if (gdth_internal_cmd(hanum,CACHESERVICE,GDT_X_INFO,hdrive,0,0) | 2017 | if (gdth_internal_cmd(ha, CACHESERVICE, GDT_X_INFO, hdrive, 0, 0) |
2311 | && ha->info2 != 0) { | 2018 | && ha->info2 != 0) { |
2312 | ha->hdr[hdrive].size = ((ulong64)ha->info2 << 32) | ha->info; | 2019 | ha->hdr[hdrive].size = ((ulong64)ha->info2 << 32) | ha->info; |
2313 | } | 2020 | } |
@@ -2316,14 +2023,14 @@ static int gdth_analyse_hdrive(int hanum,ushort hdrive) | |||
2316 | hdrive,ha->hdr[hdrive].size,drv_hds,drv_secs)); | 2023 | hdrive,ha->hdr[hdrive].size,drv_hds,drv_secs)); |
2317 | 2024 | ||
2318 | /* get informations about device */ | 2025 | /* get informations about device */ |
2319 | if (gdth_internal_cmd(hanum,CACHESERVICE,GDT_DEVTYPE,hdrive,0,0)) { | 2026 | if (gdth_internal_cmd(ha, CACHESERVICE, GDT_DEVTYPE, hdrive, 0, 0)) { |
2320 | TRACE2(("gdth_search_dr() cache drive %d devtype %d\n", | 2027 | TRACE2(("gdth_search_dr() cache drive %d devtype %d\n", |
2321 | hdrive,ha->info)); | 2028 | hdrive,ha->info)); |
2322 | ha->hdr[hdrive].devtype = (ushort)ha->info; | 2029 | ha->hdr[hdrive].devtype = (ushort)ha->info; |
2323 | } | 2030 | } |
2324 | 2031 | ||
2325 | /* cluster info */ | 2032 | /* cluster info */ |
2326 | if (gdth_internal_cmd(hanum,CACHESERVICE,GDT_CLUST_INFO,hdrive,0,0)) { | 2033 | if (gdth_internal_cmd(ha, CACHESERVICE, GDT_CLUST_INFO, hdrive, 0, 0)) { |
2327 | TRACE2(("gdth_search_dr() cache drive %d cluster info %d\n", | 2034 | TRACE2(("gdth_search_dr() cache drive %d cluster info %d\n", |
2328 | hdrive,ha->info)); | 2035 | hdrive,ha->info)); |
2329 | if (!shared_access) | 2036 | if (!shared_access) |
@@ -2331,7 +2038,7 @@ static int gdth_analyse_hdrive(int hanum,ushort hdrive) | |||
2331 | } | 2038 | } |
2332 | 2039 | ||
2333 | /* R/W attributes */ | 2040 | /* R/W attributes */ |
2334 | if (gdth_internal_cmd(hanum,CACHESERVICE,GDT_RW_ATTRIBS,hdrive,0,0)) { | 2041 | if (gdth_internal_cmd(ha, CACHESERVICE, GDT_RW_ATTRIBS, hdrive, 0, 0)) { |
2335 | TRACE2(("gdth_search_dr() cache drive %d r/w attrib. %d\n", | 2042 | TRACE2(("gdth_search_dr() cache drive %d r/w attrib. %d\n", |
2336 | hdrive,ha->info)); | 2043 | hdrive,ha->info)); |
2337 | ha->hdr[hdrive].rw_attribs = (unchar)ha->info; | 2044 | ha->hdr[hdrive].rw_attribs = (unchar)ha->info; |
@@ -2343,27 +2050,26 @@ static int gdth_analyse_hdrive(int hanum,ushort hdrive) | |||
2343 | 2050 | ||
2344 | /* command queueing/sending functions */ | 2051 | /* command queueing/sending functions */ |
2345 | 2052 | ||
2346 | static void gdth_putq(int hanum,Scsi_Cmnd *scp,unchar priority) | 2053 | static void gdth_putq(gdth_ha_str *ha, Scsi_Cmnd *scp, unchar priority) |
2347 | { | 2054 | { |
2348 | register gdth_ha_str *ha; | 2055 | struct gdth_cmndinfo *cmndinfo = gdth_cmnd_priv(scp); |
2349 | register Scsi_Cmnd *pscp; | 2056 | register Scsi_Cmnd *pscp; |
2350 | register Scsi_Cmnd *nscp; | 2057 | register Scsi_Cmnd *nscp; |
2351 | ulong flags; | 2058 | ulong flags; |
2352 | unchar b, t; | 2059 | unchar b, t; |
2353 | 2060 | ||
2354 | TRACE(("gdth_putq() priority %d\n",priority)); | 2061 | TRACE(("gdth_putq() priority %d\n",priority)); |
2355 | ha = HADATA(gdth_ctr_tab[hanum]); | ||
2356 | spin_lock_irqsave(&ha->smp_lock, flags); | 2062 | spin_lock_irqsave(&ha->smp_lock, flags); |
2357 | 2063 | ||
2358 | if (scp->done != gdth_scsi_done) { | 2064 | if (!cmndinfo->internal_command) { |
2359 | scp->SCp.this_residual = (int)priority; | 2065 | cmndinfo->priority = priority; |
2360 | b = virt_ctr ? NUMDATA(scp->device->host)->busnum:scp->device->channel; | 2066 | b = scp->device->channel; |
2361 | t = scp->device->id; | 2067 | t = scp->device->id; |
2362 | if (priority >= DEFAULT_PRI) { | 2068 | if (priority >= DEFAULT_PRI) { |
2363 | if ((b != ha->virt_bus && ha->raw[BUS_L2P(ha,b)].lock) || | 2069 | if ((b != ha->virt_bus && ha->raw[BUS_L2P(ha,b)].lock) || |
2364 | (b==ha->virt_bus && t<MAX_HDRIVES && ha->hdr[t].lock)) { | 2070 | (b==ha->virt_bus && t<MAX_HDRIVES && ha->hdr[t].lock)) { |
2365 | TRACE2(("gdth_putq(): locked IO ->update_timeout()\n")); | 2071 | TRACE2(("gdth_putq(): locked IO ->update_timeout()\n")); |
2366 | scp->SCp.buffers_residual = gdth_update_timeout(hanum, scp, 0); | 2072 | cmndinfo->timeout = gdth_update_timeout(scp, 0); |
2367 | } | 2073 | } |
2368 | } | 2074 | } |
2369 | } | 2075 | } |
@@ -2375,7 +2081,7 @@ static void gdth_putq(int hanum,Scsi_Cmnd *scp,unchar priority) | |||
2375 | pscp = ha->req_first; | 2081 | pscp = ha->req_first; |
2376 | nscp = (Scsi_Cmnd *)pscp->SCp.ptr; | 2082 | nscp = (Scsi_Cmnd *)pscp->SCp.ptr; |
2377 | /* priority: 0-highest,..,0xff-lowest */ | 2083 | /* priority: 0-highest,..,0xff-lowest */ |
2378 | while (nscp && (unchar)nscp->SCp.this_residual <= priority) { | 2084 | while (nscp && gdth_cmnd_priv(nscp)->priority <= priority) { |
2379 | pscp = nscp; | 2085 | pscp = nscp; |
2380 | nscp = (Scsi_Cmnd *)pscp->SCp.ptr; | 2086 | nscp = (Scsi_Cmnd *)pscp->SCp.ptr; |
2381 | } | 2087 | } |
@@ -2395,9 +2101,8 @@ static void gdth_putq(int hanum,Scsi_Cmnd *scp,unchar priority) | |||
2395 | #endif | 2101 | #endif |
2396 | } | 2102 | } |
2397 | 2103 | ||
2398 | static void gdth_next(int hanum) | 2104 | static void gdth_next(gdth_ha_str *ha) |
2399 | { | 2105 | { |
2400 | register gdth_ha_str *ha; | ||
2401 | register Scsi_Cmnd *pscp; | 2106 | register Scsi_Cmnd *pscp; |
2402 | register Scsi_Cmnd *nscp; | 2107 | register Scsi_Cmnd *nscp; |
2403 | unchar b, t, l, firsttime; | 2108 | unchar b, t, l, firsttime; |
@@ -2405,8 +2110,7 @@ static void gdth_next(int hanum) | |||
2405 | ulong flags = 0; | 2110 | ulong flags = 0; |
2406 | int cmd_index; | 2111 | int cmd_index; |
2407 | 2112 | ||
2408 | TRACE(("gdth_next() hanum %d\n",hanum)); | 2113 | TRACE(("gdth_next() hanum %d\n", ha->hanum)); |
2409 | ha = HADATA(gdth_ctr_tab[hanum]); | ||
2410 | if (!gdth_polling) | 2114 | if (!gdth_polling) |
2411 | spin_lock_irqsave(&ha->smp_lock, flags); | 2115 | spin_lock_irqsave(&ha->smp_lock, flags); |
2412 | 2116 | ||
@@ -2416,14 +2120,14 @@ static void gdth_next(int hanum) | |||
2416 | cmd_index = 0; | 2120 | cmd_index = 0; |
2417 | 2121 | ||
2418 | for (nscp = pscp = ha->req_first; nscp; nscp = (Scsi_Cmnd *)nscp->SCp.ptr) { | 2122 | for (nscp = pscp = ha->req_first; nscp; nscp = (Scsi_Cmnd *)nscp->SCp.ptr) { |
2123 | struct gdth_cmndinfo *nscp_cmndinfo = gdth_cmnd_priv(nscp); | ||
2419 | if (nscp != pscp && nscp != (Scsi_Cmnd *)pscp->SCp.ptr) | 2124 | if (nscp != pscp && nscp != (Scsi_Cmnd *)pscp->SCp.ptr) |
2420 | pscp = (Scsi_Cmnd *)pscp->SCp.ptr; | 2125 | pscp = (Scsi_Cmnd *)pscp->SCp.ptr; |
2421 | if (nscp->done != gdth_scsi_done) { | 2126 | if (!nscp_cmndinfo->internal_command) { |
2422 | b = virt_ctr ? | 2127 | b = nscp->device->channel; |
2423 | NUMDATA(nscp->device->host)->busnum : nscp->device->channel; | ||
2424 | t = nscp->device->id; | 2128 | t = nscp->device->id; |
2425 | l = nscp->device->lun; | 2129 | l = nscp->device->lun; |
2426 | if (nscp->SCp.this_residual >= DEFAULT_PRI) { | 2130 | if (nscp_cmndinfo->priority >= DEFAULT_PRI) { |
2427 | if ((b != ha->virt_bus && ha->raw[BUS_L2P(ha,b)].lock) || | 2131 | if ((b != ha->virt_bus && ha->raw[BUS_L2P(ha,b)].lock) || |
2428 | (b == ha->virt_bus && t < MAX_HDRIVES && ha->hdr[t].lock)) | 2132 | (b == ha->virt_bus && t < MAX_HDRIVES && ha->hdr[t].lock)) |
2429 | continue; | 2133 | continue; |
@@ -2432,21 +2136,21 @@ static void gdth_next(int hanum) | |||
2432 | b = t = l = 0; | 2136 | b = t = l = 0; |
2433 | 2137 | ||
2434 | if (firsttime) { | 2138 | if (firsttime) { |
2435 | if (gdth_test_busy(hanum)) { /* controller busy ? */ | 2139 | if (gdth_test_busy(ha)) { /* controller busy ? */ |
2436 | TRACE(("gdth_next() controller %d busy !\n",hanum)); | 2140 | TRACE(("gdth_next() controller %d busy !\n", ha->hanum)); |
2437 | if (!gdth_polling) { | 2141 | if (!gdth_polling) { |
2438 | spin_unlock_irqrestore(&ha->smp_lock, flags); | 2142 | spin_unlock_irqrestore(&ha->smp_lock, flags); |
2439 | return; | 2143 | return; |
2440 | } | 2144 | } |
2441 | while (gdth_test_busy(hanum)) | 2145 | while (gdth_test_busy(ha)) |
2442 | gdth_delay(1); | 2146 | gdth_delay(1); |
2443 | } | 2147 | } |
2444 | firsttime = FALSE; | 2148 | firsttime = FALSE; |
2445 | } | 2149 | } |
2446 | 2150 | ||
2447 | if (nscp->done != gdth_scsi_done) { | 2151 | if (!nscp_cmndinfo->internal_command) { |
2448 | if (nscp->SCp.phase == -1) { | 2152 | if (nscp_cmndinfo->phase == -1) { |
2449 | nscp->SCp.phase = CACHESERVICE; /* default: cache svc. */ | 2153 | nscp_cmndinfo->phase = CACHESERVICE; /* default: cache svc. */ |
2450 | if (nscp->cmnd[0] == TEST_UNIT_READY) { | 2154 | if (nscp->cmnd[0] == TEST_UNIT_READY) { |
2451 | TRACE2(("TEST_UNIT_READY Bus %d Id %d LUN %d\n", | 2155 | TRACE2(("TEST_UNIT_READY Bus %d Id %d LUN %d\n", |
2452 | b, t, l)); | 2156 | b, t, l)); |
@@ -2459,8 +2163,8 @@ static void gdth_next(int hanum) | |||
2459 | } else if ((ha->scan_mode & 0x0f) == 1) { | 2163 | } else if ((ha->scan_mode & 0x0f) == 1) { |
2460 | if (b == 0 && ((t == 0 && l == 1) || | 2164 | if (b == 0 && ((t == 0 && l == 1) || |
2461 | (t == 1 && l == 0))) { | 2165 | (t == 1 && l == 0))) { |
2462 | nscp->SCp.sent_command = GDT_SCAN_START; | 2166 | nscp_cmndinfo->OpCode = GDT_SCAN_START; |
2463 | nscp->SCp.phase = ((ha->scan_mode & 0x10 ? 1:0) << 8) | 2167 | nscp_cmndinfo->phase = ((ha->scan_mode & 0x10 ? 1:0) << 8) |
2464 | | SCSIRAWSERVICE; | 2168 | | SCSIRAWSERVICE; |
2465 | ha->scan_mode = 0x12; | 2169 | ha->scan_mode = 0x12; |
2466 | TRACE2(("Scan mode: 0x%x (SCAN_START)\n", | 2170 | TRACE2(("Scan mode: 0x%x (SCAN_START)\n", |
@@ -2471,8 +2175,8 @@ static void gdth_next(int hanum) | |||
2471 | } | 2175 | } |
2472 | } else if (ha->scan_mode == 0x12) { | 2176 | } else if (ha->scan_mode == 0x12) { |
2473 | if (b == ha->bus_cnt && t == ha->tid_cnt-1) { | 2177 | if (b == ha->bus_cnt && t == ha->tid_cnt-1) { |
2474 | nscp->SCp.phase = SCSIRAWSERVICE; | 2178 | nscp_cmndinfo->phase = SCSIRAWSERVICE; |
2475 | nscp->SCp.sent_command = GDT_SCAN_END; | 2179 | nscp_cmndinfo->OpCode = GDT_SCAN_END; |
2476 | ha->scan_mode &= 0x10; | 2180 | ha->scan_mode &= 0x10; |
2477 | TRACE2(("Scan mode: 0x%x (SCAN_END)\n", | 2181 | TRACE2(("Scan mode: 0x%x (SCAN_END)\n", |
2478 | ha->scan_mode)); | 2182 | ha->scan_mode)); |
@@ -2483,18 +2187,18 @@ static void gdth_next(int hanum) | |||
2483 | nscp->cmnd[0] != READ_CAPACITY && nscp->cmnd[0] != MODE_SENSE && | 2187 | nscp->cmnd[0] != READ_CAPACITY && nscp->cmnd[0] != MODE_SENSE && |
2484 | (ha->hdr[t].cluster_type & CLUSTER_DRIVE)) { | 2188 | (ha->hdr[t].cluster_type & CLUSTER_DRIVE)) { |
2485 | /* always GDT_CLUST_INFO! */ | 2189 | /* always GDT_CLUST_INFO! */ |
2486 | nscp->SCp.sent_command = GDT_CLUST_INFO; | 2190 | nscp_cmndinfo->OpCode = GDT_CLUST_INFO; |
2487 | } | 2191 | } |
2488 | } | 2192 | } |
2489 | } | 2193 | } |
2490 | 2194 | ||
2491 | if (nscp->SCp.sent_command != -1) { | 2195 | if (nscp_cmndinfo->OpCode != -1) { |
2492 | if ((nscp->SCp.phase & 0xff) == CACHESERVICE) { | 2196 | if ((nscp_cmndinfo->phase & 0xff) == CACHESERVICE) { |
2493 | if (!(cmd_index=gdth_fill_cache_cmd(hanum,nscp,t))) | 2197 | if (!(cmd_index=gdth_fill_cache_cmd(ha, nscp, t))) |
2494 | this_cmd = FALSE; | 2198 | this_cmd = FALSE; |
2495 | next_cmd = FALSE; | 2199 | next_cmd = FALSE; |
2496 | } else if ((nscp->SCp.phase & 0xff) == SCSIRAWSERVICE) { | 2200 | } else if ((nscp_cmndinfo->phase & 0xff) == SCSIRAWSERVICE) { |
2497 | if (!(cmd_index=gdth_fill_raw_cmd(hanum,nscp,BUS_L2P(ha,b)))) | 2201 | if (!(cmd_index=gdth_fill_raw_cmd(ha, nscp, BUS_L2P(ha, b)))) |
2498 | this_cmd = FALSE; | 2202 | this_cmd = FALSE; |
2499 | next_cmd = FALSE; | 2203 | next_cmd = FALSE; |
2500 | } else { | 2204 | } else { |
@@ -2502,18 +2206,18 @@ static void gdth_next(int hanum) | |||
2502 | nscp->sense_buffer[0] = 0x70; | 2206 | nscp->sense_buffer[0] = 0x70; |
2503 | nscp->sense_buffer[2] = NOT_READY; | 2207 | nscp->sense_buffer[2] = NOT_READY; |
2504 | nscp->result = (DID_OK << 16) | (CHECK_CONDITION << 1); | 2208 | nscp->result = (DID_OK << 16) | (CHECK_CONDITION << 1); |
2505 | if (!nscp->SCp.have_data_in) | 2209 | if (!nscp_cmndinfo->wait_for_completion) |
2506 | nscp->SCp.have_data_in++; | 2210 | nscp_cmndinfo->wait_for_completion++; |
2507 | else | 2211 | else |
2508 | nscp->scsi_done(nscp); | 2212 | gdth_scsi_done(nscp); |
2509 | } | 2213 | } |
2510 | } else if (nscp->done == gdth_scsi_done) { | 2214 | } else if (gdth_cmnd_priv(nscp)->internal_command) { |
2511 | if (!(cmd_index=gdth_special_cmd(hanum,nscp))) | 2215 | if (!(cmd_index=gdth_special_cmd(ha, nscp))) |
2512 | this_cmd = FALSE; | 2216 | this_cmd = FALSE; |
2513 | next_cmd = FALSE; | 2217 | next_cmd = FALSE; |
2514 | } else if (b != ha->virt_bus) { | 2218 | } else if (b != ha->virt_bus) { |
2515 | if (ha->raw[BUS_L2P(ha,b)].io_cnt[t] >= GDTH_MAX_RAW || | 2219 | if (ha->raw[BUS_L2P(ha,b)].io_cnt[t] >= GDTH_MAX_RAW || |
2516 | !(cmd_index=gdth_fill_raw_cmd(hanum,nscp,BUS_L2P(ha,b)))) | 2220 | !(cmd_index=gdth_fill_raw_cmd(ha, nscp, BUS_L2P(ha, b)))) |
2517 | this_cmd = FALSE; | 2221 | this_cmd = FALSE; |
2518 | else | 2222 | else |
2519 | ha->raw[BUS_L2P(ha,b)].io_cnt[t]++; | 2223 | ha->raw[BUS_L2P(ha,b)].io_cnt[t]++; |
@@ -2521,10 +2225,10 @@ static void gdth_next(int hanum) | |||
2521 | TRACE2(("Command 0x%x to bus %d id %d lun %d -> IGNORE\n", | 2225 | TRACE2(("Command 0x%x to bus %d id %d lun %d -> IGNORE\n", |
2522 | nscp->cmnd[0], b, t, l)); | 2226 | nscp->cmnd[0], b, t, l)); |
2523 | nscp->result = DID_BAD_TARGET << 16; | 2227 | nscp->result = DID_BAD_TARGET << 16; |
2524 | if (!nscp->SCp.have_data_in) | 2228 | if (!nscp_cmndinfo->wait_for_completion) |
2525 | nscp->SCp.have_data_in++; | 2229 | nscp_cmndinfo->wait_for_completion++; |
2526 | else | 2230 | else |
2527 | nscp->scsi_done(nscp); | 2231 | gdth_scsi_done(nscp); |
2528 | } else { | 2232 | } else { |
2529 | switch (nscp->cmnd[0]) { | 2233 | switch (nscp->cmnd[0]) { |
2530 | case TEST_UNIT_READY: | 2234 | case TEST_UNIT_READY: |
@@ -2547,12 +2251,12 @@ static void gdth_next(int hanum) | |||
2547 | nscp->sense_buffer[0] = 0x70; | 2251 | nscp->sense_buffer[0] = 0x70; |
2548 | nscp->sense_buffer[2] = UNIT_ATTENTION; | 2252 | nscp->sense_buffer[2] = UNIT_ATTENTION; |
2549 | nscp->result = (DID_OK << 16) | (CHECK_CONDITION << 1); | 2253 | nscp->result = (DID_OK << 16) | (CHECK_CONDITION << 1); |
2550 | if (!nscp->SCp.have_data_in) | 2254 | if (!nscp_cmndinfo->wait_for_completion) |
2551 | nscp->SCp.have_data_in++; | 2255 | nscp_cmndinfo->wait_for_completion++; |
2552 | else | 2256 | else |
2553 | nscp->scsi_done(nscp); | 2257 | gdth_scsi_done(nscp); |
2554 | } else if (gdth_internal_cache_cmd(hanum,nscp)) | 2258 | } else if (gdth_internal_cache_cmd(ha, nscp)) |
2555 | nscp->scsi_done(nscp); | 2259 | gdth_scsi_done(nscp); |
2556 | break; | 2260 | break; |
2557 | 2261 | ||
2558 | case ALLOW_MEDIUM_REMOVAL: | 2262 | case ALLOW_MEDIUM_REMOVAL: |
@@ -2563,15 +2267,15 @@ static void gdth_next(int hanum) | |||
2563 | TRACE(("Prevent r. nonremov. drive->do nothing\n")); | 2267 | TRACE(("Prevent r. nonremov. drive->do nothing\n")); |
2564 | nscp->result = DID_OK << 16; | 2268 | nscp->result = DID_OK << 16; |
2565 | nscp->sense_buffer[0] = 0; | 2269 | nscp->sense_buffer[0] = 0; |
2566 | if (!nscp->SCp.have_data_in) | 2270 | if (!nscp_cmndinfo->wait_for_completion) |
2567 | nscp->SCp.have_data_in++; | 2271 | nscp_cmndinfo->wait_for_completion++; |
2568 | else | 2272 | else |
2569 | nscp->scsi_done(nscp); | 2273 | gdth_scsi_done(nscp); |
2570 | } else { | 2274 | } else { |
2571 | nscp->cmnd[3] = (ha->hdr[t].devtype&1) ? 1:0; | 2275 | nscp->cmnd[3] = (ha->hdr[t].devtype&1) ? 1:0; |
2572 | TRACE(("Prevent/allow r. %d rem. drive %d\n", | 2276 | TRACE(("Prevent/allow r. %d rem. drive %d\n", |
2573 | nscp->cmnd[4],nscp->cmnd[3])); | 2277 | nscp->cmnd[4],nscp->cmnd[3])); |
2574 | if (!(cmd_index=gdth_fill_cache_cmd(hanum,nscp,t))) | 2278 | if (!(cmd_index=gdth_fill_cache_cmd(ha, nscp, t))) |
2575 | this_cmd = FALSE; | 2279 | this_cmd = FALSE; |
2576 | } | 2280 | } |
2577 | break; | 2281 | break; |
@@ -2580,7 +2284,7 @@ static void gdth_next(int hanum) | |||
2580 | case RELEASE: | 2284 | case RELEASE: |
2581 | TRACE2(("cache cmd %s\n",nscp->cmnd[0] == RESERVE ? | 2285 | TRACE2(("cache cmd %s\n",nscp->cmnd[0] == RESERVE ? |
2582 | "RESERVE" : "RELEASE")); | 2286 | "RESERVE" : "RELEASE")); |
2583 | if (!(cmd_index=gdth_fill_cache_cmd(hanum,nscp,t))) | 2287 | if (!(cmd_index=gdth_fill_cache_cmd(ha, nscp, t))) |
2584 | this_cmd = FALSE; | 2288 | this_cmd = FALSE; |
2585 | break; | 2289 | break; |
2586 | 2290 | ||
@@ -2599,11 +2303,11 @@ static void gdth_next(int hanum) | |||
2599 | nscp->sense_buffer[0] = 0x70; | 2303 | nscp->sense_buffer[0] = 0x70; |
2600 | nscp->sense_buffer[2] = UNIT_ATTENTION; | 2304 | nscp->sense_buffer[2] = UNIT_ATTENTION; |
2601 | nscp->result = (DID_OK << 16) | (CHECK_CONDITION << 1); | 2305 | nscp->result = (DID_OK << 16) | (CHECK_CONDITION << 1); |
2602 | if (!nscp->SCp.have_data_in) | 2306 | if (!nscp_cmndinfo->wait_for_completion) |
2603 | nscp->SCp.have_data_in++; | 2307 | nscp_cmndinfo->wait_for_completion++; |
2604 | else | 2308 | else |
2605 | nscp->scsi_done(nscp); | 2309 | gdth_scsi_done(nscp); |
2606 | } else if (!(cmd_index=gdth_fill_cache_cmd(hanum,nscp,t))) | 2310 | } else if (!(cmd_index=gdth_fill_cache_cmd(ha, nscp, t))) |
2607 | this_cmd = FALSE; | 2311 | this_cmd = FALSE; |
2608 | break; | 2312 | break; |
2609 | 2313 | ||
@@ -2612,12 +2316,12 @@ static void gdth_next(int hanum) | |||
2612 | nscp->cmnd[1],nscp->cmnd[2],nscp->cmnd[3], | 2316 | nscp->cmnd[1],nscp->cmnd[2],nscp->cmnd[3], |
2613 | nscp->cmnd[4],nscp->cmnd[5])); | 2317 | nscp->cmnd[4],nscp->cmnd[5])); |
2614 | printk("GDT-HA %d: Unknown SCSI command 0x%x to cache service !\n", | 2318 | printk("GDT-HA %d: Unknown SCSI command 0x%x to cache service !\n", |
2615 | hanum, nscp->cmnd[0]); | 2319 | ha->hanum, nscp->cmnd[0]); |
2616 | nscp->result = DID_ABORT << 16; | 2320 | nscp->result = DID_ABORT << 16; |
2617 | if (!nscp->SCp.have_data_in) | 2321 | if (!nscp_cmndinfo->wait_for_completion) |
2618 | nscp->SCp.have_data_in++; | 2322 | nscp_cmndinfo->wait_for_completion++; |
2619 | else | 2323 | else |
2620 | nscp->scsi_done(nscp); | 2324 | gdth_scsi_done(nscp); |
2621 | break; | 2325 | break; |
2622 | } | 2326 | } |
2623 | } | 2327 | } |
@@ -2633,79 +2337,77 @@ static void gdth_next(int hanum) | |||
2633 | } | 2337 | } |
2634 | 2338 | ||
2635 | if (ha->cmd_cnt > 0) { | 2339 | if (ha->cmd_cnt > 0) { |
2636 | gdth_release_event(hanum); | 2340 | gdth_release_event(ha); |
2637 | } | 2341 | } |
2638 | 2342 | ||
2639 | if (!gdth_polling) | 2343 | if (!gdth_polling) |
2640 | spin_unlock_irqrestore(&ha->smp_lock, flags); | 2344 | spin_unlock_irqrestore(&ha->smp_lock, flags); |
2641 | 2345 | ||
2642 | if (gdth_polling && ha->cmd_cnt > 0) { | 2346 | if (gdth_polling && ha->cmd_cnt > 0) { |
2643 | if (!gdth_wait(hanum,cmd_index,POLL_TIMEOUT)) | 2347 | if (!gdth_wait(ha, cmd_index, POLL_TIMEOUT)) |
2644 | printk("GDT-HA %d: Command %d timed out !\n", | 2348 | printk("GDT-HA %d: Command %d timed out !\n", |
2645 | hanum,cmd_index); | 2349 | ha->hanum, cmd_index); |
2646 | } | 2350 | } |
2647 | } | 2351 | } |
2648 | 2352 | ||
2649 | static void gdth_copy_internal_data(int hanum,Scsi_Cmnd *scp, | 2353 | /* |
2650 | char *buffer,ushort count) | 2354 | * gdth_copy_internal_data() - copy to/from a buffer onto a scsi_cmnd's |
2355 | * buffers, kmap_atomic() as needed. | ||
2356 | */ | ||
2357 | static void gdth_copy_internal_data(gdth_ha_str *ha, Scsi_Cmnd *scp, | ||
2358 | char *buffer, ushort count, int to_buffer) | ||
2651 | { | 2359 | { |
2652 | ushort cpcount,i; | 2360 | ushort cpcount,i, max_sg = gdth_sg_count(scp); |
2653 | ushort cpsum,cpnow; | 2361 | ushort cpsum,cpnow; |
2654 | struct scatterlist *sl; | 2362 | struct scatterlist *sl; |
2655 | gdth_ha_str *ha; | ||
2656 | char *address; | 2363 | char *address; |
2657 | 2364 | ||
2658 | cpcount = count<=(ushort)scp->request_bufflen ? count:(ushort)scp->request_bufflen; | 2365 | cpcount = min_t(ushort, count, gdth_bufflen(scp)); |
2659 | ha = HADATA(gdth_ctr_tab[hanum]); | ||
2660 | 2366 | ||
2661 | if (scp->use_sg) { | 2367 | if (cpcount) { |
2662 | sl = (struct scatterlist *)scp->request_buffer; | 2368 | cpsum=0; |
2663 | for (i=0,cpsum=0; i<scp->use_sg; ++i,++sl) { | 2369 | scsi_for_each_sg(scp, sl, max_sg, i) { |
2664 | unsigned long flags; | 2370 | unsigned long flags; |
2665 | cpnow = (ushort)sl->length; | 2371 | cpnow = (ushort)sl->length; |
2666 | TRACE(("copy_internal() now %d sum %d count %d %d\n", | 2372 | TRACE(("copy_internal() now %d sum %d count %d %d\n", |
2667 | cpnow,cpsum,cpcount,(ushort)scp->bufflen)); | 2373 | cpnow, cpsum, cpcount, gdth_bufflen(scp))); |
2668 | if (cpsum+cpnow > cpcount) | 2374 | if (cpsum+cpnow > cpcount) |
2669 | cpnow = cpcount - cpsum; | 2375 | cpnow = cpcount - cpsum; |
2670 | cpsum += cpnow; | 2376 | cpsum += cpnow; |
2671 | if (!sl->page) { | 2377 | if (!sl->page) { |
2672 | printk("GDT-HA %d: invalid sc/gt element in gdth_copy_internal_data()\n", | 2378 | printk("GDT-HA %d: invalid sc/gt element in gdth_copy_internal_data()\n", |
2673 | hanum); | 2379 | ha->hanum); |
2674 | return; | 2380 | return; |
2675 | } | 2381 | } |
2676 | local_irq_save(flags); | 2382 | local_irq_save(flags); |
2677 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) | ||
2678 | address = kmap_atomic(sl->page, KM_BIO_SRC_IRQ) + sl->offset; | 2383 | address = kmap_atomic(sl->page, KM_BIO_SRC_IRQ) + sl->offset; |
2679 | memcpy(address,buffer,cpnow); | 2384 | if (to_buffer) |
2385 | memcpy(buffer, address, cpnow); | ||
2386 | else | ||
2387 | memcpy(address, buffer, cpnow); | ||
2680 | flush_dcache_page(sl->page); | 2388 | flush_dcache_page(sl->page); |
2681 | kunmap_atomic(address, KM_BIO_SRC_IRQ); | 2389 | kunmap_atomic(address, KM_BIO_SRC_IRQ); |
2682 | #else | ||
2683 | address = kmap_atomic(sl->page, KM_BH_IRQ) + sl->offset; | ||
2684 | memcpy(address,buffer,cpnow); | ||
2685 | flush_dcache_page(sl->page); | ||
2686 | kunmap_atomic(address, KM_BH_IRQ); | ||
2687 | #endif | ||
2688 | local_irq_restore(flags); | 2390 | local_irq_restore(flags); |
2689 | if (cpsum == cpcount) | 2391 | if (cpsum == cpcount) |
2690 | break; | 2392 | break; |
2691 | buffer += cpnow; | 2393 | buffer += cpnow; |
2692 | } | 2394 | } |
2693 | } else { | 2395 | } else if (count) { |
2694 | TRACE(("copy_internal() count %d\n",cpcount)); | 2396 | printk("GDT-HA %d: SCSI command with no buffers but data transfer expected!\n", |
2695 | memcpy((char*)scp->request_buffer,buffer,cpcount); | 2397 | ha->hanum); |
2398 | WARN_ON(1); | ||
2696 | } | 2399 | } |
2697 | } | 2400 | } |
2698 | 2401 | ||
2699 | static int gdth_internal_cache_cmd(int hanum,Scsi_Cmnd *scp) | 2402 | static int gdth_internal_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp) |
2700 | { | 2403 | { |
2701 | register gdth_ha_str *ha; | ||
2702 | unchar t; | 2404 | unchar t; |
2703 | gdth_inq_data inq; | 2405 | gdth_inq_data inq; |
2704 | gdth_rdcap_data rdc; | 2406 | gdth_rdcap_data rdc; |
2705 | gdth_sense_data sd; | 2407 | gdth_sense_data sd; |
2706 | gdth_modep_data mpd; | 2408 | gdth_modep_data mpd; |
2409 | struct gdth_cmndinfo *cmndinfo = gdth_cmnd_priv(scp); | ||
2707 | 2410 | ||
2708 | ha = HADATA(gdth_ctr_tab[hanum]); | ||
2709 | t = scp->device->id; | 2411 | t = scp->device->id; |
2710 | TRACE(("gdth_internal_cache_cmd() cmd 0x%x hdrive %d\n", | 2412 | TRACE(("gdth_internal_cache_cmd() cmd 0x%x hdrive %d\n", |
2711 | scp->cmnd[0],t)); | 2413 | scp->cmnd[0],t)); |
@@ -2736,7 +2438,7 @@ static int gdth_internal_cache_cmd(int hanum,Scsi_Cmnd *scp) | |||
2736 | strcpy(inq.vendor,ha->oem_name); | 2438 | strcpy(inq.vendor,ha->oem_name); |
2737 | sprintf(inq.product,"Host Drive #%02d",t); | 2439 | sprintf(inq.product,"Host Drive #%02d",t); |
2738 | strcpy(inq.revision," "); | 2440 | strcpy(inq.revision," "); |
2739 | gdth_copy_internal_data(hanum,scp,(char*)&inq,sizeof(gdth_inq_data)); | 2441 | gdth_copy_internal_data(ha, scp, (char*)&inq, sizeof(gdth_inq_data), 0); |
2740 | break; | 2442 | break; |
2741 | 2443 | ||
2742 | case REQUEST_SENSE: | 2444 | case REQUEST_SENSE: |
@@ -2746,7 +2448,7 @@ static int gdth_internal_cache_cmd(int hanum,Scsi_Cmnd *scp) | |||
2746 | sd.key = NO_SENSE; | 2448 | sd.key = NO_SENSE; |
2747 | sd.info = 0; | 2449 | sd.info = 0; |
2748 | sd.add_length= 0; | 2450 | sd.add_length= 0; |
2749 | gdth_copy_internal_data(hanum,scp,(char*)&sd,sizeof(gdth_sense_data)); | 2451 | gdth_copy_internal_data(ha, scp, (char*)&sd, sizeof(gdth_sense_data), 0); |
2750 | break; | 2452 | break; |
2751 | 2453 | ||
2752 | case MODE_SENSE: | 2454 | case MODE_SENSE: |
@@ -2758,7 +2460,7 @@ static int gdth_internal_cache_cmd(int hanum,Scsi_Cmnd *scp) | |||
2758 | mpd.bd.block_length[0] = (SECTOR_SIZE & 0x00ff0000) >> 16; | 2460 | mpd.bd.block_length[0] = (SECTOR_SIZE & 0x00ff0000) >> 16; |
2759 | mpd.bd.block_length[1] = (SECTOR_SIZE & 0x0000ff00) >> 8; | 2461 | mpd.bd.block_length[1] = (SECTOR_SIZE & 0x0000ff00) >> 8; |
2760 | mpd.bd.block_length[2] = (SECTOR_SIZE & 0x000000ff); | 2462 | mpd.bd.block_length[2] = (SECTOR_SIZE & 0x000000ff); |
2761 | gdth_copy_internal_data(hanum,scp,(char*)&mpd,sizeof(gdth_modep_data)); | 2463 | gdth_copy_internal_data(ha, scp, (char*)&mpd, sizeof(gdth_modep_data), 0); |
2762 | break; | 2464 | break; |
2763 | 2465 | ||
2764 | case READ_CAPACITY: | 2466 | case READ_CAPACITY: |
@@ -2768,7 +2470,7 @@ static int gdth_internal_cache_cmd(int hanum,Scsi_Cmnd *scp) | |||
2768 | else | 2470 | else |
2769 | rdc.last_block_no = cpu_to_be32(ha->hdr[t].size-1); | 2471 | rdc.last_block_no = cpu_to_be32(ha->hdr[t].size-1); |
2770 | rdc.block_length = cpu_to_be32(SECTOR_SIZE); | 2472 | rdc.block_length = cpu_to_be32(SECTOR_SIZE); |
2771 | gdth_copy_internal_data(hanum,scp,(char*)&rdc,sizeof(gdth_rdcap_data)); | 2473 | gdth_copy_internal_data(ha, scp, (char*)&rdc, sizeof(gdth_rdcap_data), 0); |
2772 | break; | 2474 | break; |
2773 | 2475 | ||
2774 | case SERVICE_ACTION_IN: | 2476 | case SERVICE_ACTION_IN: |
@@ -2779,7 +2481,8 @@ static int gdth_internal_cache_cmd(int hanum,Scsi_Cmnd *scp) | |||
2779 | TRACE2(("Read capacity (16) hdrive %d\n",t)); | 2481 | TRACE2(("Read capacity (16) hdrive %d\n",t)); |
2780 | rdc16.last_block_no = cpu_to_be64(ha->hdr[t].size-1); | 2482 | rdc16.last_block_no = cpu_to_be64(ha->hdr[t].size-1); |
2781 | rdc16.block_length = cpu_to_be32(SECTOR_SIZE); | 2483 | rdc16.block_length = cpu_to_be32(SECTOR_SIZE); |
2782 | gdth_copy_internal_data(hanum,scp,(char*)&rdc16,sizeof(gdth_rdcap16_data)); | 2484 | gdth_copy_internal_data(ha, scp, (char*)&rdc16, |
2485 | sizeof(gdth_rdcap16_data), 0); | ||
2783 | } else { | 2486 | } else { |
2784 | scp->result = DID_ABORT << 16; | 2487 | scp->result = DID_ABORT << 16; |
2785 | } | 2488 | } |
@@ -2790,27 +2493,22 @@ static int gdth_internal_cache_cmd(int hanum,Scsi_Cmnd *scp) | |||
2790 | break; | 2493 | break; |
2791 | } | 2494 | } |
2792 | 2495 | ||
2793 | if (!scp->SCp.have_data_in) | 2496 | if (!cmndinfo->wait_for_completion) |
2794 | scp->SCp.have_data_in++; | 2497 | cmndinfo->wait_for_completion++; |
2795 | else | 2498 | else |
2796 | return 1; | 2499 | return 1; |
2797 | 2500 | ||
2798 | return 0; | 2501 | return 0; |
2799 | } | 2502 | } |
2800 | 2503 | ||
2801 | static int gdth_fill_cache_cmd(int hanum,Scsi_Cmnd *scp,ushort hdrive) | 2504 | static int gdth_fill_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp, ushort hdrive) |
2802 | { | 2505 | { |
2803 | register gdth_ha_str *ha; | ||
2804 | register gdth_cmd_str *cmdp; | 2506 | register gdth_cmd_str *cmdp; |
2805 | struct scatterlist *sl; | 2507 | struct gdth_cmndinfo *cmndinfo = gdth_cmnd_priv(scp); |
2806 | ulong32 cnt, blockcnt; | 2508 | ulong32 cnt, blockcnt; |
2807 | ulong64 no, blockno; | 2509 | ulong64 no, blockno; |
2808 | dma_addr_t phys_addr; | ||
2809 | int i, cmd_index, read_write, sgcnt, mode64; | 2510 | int i, cmd_index, read_write, sgcnt, mode64; |
2810 | struct page *page; | ||
2811 | ulong offset; | ||
2812 | 2511 | ||
2813 | ha = HADATA(gdth_ctr_tab[hanum]); | ||
2814 | cmdp = ha->pccb; | 2512 | cmdp = ha->pccb; |
2815 | TRACE(("gdth_fill_cache_cmd() cmd 0x%x cmdsize %d hdrive %d\n", | 2513 | TRACE(("gdth_fill_cache_cmd() cmd 0x%x cmdsize %d hdrive %d\n", |
2816 | scp->cmnd[0],scp->cmd_len,hdrive)); | 2514 | scp->cmnd[0],scp->cmd_len,hdrive)); |
@@ -2826,18 +2524,18 @@ static int gdth_fill_cache_cmd(int hanum,Scsi_Cmnd *scp,ushort hdrive) | |||
2826 | cmdp->Service = CACHESERVICE; | 2524 | cmdp->Service = CACHESERVICE; |
2827 | cmdp->RequestBuffer = scp; | 2525 | cmdp->RequestBuffer = scp; |
2828 | /* search free command index */ | 2526 | /* search free command index */ |
2829 | if (!(cmd_index=gdth_get_cmd_index(hanum))) { | 2527 | if (!(cmd_index=gdth_get_cmd_index(ha))) { |
2830 | TRACE(("GDT: No free command index found\n")); | 2528 | TRACE(("GDT: No free command index found\n")); |
2831 | return 0; | 2529 | return 0; |
2832 | } | 2530 | } |
2833 | /* if it's the first command, set command semaphore */ | 2531 | /* if it's the first command, set command semaphore */ |
2834 | if (ha->cmd_cnt == 0) | 2532 | if (ha->cmd_cnt == 0) |
2835 | gdth_set_sema0(hanum); | 2533 | gdth_set_sema0(ha); |
2836 | 2534 | ||
2837 | /* fill command */ | 2535 | /* fill command */ |
2838 | read_write = 0; | 2536 | read_write = 0; |
2839 | if (scp->SCp.sent_command != -1) | 2537 | if (cmndinfo->OpCode != -1) |
2840 | cmdp->OpCode = scp->SCp.sent_command; /* special cache cmd. */ | 2538 | cmdp->OpCode = cmndinfo->OpCode; /* special cache cmd. */ |
2841 | else if (scp->cmnd[0] == RESERVE) | 2539 | else if (scp->cmnd[0] == RESERVE) |
2842 | cmdp->OpCode = GDT_RESERVE_DRV; | 2540 | cmdp->OpCode = GDT_RESERVE_DRV; |
2843 | else if (scp->cmnd[0] == RELEASE) | 2541 | else if (scp->cmnd[0] == RELEASE) |
@@ -2898,17 +2596,17 @@ static int gdth_fill_cache_cmd(int hanum,Scsi_Cmnd *scp,ushort hdrive) | |||
2898 | cmdp->u.cache.BlockCnt = blockcnt; | 2596 | cmdp->u.cache.BlockCnt = blockcnt; |
2899 | } | 2597 | } |
2900 | 2598 | ||
2901 | if (scp->use_sg) { | 2599 | if (gdth_bufflen(scp)) { |
2902 | sl = (struct scatterlist *)scp->request_buffer; | 2600 | cmndinfo->dma_dir = (read_write == 1 ? |
2903 | sgcnt = scp->use_sg; | ||
2904 | scp->SCp.Status = GDTH_MAP_SG; | ||
2905 | scp->SCp.Message = (read_write == 1 ? | ||
2906 | PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE); | 2601 | PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE); |
2907 | sgcnt = pci_map_sg(ha->pdev,sl,scp->use_sg,scp->SCp.Message); | 2602 | sgcnt = pci_map_sg(ha->pdev, gdth_sglist(scp), gdth_sg_count(scp), |
2603 | cmndinfo->dma_dir); | ||
2908 | if (mode64) { | 2604 | if (mode64) { |
2605 | struct scatterlist *sl; | ||
2606 | |||
2909 | cmdp->u.cache64.DestAddr= (ulong64)-1; | 2607 | cmdp->u.cache64.DestAddr= (ulong64)-1; |
2910 | cmdp->u.cache64.sg_canz = sgcnt; | 2608 | cmdp->u.cache64.sg_canz = sgcnt; |
2911 | for (i=0; i<sgcnt; ++i,++sl) { | 2609 | scsi_for_each_sg(scp, sl, sgcnt, i) { |
2912 | cmdp->u.cache64.sg_lst[i].sg_ptr = sg_dma_address(sl); | 2610 | cmdp->u.cache64.sg_lst[i].sg_ptr = sg_dma_address(sl); |
2913 | #ifdef GDTH_DMA_STATISTICS | 2611 | #ifdef GDTH_DMA_STATISTICS |
2914 | if (cmdp->u.cache64.sg_lst[i].sg_ptr > (ulong64)0xffffffff) | 2612 | if (cmdp->u.cache64.sg_lst[i].sg_ptr > (ulong64)0xffffffff) |
@@ -2919,9 +2617,11 @@ static int gdth_fill_cache_cmd(int hanum,Scsi_Cmnd *scp,ushort hdrive) | |||
2919 | cmdp->u.cache64.sg_lst[i].sg_len = sg_dma_len(sl); | 2617 | cmdp->u.cache64.sg_lst[i].sg_len = sg_dma_len(sl); |
2920 | } | 2618 | } |
2921 | } else { | 2619 | } else { |
2620 | struct scatterlist *sl; | ||
2621 | |||
2922 | cmdp->u.cache.DestAddr= 0xffffffff; | 2622 | cmdp->u.cache.DestAddr= 0xffffffff; |
2923 | cmdp->u.cache.sg_canz = sgcnt; | 2623 | cmdp->u.cache.sg_canz = sgcnt; |
2924 | for (i=0; i<sgcnt; ++i,++sl) { | 2624 | scsi_for_each_sg(scp, sl, sgcnt, i) { |
2925 | cmdp->u.cache.sg_lst[i].sg_ptr = sg_dma_address(sl); | 2625 | cmdp->u.cache.sg_lst[i].sg_ptr = sg_dma_address(sl); |
2926 | #ifdef GDTH_DMA_STATISTICS | 2626 | #ifdef GDTH_DMA_STATISTICS |
2927 | ha->dma32_cnt++; | 2627 | ha->dma32_cnt++; |
@@ -2937,38 +2637,6 @@ static int gdth_fill_cache_cmd(int hanum,Scsi_Cmnd *scp,ushort hdrive) | |||
2937 | } | 2637 | } |
2938 | #endif | 2638 | #endif |
2939 | 2639 | ||
2940 | } else if (scp->request_bufflen) { | ||
2941 | scp->SCp.Status = GDTH_MAP_SINGLE; | ||
2942 | scp->SCp.Message = (read_write == 1 ? | ||
2943 | PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE); | ||
2944 | page = virt_to_page(scp->request_buffer); | ||
2945 | offset = (ulong)scp->request_buffer & ~PAGE_MASK; | ||
2946 | phys_addr = pci_map_page(ha->pdev,page,offset, | ||
2947 | scp->request_bufflen,scp->SCp.Message); | ||
2948 | scp->SCp.dma_handle = phys_addr; | ||
2949 | if (mode64) { | ||
2950 | if (ha->cache_feat & SCATTER_GATHER) { | ||
2951 | cmdp->u.cache64.DestAddr = (ulong64)-1; | ||
2952 | cmdp->u.cache64.sg_canz = 1; | ||
2953 | cmdp->u.cache64.sg_lst[0].sg_ptr = phys_addr; | ||
2954 | cmdp->u.cache64.sg_lst[0].sg_len = scp->request_bufflen; | ||
2955 | cmdp->u.cache64.sg_lst[1].sg_len = 0; | ||
2956 | } else { | ||
2957 | cmdp->u.cache64.DestAddr = phys_addr; | ||
2958 | cmdp->u.cache64.sg_canz= 0; | ||
2959 | } | ||
2960 | } else { | ||
2961 | if (ha->cache_feat & SCATTER_GATHER) { | ||
2962 | cmdp->u.cache.DestAddr = 0xffffffff; | ||
2963 | cmdp->u.cache.sg_canz = 1; | ||
2964 | cmdp->u.cache.sg_lst[0].sg_ptr = phys_addr; | ||
2965 | cmdp->u.cache.sg_lst[0].sg_len = scp->request_bufflen; | ||
2966 | cmdp->u.cache.sg_lst[1].sg_len = 0; | ||
2967 | } else { | ||
2968 | cmdp->u.cache.DestAddr = phys_addr; | ||
2969 | cmdp->u.cache.sg_canz= 0; | ||
2970 | } | ||
2971 | } | ||
2972 | } | 2640 | } |
2973 | } | 2641 | } |
2974 | /* evaluate command size, check space */ | 2642 | /* evaluate command size, check space */ |
@@ -3004,23 +2672,21 @@ static int gdth_fill_cache_cmd(int hanum,Scsi_Cmnd *scp,ushort hdrive) | |||
3004 | } | 2672 | } |
3005 | 2673 | ||
3006 | /* copy command */ | 2674 | /* copy command */ |
3007 | gdth_copy_command(hanum); | 2675 | gdth_copy_command(ha); |
3008 | return cmd_index; | 2676 | return cmd_index; |
3009 | } | 2677 | } |
3010 | 2678 | ||
3011 | static int gdth_fill_raw_cmd(int hanum,Scsi_Cmnd *scp,unchar b) | 2679 | static int gdth_fill_raw_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp, unchar b) |
3012 | { | 2680 | { |
3013 | register gdth_ha_str *ha; | ||
3014 | register gdth_cmd_str *cmdp; | 2681 | register gdth_cmd_str *cmdp; |
3015 | struct scatterlist *sl; | ||
3016 | ushort i; | 2682 | ushort i; |
3017 | dma_addr_t phys_addr, sense_paddr; | 2683 | dma_addr_t sense_paddr; |
3018 | int cmd_index, sgcnt, mode64; | 2684 | int cmd_index, sgcnt, mode64; |
3019 | unchar t,l; | 2685 | unchar t,l; |
3020 | struct page *page; | 2686 | struct page *page; |
3021 | ulong offset; | 2687 | ulong offset; |
2688 | struct gdth_cmndinfo *cmndinfo; | ||
3022 | 2689 | ||
3023 | ha = HADATA(gdth_ctr_tab[hanum]); | ||
3024 | t = scp->device->id; | 2690 | t = scp->device->id; |
3025 | l = scp->device->lun; | 2691 | l = scp->device->lun; |
3026 | cmdp = ha->pccb; | 2692 | cmdp = ha->pccb; |
@@ -3035,26 +2701,27 @@ static int gdth_fill_raw_cmd(int hanum,Scsi_Cmnd *scp,unchar b) | |||
3035 | cmdp->Service = SCSIRAWSERVICE; | 2701 | cmdp->Service = SCSIRAWSERVICE; |
3036 | cmdp->RequestBuffer = scp; | 2702 | cmdp->RequestBuffer = scp; |
3037 | /* search free command index */ | 2703 | /* search free command index */ |
3038 | if (!(cmd_index=gdth_get_cmd_index(hanum))) { | 2704 | if (!(cmd_index=gdth_get_cmd_index(ha))) { |
3039 | TRACE(("GDT: No free command index found\n")); | 2705 | TRACE(("GDT: No free command index found\n")); |
3040 | return 0; | 2706 | return 0; |
3041 | } | 2707 | } |
3042 | /* if it's the first command, set command semaphore */ | 2708 | /* if it's the first command, set command semaphore */ |
3043 | if (ha->cmd_cnt == 0) | 2709 | if (ha->cmd_cnt == 0) |
3044 | gdth_set_sema0(hanum); | 2710 | gdth_set_sema0(ha); |
3045 | 2711 | ||
2712 | cmndinfo = gdth_cmnd_priv(scp); | ||
3046 | /* fill command */ | 2713 | /* fill command */ |
3047 | if (scp->SCp.sent_command != -1) { | 2714 | if (cmndinfo->OpCode != -1) { |
3048 | cmdp->OpCode = scp->SCp.sent_command; /* special raw cmd. */ | 2715 | cmdp->OpCode = cmndinfo->OpCode; /* special raw cmd. */ |
3049 | cmdp->BoardNode = LOCALBOARD; | 2716 | cmdp->BoardNode = LOCALBOARD; |
3050 | if (mode64) { | 2717 | if (mode64) { |
3051 | cmdp->u.raw64.direction = (scp->SCp.phase >> 8); | 2718 | cmdp->u.raw64.direction = (cmndinfo->phase >> 8); |
3052 | TRACE2(("special raw cmd 0x%x param 0x%x\n", | 2719 | TRACE2(("special raw cmd 0x%x param 0x%x\n", |
3053 | cmdp->OpCode, cmdp->u.raw64.direction)); | 2720 | cmdp->OpCode, cmdp->u.raw64.direction)); |
3054 | /* evaluate command size */ | 2721 | /* evaluate command size */ |
3055 | ha->cmd_len = GDTOFFSOF(gdth_cmd_str,u.raw64.sg_lst); | 2722 | ha->cmd_len = GDTOFFSOF(gdth_cmd_str,u.raw64.sg_lst); |
3056 | } else { | 2723 | } else { |
3057 | cmdp->u.raw.direction = (scp->SCp.phase >> 8); | 2724 | cmdp->u.raw.direction = (cmndinfo->phase >> 8); |
3058 | TRACE2(("special raw cmd 0x%x param 0x%x\n", | 2725 | TRACE2(("special raw cmd 0x%x param 0x%x\n", |
3059 | cmdp->OpCode, cmdp->u.raw.direction)); | 2726 | cmdp->OpCode, cmdp->u.raw.direction)); |
3060 | /* evaluate command size */ | 2727 | /* evaluate command size */ |
@@ -3066,9 +2733,8 @@ static int gdth_fill_raw_cmd(int hanum,Scsi_Cmnd *scp,unchar b) | |||
3066 | offset = (ulong)scp->sense_buffer & ~PAGE_MASK; | 2733 | offset = (ulong)scp->sense_buffer & ~PAGE_MASK; |
3067 | sense_paddr = pci_map_page(ha->pdev,page,offset, | 2734 | sense_paddr = pci_map_page(ha->pdev,page,offset, |
3068 | 16,PCI_DMA_FROMDEVICE); | 2735 | 16,PCI_DMA_FROMDEVICE); |
3069 | *(ulong32 *)&scp->SCp.buffer = (ulong32)sense_paddr; | 2736 | |
3070 | /* high part, if 64bit */ | 2737 | cmndinfo->sense_paddr = sense_paddr; |
3071 | *(ulong32 *)&scp->host_scribble = (ulong32)((ulong64)sense_paddr >> 32); | ||
3072 | cmdp->OpCode = GDT_WRITE; /* always */ | 2738 | cmdp->OpCode = GDT_WRITE; /* always */ |
3073 | cmdp->BoardNode = LOCALBOARD; | 2739 | cmdp->BoardNode = LOCALBOARD; |
3074 | if (mode64) { | 2740 | if (mode64) { |
@@ -3080,7 +2746,7 @@ static int gdth_fill_raw_cmd(int hanum,Scsi_Cmnd *scp,unchar b) | |||
3080 | cmdp->u.raw64.lun = l; | 2746 | cmdp->u.raw64.lun = l; |
3081 | cmdp->u.raw64.bus = b; | 2747 | cmdp->u.raw64.bus = b; |
3082 | cmdp->u.raw64.priority = 0; | 2748 | cmdp->u.raw64.priority = 0; |
3083 | cmdp->u.raw64.sdlen = scp->request_bufflen; | 2749 | cmdp->u.raw64.sdlen = gdth_bufflen(scp); |
3084 | cmdp->u.raw64.sense_len = 16; | 2750 | cmdp->u.raw64.sense_len = 16; |
3085 | cmdp->u.raw64.sense_data = sense_paddr; | 2751 | cmdp->u.raw64.sense_data = sense_paddr; |
3086 | cmdp->u.raw64.direction = | 2752 | cmdp->u.raw64.direction = |
@@ -3097,7 +2763,7 @@ static int gdth_fill_raw_cmd(int hanum,Scsi_Cmnd *scp,unchar b) | |||
3097 | cmdp->u.raw.bus = b; | 2763 | cmdp->u.raw.bus = b; |
3098 | cmdp->u.raw.priority = 0; | 2764 | cmdp->u.raw.priority = 0; |
3099 | cmdp->u.raw.link_p = 0; | 2765 | cmdp->u.raw.link_p = 0; |
3100 | cmdp->u.raw.sdlen = scp->request_bufflen; | 2766 | cmdp->u.raw.sdlen = gdth_bufflen(scp); |
3101 | cmdp->u.raw.sense_len = 16; | 2767 | cmdp->u.raw.sense_len = 16; |
3102 | cmdp->u.raw.sense_data = sense_paddr; | 2768 | cmdp->u.raw.sense_data = sense_paddr; |
3103 | cmdp->u.raw.direction = | 2769 | cmdp->u.raw.direction = |
@@ -3106,16 +2772,16 @@ static int gdth_fill_raw_cmd(int hanum,Scsi_Cmnd *scp,unchar b) | |||
3106 | cmdp->u.raw.sg_ranz = 0; | 2772 | cmdp->u.raw.sg_ranz = 0; |
3107 | } | 2773 | } |
3108 | 2774 | ||
3109 | if (scp->use_sg) { | 2775 | if (gdth_bufflen(scp)) { |
3110 | sl = (struct scatterlist *)scp->request_buffer; | 2776 | cmndinfo->dma_dir = PCI_DMA_BIDIRECTIONAL; |
3111 | sgcnt = scp->use_sg; | 2777 | sgcnt = pci_map_sg(ha->pdev, gdth_sglist(scp), gdth_sg_count(scp), |
3112 | scp->SCp.Status = GDTH_MAP_SG; | 2778 | cmndinfo->dma_dir); |
3113 | scp->SCp.Message = PCI_DMA_BIDIRECTIONAL; | ||
3114 | sgcnt = pci_map_sg(ha->pdev,sl,scp->use_sg,scp->SCp.Message); | ||
3115 | if (mode64) { | 2779 | if (mode64) { |
2780 | struct scatterlist *sl; | ||
2781 | |||
3116 | cmdp->u.raw64.sdata = (ulong64)-1; | 2782 | cmdp->u.raw64.sdata = (ulong64)-1; |
3117 | cmdp->u.raw64.sg_ranz = sgcnt; | 2783 | cmdp->u.raw64.sg_ranz = sgcnt; |
3118 | for (i=0; i<sgcnt; ++i,++sl) { | 2784 | scsi_for_each_sg(scp, sl, sgcnt, i) { |
3119 | cmdp->u.raw64.sg_lst[i].sg_ptr = sg_dma_address(sl); | 2785 | cmdp->u.raw64.sg_lst[i].sg_ptr = sg_dma_address(sl); |
3120 | #ifdef GDTH_DMA_STATISTICS | 2786 | #ifdef GDTH_DMA_STATISTICS |
3121 | if (cmdp->u.raw64.sg_lst[i].sg_ptr > (ulong64)0xffffffff) | 2787 | if (cmdp->u.raw64.sg_lst[i].sg_ptr > (ulong64)0xffffffff) |
@@ -3126,9 +2792,11 @@ static int gdth_fill_raw_cmd(int hanum,Scsi_Cmnd *scp,unchar b) | |||
3126 | cmdp->u.raw64.sg_lst[i].sg_len = sg_dma_len(sl); | 2792 | cmdp->u.raw64.sg_lst[i].sg_len = sg_dma_len(sl); |
3127 | } | 2793 | } |
3128 | } else { | 2794 | } else { |
2795 | struct scatterlist *sl; | ||
2796 | |||
3129 | cmdp->u.raw.sdata = 0xffffffff; | 2797 | cmdp->u.raw.sdata = 0xffffffff; |
3130 | cmdp->u.raw.sg_ranz = sgcnt; | 2798 | cmdp->u.raw.sg_ranz = sgcnt; |
3131 | for (i=0; i<sgcnt; ++i,++sl) { | 2799 | scsi_for_each_sg(scp, sl, sgcnt, i) { |
3132 | cmdp->u.raw.sg_lst[i].sg_ptr = sg_dma_address(sl); | 2800 | cmdp->u.raw.sg_lst[i].sg_ptr = sg_dma_address(sl); |
3133 | #ifdef GDTH_DMA_STATISTICS | 2801 | #ifdef GDTH_DMA_STATISTICS |
3134 | ha->dma32_cnt++; | 2802 | ha->dma32_cnt++; |
@@ -3144,38 +2812,6 @@ static int gdth_fill_raw_cmd(int hanum,Scsi_Cmnd *scp,unchar b) | |||
3144 | } | 2812 | } |
3145 | #endif | 2813 | #endif |
3146 | 2814 | ||
3147 | } else if (scp->request_bufflen) { | ||
3148 | scp->SCp.Status = GDTH_MAP_SINGLE; | ||
3149 | scp->SCp.Message = PCI_DMA_BIDIRECTIONAL; | ||
3150 | page = virt_to_page(scp->request_buffer); | ||
3151 | offset = (ulong)scp->request_buffer & ~PAGE_MASK; | ||
3152 | phys_addr = pci_map_page(ha->pdev,page,offset, | ||
3153 | scp->request_bufflen,scp->SCp.Message); | ||
3154 | scp->SCp.dma_handle = phys_addr; | ||
3155 | |||
3156 | if (mode64) { | ||
3157 | if (ha->raw_feat & SCATTER_GATHER) { | ||
3158 | cmdp->u.raw64.sdata = (ulong64)-1; | ||
3159 | cmdp->u.raw64.sg_ranz= 1; | ||
3160 | cmdp->u.raw64.sg_lst[0].sg_ptr = phys_addr; | ||
3161 | cmdp->u.raw64.sg_lst[0].sg_len = scp->request_bufflen; | ||
3162 | cmdp->u.raw64.sg_lst[1].sg_len = 0; | ||
3163 | } else { | ||
3164 | cmdp->u.raw64.sdata = phys_addr; | ||
3165 | cmdp->u.raw64.sg_ranz= 0; | ||
3166 | } | ||
3167 | } else { | ||
3168 | if (ha->raw_feat & SCATTER_GATHER) { | ||
3169 | cmdp->u.raw.sdata = 0xffffffff; | ||
3170 | cmdp->u.raw.sg_ranz= 1; | ||
3171 | cmdp->u.raw.sg_lst[0].sg_ptr = phys_addr; | ||
3172 | cmdp->u.raw.sg_lst[0].sg_len = scp->request_bufflen; | ||
3173 | cmdp->u.raw.sg_lst[1].sg_len = 0; | ||
3174 | } else { | ||
3175 | cmdp->u.raw.sdata = phys_addr; | ||
3176 | cmdp->u.raw.sg_ranz= 0; | ||
3177 | } | ||
3178 | } | ||
3179 | } | 2815 | } |
3180 | if (mode64) { | 2816 | if (mode64) { |
3181 | TRACE(("raw cmd: addr. %x sganz %x sgptr0 %x sglen0 %x\n", | 2817 | TRACE(("raw cmd: addr. %x sganz %x sgptr0 %x sglen0 %x\n", |
@@ -3209,35 +2845,33 @@ static int gdth_fill_raw_cmd(int hanum,Scsi_Cmnd *scp,unchar b) | |||
3209 | } | 2845 | } |
3210 | 2846 | ||
3211 | /* copy command */ | 2847 | /* copy command */ |
3212 | gdth_copy_command(hanum); | 2848 | gdth_copy_command(ha); |
3213 | return cmd_index; | 2849 | return cmd_index; |
3214 | } | 2850 | } |
3215 | 2851 | ||
3216 | static int gdth_special_cmd(int hanum,Scsi_Cmnd *scp) | 2852 | static int gdth_special_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp) |
3217 | { | 2853 | { |
3218 | register gdth_ha_str *ha; | ||
3219 | register gdth_cmd_str *cmdp; | 2854 | register gdth_cmd_str *cmdp; |
3220 | int cmd_index; | 2855 | int cmd_index; |
3221 | 2856 | ||
3222 | ha = HADATA(gdth_ctr_tab[hanum]); | ||
3223 | cmdp= ha->pccb; | 2857 | cmdp= ha->pccb; |
3224 | TRACE2(("gdth_special_cmd(): ")); | 2858 | TRACE2(("gdth_special_cmd(): ")); |
3225 | 2859 | ||
3226 | if (ha->type==GDT_EISA && ha->cmd_cnt>0) | 2860 | if (ha->type==GDT_EISA && ha->cmd_cnt>0) |
3227 | return 0; | 2861 | return 0; |
3228 | 2862 | ||
3229 | memcpy( cmdp, scp->request_buffer, sizeof(gdth_cmd_str)); | 2863 | gdth_copy_internal_data(ha, scp, (char *)cmdp, sizeof(gdth_cmd_str), 1); |
3230 | cmdp->RequestBuffer = scp; | 2864 | cmdp->RequestBuffer = scp; |
3231 | 2865 | ||
3232 | /* search free command index */ | 2866 | /* search free command index */ |
3233 | if (!(cmd_index=gdth_get_cmd_index(hanum))) { | 2867 | if (!(cmd_index=gdth_get_cmd_index(ha))) { |
3234 | TRACE(("GDT: No free command index found\n")); | 2868 | TRACE(("GDT: No free command index found\n")); |
3235 | return 0; | 2869 | return 0; |
3236 | } | 2870 | } |
3237 | 2871 | ||
3238 | /* if it's the first command, set command semaphore */ | 2872 | /* if it's the first command, set command semaphore */ |
3239 | if (ha->cmd_cnt == 0) | 2873 | if (ha->cmd_cnt == 0) |
3240 | gdth_set_sema0(hanum); | 2874 | gdth_set_sema0(ha); |
3241 | 2875 | ||
3242 | /* evaluate command size, check space */ | 2876 | /* evaluate command size, check space */ |
3243 | if (cmdp->OpCode == GDT_IOCTL) { | 2877 | if (cmdp->OpCode == GDT_IOCTL) { |
@@ -3275,7 +2909,7 @@ static int gdth_special_cmd(int hanum,Scsi_Cmnd *scp) | |||
3275 | } | 2909 | } |
3276 | 2910 | ||
3277 | /* copy command */ | 2911 | /* copy command */ |
3278 | gdth_copy_command(hanum); | 2912 | gdth_copy_command(ha); |
3279 | return cmd_index; | 2913 | return cmd_index; |
3280 | } | 2914 | } |
3281 | 2915 | ||
@@ -3402,15 +3036,14 @@ static void gdth_clear_events(void) | |||
3402 | 3036 | ||
3403 | /* SCSI interface functions */ | 3037 | /* SCSI interface functions */ |
3404 | 3038 | ||
3405 | static irqreturn_t gdth_interrupt(int irq,void *dev_id) | 3039 | static irqreturn_t __gdth_interrupt(gdth_ha_str *ha, int irq, |
3040 | int gdth_from_wait, int* pIndex) | ||
3406 | { | 3041 | { |
3407 | gdth_ha_str *ha2 = (gdth_ha_str *)dev_id; | ||
3408 | register gdth_ha_str *ha; | ||
3409 | gdt6m_dpram_str __iomem *dp6m_ptr = NULL; | 3042 | gdt6m_dpram_str __iomem *dp6m_ptr = NULL; |
3410 | gdt6_dpram_str __iomem *dp6_ptr; | 3043 | gdt6_dpram_str __iomem *dp6_ptr; |
3411 | gdt2_dpram_str __iomem *dp2_ptr; | 3044 | gdt2_dpram_str __iomem *dp2_ptr; |
3412 | Scsi_Cmnd *scp; | 3045 | Scsi_Cmnd *scp; |
3413 | int hanum, rval, i; | 3046 | int rval, i; |
3414 | unchar IStatus; | 3047 | unchar IStatus; |
3415 | ushort Service; | 3048 | ushort Service; |
3416 | ulong flags = 0; | 3049 | ulong flags = 0; |
@@ -3431,17 +3064,15 @@ static irqreturn_t gdth_interrupt(int irq,void *dev_id) | |||
3431 | } | 3064 | } |
3432 | 3065 | ||
3433 | if (!gdth_polling) | 3066 | if (!gdth_polling) |
3434 | spin_lock_irqsave(&ha2->smp_lock, flags); | 3067 | spin_lock_irqsave(&ha->smp_lock, flags); |
3435 | wait_index = 0; | ||
3436 | 3068 | ||
3437 | /* search controller */ | 3069 | /* search controller */ |
3438 | if ((hanum = gdth_get_status(&IStatus,irq)) == -1) { | 3070 | if (0 == (IStatus = gdth_get_status(ha, irq))) { |
3439 | /* spurious interrupt */ | 3071 | /* spurious interrupt */ |
3440 | if (!gdth_polling) | 3072 | if (!gdth_polling) |
3441 | spin_unlock_irqrestore(&ha2->smp_lock, flags); | 3073 | spin_unlock_irqrestore(&ha->smp_lock, flags); |
3442 | return IRQ_HANDLED; | 3074 | return IRQ_HANDLED; |
3443 | } | 3075 | } |
3444 | ha = HADATA(gdth_ctr_tab[hanum]); | ||
3445 | 3076 | ||
3446 | #ifdef GDTH_STATISTICS | 3077 | #ifdef GDTH_STATISTICS |
3447 | ++act_ints; | 3078 | ++act_ints; |
@@ -3482,32 +3113,32 @@ static irqreturn_t gdth_interrupt(int irq,void *dev_id) | |||
3482 | dp2_ptr = ha->brd; | 3113 | dp2_ptr = ha->brd; |
3483 | if (IStatus & 0x80) { /* error flag */ | 3114 | if (IStatus & 0x80) { /* error flag */ |
3484 | IStatus &= ~0x80; | 3115 | IStatus &= ~0x80; |
3485 | ha->status = gdth_readw(&dp2_ptr->u.ic.Status); | 3116 | ha->status = readw(&dp2_ptr->u.ic.Status); |
3486 | TRACE2(("gdth_interrupt() error %d/%d\n",IStatus,ha->status)); | 3117 | TRACE2(("gdth_interrupt() error %d/%d\n",IStatus,ha->status)); |
3487 | } else /* no error */ | 3118 | } else /* no error */ |
3488 | ha->status = S_OK; | 3119 | ha->status = S_OK; |
3489 | ha->info = gdth_readl(&dp2_ptr->u.ic.Info[0]); | 3120 | ha->info = readl(&dp2_ptr->u.ic.Info[0]); |
3490 | ha->service = gdth_readw(&dp2_ptr->u.ic.Service); | 3121 | ha->service = readw(&dp2_ptr->u.ic.Service); |
3491 | ha->info2 = gdth_readl(&dp2_ptr->u.ic.Info[1]); | 3122 | ha->info2 = readl(&dp2_ptr->u.ic.Info[1]); |
3492 | 3123 | ||
3493 | gdth_writeb(0xff, &dp2_ptr->io.irqdel); /* acknowledge interrupt */ | 3124 | writeb(0xff, &dp2_ptr->io.irqdel); /* acknowledge interrupt */ |
3494 | gdth_writeb(0, &dp2_ptr->u.ic.Cmd_Index);/* reset command index */ | 3125 | writeb(0, &dp2_ptr->u.ic.Cmd_Index);/* reset command index */ |
3495 | gdth_writeb(0, &dp2_ptr->io.Sema1); /* reset status semaphore */ | 3126 | writeb(0, &dp2_ptr->io.Sema1); /* reset status semaphore */ |
3496 | } else if (ha->type == GDT_PCI) { | 3127 | } else if (ha->type == GDT_PCI) { |
3497 | dp6_ptr = ha->brd; | 3128 | dp6_ptr = ha->brd; |
3498 | if (IStatus & 0x80) { /* error flag */ | 3129 | if (IStatus & 0x80) { /* error flag */ |
3499 | IStatus &= ~0x80; | 3130 | IStatus &= ~0x80; |
3500 | ha->status = gdth_readw(&dp6_ptr->u.ic.Status); | 3131 | ha->status = readw(&dp6_ptr->u.ic.Status); |
3501 | TRACE2(("gdth_interrupt() error %d/%d\n",IStatus,ha->status)); | 3132 | TRACE2(("gdth_interrupt() error %d/%d\n",IStatus,ha->status)); |
3502 | } else /* no error */ | 3133 | } else /* no error */ |
3503 | ha->status = S_OK; | 3134 | ha->status = S_OK; |
3504 | ha->info = gdth_readl(&dp6_ptr->u.ic.Info[0]); | 3135 | ha->info = readl(&dp6_ptr->u.ic.Info[0]); |
3505 | ha->service = gdth_readw(&dp6_ptr->u.ic.Service); | 3136 | ha->service = readw(&dp6_ptr->u.ic.Service); |
3506 | ha->info2 = gdth_readl(&dp6_ptr->u.ic.Info[1]); | 3137 | ha->info2 = readl(&dp6_ptr->u.ic.Info[1]); |
3507 | 3138 | ||
3508 | gdth_writeb(0xff, &dp6_ptr->io.irqdel); /* acknowledge interrupt */ | 3139 | writeb(0xff, &dp6_ptr->io.irqdel); /* acknowledge interrupt */ |
3509 | gdth_writeb(0, &dp6_ptr->u.ic.Cmd_Index);/* reset command index */ | 3140 | writeb(0, &dp6_ptr->u.ic.Cmd_Index);/* reset command index */ |
3510 | gdth_writeb(0, &dp6_ptr->io.Sema1); /* reset status semaphore */ | 3141 | writeb(0, &dp6_ptr->io.Sema1); /* reset status semaphore */ |
3511 | } else if (ha->type == GDT_PCINEW) { | 3142 | } else if (ha->type == GDT_PCINEW) { |
3512 | if (IStatus & 0x80) { /* error flag */ | 3143 | if (IStatus & 0x80) { /* error flag */ |
3513 | IStatus &= ~0x80; | 3144 | IStatus &= ~0x80; |
@@ -3530,7 +3161,7 @@ static irqreturn_t gdth_interrupt(int irq,void *dev_id) | |||
3530 | ha->status = pcs->ext_status & 0xffff; | 3161 | ha->status = pcs->ext_status & 0xffff; |
3531 | else | 3162 | else |
3532 | #endif | 3163 | #endif |
3533 | ha->status = gdth_readw(&dp6m_ptr->i960r.status); | 3164 | ha->status = readw(&dp6m_ptr->i960r.status); |
3534 | TRACE2(("gdth_interrupt() error %d/%d\n",IStatus,ha->status)); | 3165 | TRACE2(("gdth_interrupt() error %d/%d\n",IStatus,ha->status)); |
3535 | } else /* no error */ | 3166 | } else /* no error */ |
3536 | ha->status = S_OK; | 3167 | ha->status = S_OK; |
@@ -3543,18 +3174,18 @@ static irqreturn_t gdth_interrupt(int irq,void *dev_id) | |||
3543 | } else | 3174 | } else |
3544 | #endif | 3175 | #endif |
3545 | { | 3176 | { |
3546 | ha->info = gdth_readl(&dp6m_ptr->i960r.info[0]); | 3177 | ha->info = readl(&dp6m_ptr->i960r.info[0]); |
3547 | ha->service = gdth_readw(&dp6m_ptr->i960r.service); | 3178 | ha->service = readw(&dp6m_ptr->i960r.service); |
3548 | ha->info2 = gdth_readl(&dp6m_ptr->i960r.info[1]); | 3179 | ha->info2 = readl(&dp6m_ptr->i960r.info[1]); |
3549 | } | 3180 | } |
3550 | /* event string */ | 3181 | /* event string */ |
3551 | if (IStatus == ASYNCINDEX) { | 3182 | if (IStatus == ASYNCINDEX) { |
3552 | if (ha->service != SCREENSERVICE && | 3183 | if (ha->service != SCREENSERVICE && |
3553 | (ha->fw_vers & 0xff) >= 0x1a) { | 3184 | (ha->fw_vers & 0xff) >= 0x1a) { |
3554 | ha->dvr.severity = gdth_readb | 3185 | ha->dvr.severity = readb |
3555 | (&((gdt6m_dpram_str __iomem *)ha->brd)->i960r.severity); | 3186 | (&((gdt6m_dpram_str __iomem *)ha->brd)->i960r.severity); |
3556 | for (i = 0; i < 256; ++i) { | 3187 | for (i = 0; i < 256; ++i) { |
3557 | ha->dvr.event_string[i] = gdth_readb | 3188 | ha->dvr.event_string[i] = readb |
3558 | (&((gdt6m_dpram_str __iomem *)ha->brd)->i960r.evt_str[i]); | 3189 | (&((gdt6m_dpram_str __iomem *)ha->brd)->i960r.evt_str[i]); |
3559 | if (ha->dvr.event_string[i] == 0) | 3190 | if (ha->dvr.event_string[i] == 0) |
3560 | break; | 3191 | break; |
@@ -3567,13 +3198,13 @@ static irqreturn_t gdth_interrupt(int irq,void *dev_id) | |||
3567 | if (!coalesced) | 3198 | if (!coalesced) |
3568 | #endif | 3199 | #endif |
3569 | { | 3200 | { |
3570 | gdth_writeb(0xff, &dp6m_ptr->i960r.edoor_reg); | 3201 | writeb(0xff, &dp6m_ptr->i960r.edoor_reg); |
3571 | gdth_writeb(0, &dp6m_ptr->i960r.sema1_reg); | 3202 | writeb(0, &dp6m_ptr->i960r.sema1_reg); |
3572 | } | 3203 | } |
3573 | } else { | 3204 | } else { |
3574 | TRACE2(("gdth_interrupt() unknown controller type\n")); | 3205 | TRACE2(("gdth_interrupt() unknown controller type\n")); |
3575 | if (!gdth_polling) | 3206 | if (!gdth_polling) |
3576 | spin_unlock_irqrestore(&ha2->smp_lock, flags); | 3207 | spin_unlock_irqrestore(&ha->smp_lock, flags); |
3577 | return IRQ_HANDLED; | 3208 | return IRQ_HANDLED; |
3578 | } | 3209 | } |
3579 | 3210 | ||
@@ -3581,26 +3212,25 @@ static irqreturn_t gdth_interrupt(int irq,void *dev_id) | |||
3581 | IStatus,ha->status,ha->info)); | 3212 | IStatus,ha->status,ha->info)); |
3582 | 3213 | ||
3583 | if (gdth_from_wait) { | 3214 | if (gdth_from_wait) { |
3584 | wait_hanum = hanum; | 3215 | *pIndex = (int)IStatus; |
3585 | wait_index = (int)IStatus; | ||
3586 | } | 3216 | } |
3587 | 3217 | ||
3588 | if (IStatus == ASYNCINDEX) { | 3218 | if (IStatus == ASYNCINDEX) { |
3589 | TRACE2(("gdth_interrupt() async. event\n")); | 3219 | TRACE2(("gdth_interrupt() async. event\n")); |
3590 | gdth_async_event(hanum); | 3220 | gdth_async_event(ha); |
3591 | if (!gdth_polling) | 3221 | if (!gdth_polling) |
3592 | spin_unlock_irqrestore(&ha2->smp_lock, flags); | 3222 | spin_unlock_irqrestore(&ha->smp_lock, flags); |
3593 | gdth_next(hanum); | 3223 | gdth_next(ha); |
3594 | return IRQ_HANDLED; | 3224 | return IRQ_HANDLED; |
3595 | } | 3225 | } |
3596 | 3226 | ||
3597 | if (IStatus == SPEZINDEX) { | 3227 | if (IStatus == SPEZINDEX) { |
3598 | TRACE2(("Service unknown or not initialized !\n")); | 3228 | TRACE2(("Service unknown or not initialized !\n")); |
3599 | ha->dvr.size = sizeof(ha->dvr.eu.driver); | 3229 | ha->dvr.size = sizeof(ha->dvr.eu.driver); |
3600 | ha->dvr.eu.driver.ionode = hanum; | 3230 | ha->dvr.eu.driver.ionode = ha->hanum; |
3601 | gdth_store_event(ha, ES_DRIVER, 4, &ha->dvr); | 3231 | gdth_store_event(ha, ES_DRIVER, 4, &ha->dvr); |
3602 | if (!gdth_polling) | 3232 | if (!gdth_polling) |
3603 | spin_unlock_irqrestore(&ha2->smp_lock, flags); | 3233 | spin_unlock_irqrestore(&ha->smp_lock, flags); |
3604 | return IRQ_HANDLED; | 3234 | return IRQ_HANDLED; |
3605 | } | 3235 | } |
3606 | scp = ha->cmd_tab[IStatus-2].cmnd; | 3236 | scp = ha->cmd_tab[IStatus-2].cmnd; |
@@ -3609,28 +3239,28 @@ static irqreturn_t gdth_interrupt(int irq,void *dev_id) | |||
3609 | if (scp == UNUSED_CMND) { | 3239 | if (scp == UNUSED_CMND) { |
3610 | TRACE2(("gdth_interrupt() index to unused command (%d)\n",IStatus)); | 3240 | TRACE2(("gdth_interrupt() index to unused command (%d)\n",IStatus)); |
3611 | ha->dvr.size = sizeof(ha->dvr.eu.driver); | 3241 | ha->dvr.size = sizeof(ha->dvr.eu.driver); |
3612 | ha->dvr.eu.driver.ionode = hanum; | 3242 | ha->dvr.eu.driver.ionode = ha->hanum; |
3613 | ha->dvr.eu.driver.index = IStatus; | 3243 | ha->dvr.eu.driver.index = IStatus; |
3614 | gdth_store_event(ha, ES_DRIVER, 1, &ha->dvr); | 3244 | gdth_store_event(ha, ES_DRIVER, 1, &ha->dvr); |
3615 | if (!gdth_polling) | 3245 | if (!gdth_polling) |
3616 | spin_unlock_irqrestore(&ha2->smp_lock, flags); | 3246 | spin_unlock_irqrestore(&ha->smp_lock, flags); |
3617 | return IRQ_HANDLED; | 3247 | return IRQ_HANDLED; |
3618 | } | 3248 | } |
3619 | if (scp == INTERNAL_CMND) { | 3249 | if (scp == INTERNAL_CMND) { |
3620 | TRACE(("gdth_interrupt() answer to internal command\n")); | 3250 | TRACE(("gdth_interrupt() answer to internal command\n")); |
3621 | if (!gdth_polling) | 3251 | if (!gdth_polling) |
3622 | spin_unlock_irqrestore(&ha2->smp_lock, flags); | 3252 | spin_unlock_irqrestore(&ha->smp_lock, flags); |
3623 | return IRQ_HANDLED; | 3253 | return IRQ_HANDLED; |
3624 | } | 3254 | } |
3625 | 3255 | ||
3626 | TRACE(("gdth_interrupt() sync. status\n")); | 3256 | TRACE(("gdth_interrupt() sync. status\n")); |
3627 | rval = gdth_sync_event(hanum,Service,IStatus,scp); | 3257 | rval = gdth_sync_event(ha,Service,IStatus,scp); |
3628 | if (!gdth_polling) | 3258 | if (!gdth_polling) |
3629 | spin_unlock_irqrestore(&ha2->smp_lock, flags); | 3259 | spin_unlock_irqrestore(&ha->smp_lock, flags); |
3630 | if (rval == 2) { | 3260 | if (rval == 2) { |
3631 | gdth_putq(hanum,scp,scp->SCp.this_residual); | 3261 | gdth_putq(ha, scp, gdth_cmnd_priv(scp)->priority); |
3632 | } else if (rval == 1) { | 3262 | } else if (rval == 1) { |
3633 | scp->scsi_done(scp); | 3263 | gdth_scsi_done(scp); |
3634 | } | 3264 | } |
3635 | 3265 | ||
3636 | #ifdef INT_COAL | 3266 | #ifdef INT_COAL |
@@ -3653,23 +3283,30 @@ static irqreturn_t gdth_interrupt(int irq,void *dev_id) | |||
3653 | 3283 | ||
3654 | /* coalescing only for new GDT_PCIMPR controllers available */ | 3284 | /* coalescing only for new GDT_PCIMPR controllers available */ |
3655 | if (ha->type == GDT_PCIMPR && coalesced) { | 3285 | if (ha->type == GDT_PCIMPR && coalesced) { |
3656 | gdth_writeb(0xff, &dp6m_ptr->i960r.edoor_reg); | 3286 | writeb(0xff, &dp6m_ptr->i960r.edoor_reg); |
3657 | gdth_writeb(0, &dp6m_ptr->i960r.sema1_reg); | 3287 | writeb(0, &dp6m_ptr->i960r.sema1_reg); |
3658 | } | 3288 | } |
3659 | #endif | 3289 | #endif |
3660 | 3290 | ||
3661 | gdth_next(hanum); | 3291 | gdth_next(ha); |
3662 | return IRQ_HANDLED; | 3292 | return IRQ_HANDLED; |
3663 | } | 3293 | } |
3664 | 3294 | ||
3665 | static int gdth_sync_event(int hanum,int service,unchar index,Scsi_Cmnd *scp) | 3295 | static irqreturn_t gdth_interrupt(int irq, void *dev_id) |
3296 | { | ||
3297 | gdth_ha_str *ha = (gdth_ha_str *)dev_id; | ||
3298 | |||
3299 | return __gdth_interrupt(ha, irq, false, NULL); | ||
3300 | } | ||
3301 | |||
3302 | static int gdth_sync_event(gdth_ha_str *ha, int service, unchar index, | ||
3303 | Scsi_Cmnd *scp) | ||
3666 | { | 3304 | { |
3667 | register gdth_ha_str *ha; | ||
3668 | gdth_msg_str *msg; | 3305 | gdth_msg_str *msg; |
3669 | gdth_cmd_str *cmdp; | 3306 | gdth_cmd_str *cmdp; |
3670 | unchar b, t; | 3307 | unchar b, t; |
3308 | struct gdth_cmndinfo *cmndinfo = gdth_cmnd_priv(scp); | ||
3671 | 3309 | ||
3672 | ha = HADATA(gdth_ctr_tab[hanum]); | ||
3673 | cmdp = ha->pccb; | 3310 | cmdp = ha->pccb; |
3674 | TRACE(("gdth_sync_event() serv %d status %d\n", | 3311 | TRACE(("gdth_sync_event() serv %d status %d\n", |
3675 | service,ha->status)); | 3312 | service,ha->status)); |
@@ -3687,12 +3324,12 @@ static int gdth_sync_event(int hanum,int service,unchar index,Scsi_Cmnd *scp) | |||
3687 | } | 3324 | } |
3688 | 3325 | ||
3689 | if (msg->msg_ext && !msg->msg_answer) { | 3326 | if (msg->msg_ext && !msg->msg_answer) { |
3690 | while (gdth_test_busy(hanum)) | 3327 | while (gdth_test_busy(ha)) |
3691 | gdth_delay(0); | 3328 | gdth_delay(0); |
3692 | cmdp->Service = SCREENSERVICE; | 3329 | cmdp->Service = SCREENSERVICE; |
3693 | cmdp->RequestBuffer = SCREEN_CMND; | 3330 | cmdp->RequestBuffer = SCREEN_CMND; |
3694 | gdth_get_cmd_index(hanum); | 3331 | gdth_get_cmd_index(ha); |
3695 | gdth_set_sema0(hanum); | 3332 | gdth_set_sema0(ha); |
3696 | cmdp->OpCode = GDT_READ; | 3333 | cmdp->OpCode = GDT_READ; |
3697 | cmdp->BoardNode = LOCALBOARD; | 3334 | cmdp->BoardNode = LOCALBOARD; |
3698 | cmdp->u.screen.reserved = 0; | 3335 | cmdp->u.screen.reserved = 0; |
@@ -3702,8 +3339,8 @@ static int gdth_sync_event(int hanum,int service,unchar index,Scsi_Cmnd *scp) | |||
3702 | ha->cmd_len = GDTOFFSOF(gdth_cmd_str,u.screen.su.msg.msg_addr) | 3339 | ha->cmd_len = GDTOFFSOF(gdth_cmd_str,u.screen.su.msg.msg_addr) |
3703 | + sizeof(ulong64); | 3340 | + sizeof(ulong64); |
3704 | ha->cmd_cnt = 0; | 3341 | ha->cmd_cnt = 0; |
3705 | gdth_copy_command(hanum); | 3342 | gdth_copy_command(ha); |
3706 | gdth_release_event(hanum); | 3343 | gdth_release_event(ha); |
3707 | return 0; | 3344 | return 0; |
3708 | } | 3345 | } |
3709 | 3346 | ||
@@ -3721,12 +3358,12 @@ static int gdth_sync_event(int hanum,int service,unchar index,Scsi_Cmnd *scp) | |||
3721 | } | 3358 | } |
3722 | msg->msg_ext = 0; | 3359 | msg->msg_ext = 0; |
3723 | msg->msg_answer = 0; | 3360 | msg->msg_answer = 0; |
3724 | while (gdth_test_busy(hanum)) | 3361 | while (gdth_test_busy(ha)) |
3725 | gdth_delay(0); | 3362 | gdth_delay(0); |
3726 | cmdp->Service = SCREENSERVICE; | 3363 | cmdp->Service = SCREENSERVICE; |
3727 | cmdp->RequestBuffer = SCREEN_CMND; | 3364 | cmdp->RequestBuffer = SCREEN_CMND; |
3728 | gdth_get_cmd_index(hanum); | 3365 | gdth_get_cmd_index(ha); |
3729 | gdth_set_sema0(hanum); | 3366 | gdth_set_sema0(ha); |
3730 | cmdp->OpCode = GDT_WRITE; | 3367 | cmdp->OpCode = GDT_WRITE; |
3731 | cmdp->BoardNode = LOCALBOARD; | 3368 | cmdp->BoardNode = LOCALBOARD; |
3732 | cmdp->u.screen.reserved = 0; | 3369 | cmdp->u.screen.reserved = 0; |
@@ -3736,74 +3373,67 @@ static int gdth_sync_event(int hanum,int service,unchar index,Scsi_Cmnd *scp) | |||
3736 | ha->cmd_len = GDTOFFSOF(gdth_cmd_str,u.screen.su.msg.msg_addr) | 3373 | ha->cmd_len = GDTOFFSOF(gdth_cmd_str,u.screen.su.msg.msg_addr) |
3737 | + sizeof(ulong64); | 3374 | + sizeof(ulong64); |
3738 | ha->cmd_cnt = 0; | 3375 | ha->cmd_cnt = 0; |
3739 | gdth_copy_command(hanum); | 3376 | gdth_copy_command(ha); |
3740 | gdth_release_event(hanum); | 3377 | gdth_release_event(ha); |
3741 | return 0; | 3378 | return 0; |
3742 | } | 3379 | } |
3743 | printk("\n"); | 3380 | printk("\n"); |
3744 | 3381 | ||
3745 | } else { | 3382 | } else { |
3746 | b = virt_ctr ? NUMDATA(scp->device->host)->busnum : scp->device->channel; | 3383 | b = scp->device->channel; |
3747 | t = scp->device->id; | 3384 | t = scp->device->id; |
3748 | if (scp->SCp.sent_command == -1 && b != ha->virt_bus) { | 3385 | if (cmndinfo->OpCode == -1 && b != ha->virt_bus) { |
3749 | ha->raw[BUS_L2P(ha,b)].io_cnt[t]--; | 3386 | ha->raw[BUS_L2P(ha,b)].io_cnt[t]--; |
3750 | } | 3387 | } |
3751 | /* cache or raw service */ | 3388 | /* cache or raw service */ |
3752 | if (ha->status == S_BSY) { | 3389 | if (ha->status == S_BSY) { |
3753 | TRACE2(("Controller busy -> retry !\n")); | 3390 | TRACE2(("Controller busy -> retry !\n")); |
3754 | if (scp->SCp.sent_command == GDT_MOUNT) | 3391 | if (cmndinfo->OpCode == GDT_MOUNT) |
3755 | scp->SCp.sent_command = GDT_CLUST_INFO; | 3392 | cmndinfo->OpCode = GDT_CLUST_INFO; |
3756 | /* retry */ | 3393 | /* retry */ |
3757 | return 2; | 3394 | return 2; |
3758 | } | 3395 | } |
3759 | if (scp->SCp.Status == GDTH_MAP_SG) | 3396 | if (gdth_bufflen(scp)) |
3760 | pci_unmap_sg(ha->pdev,scp->request_buffer, | 3397 | pci_unmap_sg(ha->pdev, gdth_sglist(scp), gdth_sg_count(scp), |
3761 | scp->use_sg,scp->SCp.Message); | 3398 | cmndinfo->dma_dir); |
3762 | else if (scp->SCp.Status == GDTH_MAP_SINGLE) | 3399 | |
3763 | pci_unmap_page(ha->pdev,scp->SCp.dma_handle, | 3400 | if (cmndinfo->sense_paddr) |
3764 | scp->request_bufflen,scp->SCp.Message); | 3401 | pci_unmap_page(ha->pdev, cmndinfo->sense_paddr, 16, |
3765 | if (scp->SCp.buffer) { | 3402 | PCI_DMA_FROMDEVICE); |
3766 | dma_addr_t addr; | ||
3767 | addr = (dma_addr_t)*(ulong32 *)&scp->SCp.buffer; | ||
3768 | if (scp->host_scribble) | ||
3769 | addr += (dma_addr_t) | ||
3770 | ((ulong64)(*(ulong32 *)&scp->host_scribble) << 32); | ||
3771 | pci_unmap_page(ha->pdev,addr,16,PCI_DMA_FROMDEVICE); | ||
3772 | } | ||
3773 | 3403 | ||
3774 | if (ha->status == S_OK) { | 3404 | if (ha->status == S_OK) { |
3775 | scp->SCp.Status = S_OK; | 3405 | cmndinfo->status = S_OK; |
3776 | scp->SCp.Message = ha->info; | 3406 | cmndinfo->info = ha->info; |
3777 | if (scp->SCp.sent_command != -1) { | 3407 | if (cmndinfo->OpCode != -1) { |
3778 | TRACE2(("gdth_sync_event(): special cmd 0x%x OK\n", | 3408 | TRACE2(("gdth_sync_event(): special cmd 0x%x OK\n", |
3779 | scp->SCp.sent_command)); | 3409 | cmndinfo->OpCode)); |
3780 | /* special commands GDT_CLUST_INFO/GDT_MOUNT ? */ | 3410 | /* special commands GDT_CLUST_INFO/GDT_MOUNT ? */ |
3781 | if (scp->SCp.sent_command == GDT_CLUST_INFO) { | 3411 | if (cmndinfo->OpCode == GDT_CLUST_INFO) { |
3782 | ha->hdr[t].cluster_type = (unchar)ha->info; | 3412 | ha->hdr[t].cluster_type = (unchar)ha->info; |
3783 | if (!(ha->hdr[t].cluster_type & | 3413 | if (!(ha->hdr[t].cluster_type & |
3784 | CLUSTER_MOUNTED)) { | 3414 | CLUSTER_MOUNTED)) { |
3785 | /* NOT MOUNTED -> MOUNT */ | 3415 | /* NOT MOUNTED -> MOUNT */ |
3786 | scp->SCp.sent_command = GDT_MOUNT; | 3416 | cmndinfo->OpCode = GDT_MOUNT; |
3787 | if (ha->hdr[t].cluster_type & | 3417 | if (ha->hdr[t].cluster_type & |
3788 | CLUSTER_RESERVED) { | 3418 | CLUSTER_RESERVED) { |
3789 | /* cluster drive RESERVED (on the other node) */ | 3419 | /* cluster drive RESERVED (on the other node) */ |
3790 | scp->SCp.phase = -2; /* reservation conflict */ | 3420 | cmndinfo->phase = -2; /* reservation conflict */ |
3791 | } | 3421 | } |
3792 | } else { | 3422 | } else { |
3793 | scp->SCp.sent_command = -1; | 3423 | cmndinfo->OpCode = -1; |
3794 | } | 3424 | } |
3795 | } else { | 3425 | } else { |
3796 | if (scp->SCp.sent_command == GDT_MOUNT) { | 3426 | if (cmndinfo->OpCode == GDT_MOUNT) { |
3797 | ha->hdr[t].cluster_type |= CLUSTER_MOUNTED; | 3427 | ha->hdr[t].cluster_type |= CLUSTER_MOUNTED; |
3798 | ha->hdr[t].media_changed = TRUE; | 3428 | ha->hdr[t].media_changed = TRUE; |
3799 | } else if (scp->SCp.sent_command == GDT_UNMOUNT) { | 3429 | } else if (cmndinfo->OpCode == GDT_UNMOUNT) { |
3800 | ha->hdr[t].cluster_type &= ~CLUSTER_MOUNTED; | 3430 | ha->hdr[t].cluster_type &= ~CLUSTER_MOUNTED; |
3801 | ha->hdr[t].media_changed = TRUE; | 3431 | ha->hdr[t].media_changed = TRUE; |
3802 | } | 3432 | } |
3803 | scp->SCp.sent_command = -1; | 3433 | cmndinfo->OpCode = -1; |
3804 | } | 3434 | } |
3805 | /* retry */ | 3435 | /* retry */ |
3806 | scp->SCp.this_residual = HIGH_PRI; | 3436 | cmndinfo->priority = HIGH_PRI; |
3807 | return 2; | 3437 | return 2; |
3808 | } else { | 3438 | } else { |
3809 | /* RESERVE/RELEASE ? */ | 3439 | /* RESERVE/RELEASE ? */ |
@@ -3816,17 +3446,17 @@ static int gdth_sync_event(int hanum,int service,unchar index,Scsi_Cmnd *scp) | |||
3816 | scp->sense_buffer[0] = 0; | 3446 | scp->sense_buffer[0] = 0; |
3817 | } | 3447 | } |
3818 | } else { | 3448 | } else { |
3819 | scp->SCp.Status = ha->status; | 3449 | cmndinfo->status = ha->status; |
3820 | scp->SCp.Message = ha->info; | 3450 | cmndinfo->info = ha->info; |
3821 | 3451 | ||
3822 | if (scp->SCp.sent_command != -1) { | 3452 | if (cmndinfo->OpCode != -1) { |
3823 | TRACE2(("gdth_sync_event(): special cmd 0x%x error 0x%x\n", | 3453 | TRACE2(("gdth_sync_event(): special cmd 0x%x error 0x%x\n", |
3824 | scp->SCp.sent_command, ha->status)); | 3454 | cmndinfo->OpCode, ha->status)); |
3825 | if (scp->SCp.sent_command == GDT_SCAN_START || | 3455 | if (cmndinfo->OpCode == GDT_SCAN_START || |
3826 | scp->SCp.sent_command == GDT_SCAN_END) { | 3456 | cmndinfo->OpCode == GDT_SCAN_END) { |
3827 | scp->SCp.sent_command = -1; | 3457 | cmndinfo->OpCode = -1; |
3828 | /* retry */ | 3458 | /* retry */ |
3829 | scp->SCp.this_residual = HIGH_PRI; | 3459 | cmndinfo->priority = HIGH_PRI; |
3830 | return 2; | 3460 | return 2; |
3831 | } | 3461 | } |
3832 | memset((char*)scp->sense_buffer,0,16); | 3462 | memset((char*)scp->sense_buffer,0,16); |
@@ -3848,9 +3478,9 @@ static int gdth_sync_event(int hanum,int service,unchar index,Scsi_Cmnd *scp) | |||
3848 | scp->sense_buffer[2] = NOT_READY; | 3478 | scp->sense_buffer[2] = NOT_READY; |
3849 | scp->result = (DID_OK << 16) | (CHECK_CONDITION << 1); | 3479 | scp->result = (DID_OK << 16) | (CHECK_CONDITION << 1); |
3850 | } | 3480 | } |
3851 | if (scp->done != gdth_scsi_done) { | 3481 | if (!cmndinfo->internal_command) { |
3852 | ha->dvr.size = sizeof(ha->dvr.eu.sync); | 3482 | ha->dvr.size = sizeof(ha->dvr.eu.sync); |
3853 | ha->dvr.eu.sync.ionode = hanum; | 3483 | ha->dvr.eu.sync.ionode = ha->hanum; |
3854 | ha->dvr.eu.sync.service = service; | 3484 | ha->dvr.eu.sync.service = service; |
3855 | ha->dvr.eu.sync.status = ha->status; | 3485 | ha->dvr.eu.sync.status = ha->status; |
3856 | ha->dvr.eu.sync.info = ha->info; | 3486 | ha->dvr.eu.sync.info = ha->info; |
@@ -3869,8 +3499,8 @@ static int gdth_sync_event(int hanum,int service,unchar index,Scsi_Cmnd *scp) | |||
3869 | } | 3499 | } |
3870 | } | 3500 | } |
3871 | } | 3501 | } |
3872 | if (!scp->SCp.have_data_in) | 3502 | if (!cmndinfo->wait_for_completion) |
3873 | scp->SCp.have_data_in++; | 3503 | cmndinfo->wait_for_completion++; |
3874 | else | 3504 | else |
3875 | return 1; | 3505 | return 1; |
3876 | } | 3506 | } |
@@ -4034,25 +3664,23 @@ static char *async_cache_tab[] = { | |||
4034 | }; | 3664 | }; |
4035 | 3665 | ||
4036 | 3666 | ||
4037 | static int gdth_async_event(int hanum) | 3667 | static int gdth_async_event(gdth_ha_str *ha) |
4038 | { | 3668 | { |
4039 | gdth_ha_str *ha; | ||
4040 | gdth_cmd_str *cmdp; | 3669 | gdth_cmd_str *cmdp; |
4041 | int cmd_index; | 3670 | int cmd_index; |
4042 | 3671 | ||
4043 | ha = HADATA(gdth_ctr_tab[hanum]); | ||
4044 | cmdp= ha->pccb; | 3672 | cmdp= ha->pccb; |
4045 | TRACE2(("gdth_async_event() ha %d serv %d\n", | 3673 | TRACE2(("gdth_async_event() ha %d serv %d\n", |
4046 | hanum,ha->service)); | 3674 | ha->hanum, ha->service)); |
4047 | 3675 | ||
4048 | if (ha->service == SCREENSERVICE) { | 3676 | if (ha->service == SCREENSERVICE) { |
4049 | if (ha->status == MSG_REQUEST) { | 3677 | if (ha->status == MSG_REQUEST) { |
4050 | while (gdth_test_busy(hanum)) | 3678 | while (gdth_test_busy(ha)) |
4051 | gdth_delay(0); | 3679 | gdth_delay(0); |
4052 | cmdp->Service = SCREENSERVICE; | 3680 | cmdp->Service = SCREENSERVICE; |
4053 | cmdp->RequestBuffer = SCREEN_CMND; | 3681 | cmdp->RequestBuffer = SCREEN_CMND; |
4054 | cmd_index = gdth_get_cmd_index(hanum); | 3682 | cmd_index = gdth_get_cmd_index(ha); |
4055 | gdth_set_sema0(hanum); | 3683 | gdth_set_sema0(ha); |
4056 | cmdp->OpCode = GDT_READ; | 3684 | cmdp->OpCode = GDT_READ; |
4057 | cmdp->BoardNode = LOCALBOARD; | 3685 | cmdp->BoardNode = LOCALBOARD; |
4058 | cmdp->u.screen.reserved = 0; | 3686 | cmdp->u.screen.reserved = 0; |
@@ -4062,7 +3690,7 @@ static int gdth_async_event(int hanum) | |||
4062 | ha->cmd_len = GDTOFFSOF(gdth_cmd_str,u.screen.su.msg.msg_addr) | 3690 | ha->cmd_len = GDTOFFSOF(gdth_cmd_str,u.screen.su.msg.msg_addr) |
4063 | + sizeof(ulong64); | 3691 | + sizeof(ulong64); |
4064 | ha->cmd_cnt = 0; | 3692 | ha->cmd_cnt = 0; |
4065 | gdth_copy_command(hanum); | 3693 | gdth_copy_command(ha); |
4066 | if (ha->type == GDT_EISA) | 3694 | if (ha->type == GDT_EISA) |
4067 | printk("[EISA slot %d] ",(ushort)ha->brd_phys); | 3695 | printk("[EISA slot %d] ",(ushort)ha->brd_phys); |
4068 | else if (ha->type == GDT_ISA) | 3696 | else if (ha->type == GDT_ISA) |
@@ -4070,19 +3698,19 @@ static int gdth_async_event(int hanum) | |||
4070 | else | 3698 | else |
4071 | printk("[PCI %d/%d] ",(ushort)(ha->brd_phys>>8), | 3699 | printk("[PCI %d/%d] ",(ushort)(ha->brd_phys>>8), |
4072 | (ushort)((ha->brd_phys>>3)&0x1f)); | 3700 | (ushort)((ha->brd_phys>>3)&0x1f)); |
4073 | gdth_release_event(hanum); | 3701 | gdth_release_event(ha); |
4074 | } | 3702 | } |
4075 | 3703 | ||
4076 | } else { | 3704 | } else { |
4077 | if (ha->type == GDT_PCIMPR && | 3705 | if (ha->type == GDT_PCIMPR && |
4078 | (ha->fw_vers & 0xff) >= 0x1a) { | 3706 | (ha->fw_vers & 0xff) >= 0x1a) { |
4079 | ha->dvr.size = 0; | 3707 | ha->dvr.size = 0; |
4080 | ha->dvr.eu.async.ionode = hanum; | 3708 | ha->dvr.eu.async.ionode = ha->hanum; |
4081 | ha->dvr.eu.async.status = ha->status; | 3709 | ha->dvr.eu.async.status = ha->status; |
4082 | /* severity and event_string already set! */ | 3710 | /* severity and event_string already set! */ |
4083 | } else { | 3711 | } else { |
4084 | ha->dvr.size = sizeof(ha->dvr.eu.async); | 3712 | ha->dvr.size = sizeof(ha->dvr.eu.async); |
4085 | ha->dvr.eu.async.ionode = hanum; | 3713 | ha->dvr.eu.async.ionode = ha->hanum; |
4086 | ha->dvr.eu.async.service = ha->service; | 3714 | ha->dvr.eu.async.service = ha->service; |
4087 | ha->dvr.eu.async.status = ha->status; | 3715 | ha->dvr.eu.async.status = ha->status; |
4088 | ha->dvr.eu.async.info = ha->info; | 3716 | ha->dvr.eu.async.info = ha->info; |
@@ -4164,9 +3792,8 @@ static void gdth_timeout(ulong data) | |||
4164 | Scsi_Cmnd *nscp; | 3792 | Scsi_Cmnd *nscp; |
4165 | gdth_ha_str *ha; | 3793 | gdth_ha_str *ha; |
4166 | ulong flags; | 3794 | ulong flags; |
4167 | int hanum = 0; | ||
4168 | 3795 | ||
4169 | ha = HADATA(gdth_ctr_tab[hanum]); | 3796 | ha = list_first_entry(&gdth_instances, gdth_ha_str, list); |
4170 | spin_lock_irqsave(&ha->smp_lock, flags); | 3797 | spin_lock_irqsave(&ha->smp_lock, flags); |
4171 | 3798 | ||
4172 | for (act_stats=0,i=0; i<GDTH_MAXCMDS; ++i) | 3799 | for (act_stats=0,i=0; i<GDTH_MAXCMDS; ++i) |
@@ -4229,8 +3856,6 @@ static void __init internal_setup(char *str,int *ints) | |||
4229 | max_ids = val; | 3856 | max_ids = val; |
4230 | else if (!strncmp(argv, "rescan:", 7)) | 3857 | else if (!strncmp(argv, "rescan:", 7)) |
4231 | rescan = val; | 3858 | rescan = val; |
4232 | else if (!strncmp(argv, "virt_ctr:", 9)) | ||
4233 | virt_ctr = val; | ||
4234 | else if (!strncmp(argv, "shared_access:", 14)) | 3859 | else if (!strncmp(argv, "shared_access:", 14)) |
4235 | shared_access = val; | 3860 | shared_access = val; |
4236 | else if (!strncmp(argv, "probe_eisa_isa:", 15)) | 3861 | else if (!strncmp(argv, "probe_eisa_isa:", 15)) |
@@ -4277,523 +3902,10 @@ int __init option_setup(char *str) | |||
4277 | return 1; | 3902 | return 1; |
4278 | } | 3903 | } |
4279 | 3904 | ||
4280 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) | 3905 | static const char *gdth_ctr_name(gdth_ha_str *ha) |
4281 | static int __init gdth_detect(struct scsi_host_template *shtp) | ||
4282 | #else | ||
4283 | static int __init gdth_detect(Scsi_Host_Template *shtp) | ||
4284 | #endif | ||
4285 | { | ||
4286 | struct Scsi_Host *shp; | ||
4287 | gdth_pci_str pcistr[MAXHA]; | ||
4288 | gdth_ha_str *ha; | ||
4289 | ulong32 isa_bios; | ||
4290 | ushort eisa_slot; | ||
4291 | int i,hanum,cnt,ctr,err; | ||
4292 | unchar b; | ||
4293 | |||
4294 | |||
4295 | #ifdef DEBUG_GDTH | ||
4296 | printk("GDT: This driver contains debugging information !! Trace level = %d\n", | ||
4297 | DebugState); | ||
4298 | printk(" Destination of debugging information: "); | ||
4299 | #ifdef __SERIAL__ | ||
4300 | #ifdef __COM2__ | ||
4301 | printk("Serial port COM2\n"); | ||
4302 | #else | ||
4303 | printk("Serial port COM1\n"); | ||
4304 | #endif | ||
4305 | #else | ||
4306 | printk("Console\n"); | ||
4307 | #endif | ||
4308 | gdth_delay(3000); | ||
4309 | #endif | ||
4310 | |||
4311 | TRACE(("gdth_detect()\n")); | ||
4312 | |||
4313 | if (disable) { | ||
4314 | printk("GDT-HA: Controller driver disabled from command line !\n"); | ||
4315 | return 0; | ||
4316 | } | ||
4317 | |||
4318 | printk("GDT-HA: Storage RAID Controller Driver. Version: %s\n",GDTH_VERSION_STR); | ||
4319 | /* initializations */ | ||
4320 | gdth_polling = TRUE; b = 0; | ||
4321 | gdth_clear_events(); | ||
4322 | |||
4323 | /* As default we do not probe for EISA or ISA controllers */ | ||
4324 | if (probe_eisa_isa) { | ||
4325 | /* scanning for controllers, at first: ISA controller */ | ||
4326 | for (isa_bios=0xc8000UL; isa_bios<=0xd8000UL; isa_bios+=0x8000UL) { | ||
4327 | dma_addr_t scratch_dma_handle; | ||
4328 | scratch_dma_handle = 0; | ||
4329 | |||
4330 | if (gdth_ctr_count >= MAXHA) | ||
4331 | break; | ||
4332 | if (gdth_search_isa(isa_bios)) { /* controller found */ | ||
4333 | shp = scsi_register(shtp,sizeof(gdth_ext_str)); | ||
4334 | if (shp == NULL) | ||
4335 | continue; | ||
4336 | |||
4337 | ha = HADATA(shp); | ||
4338 | if (!gdth_init_isa(isa_bios,ha)) { | ||
4339 | scsi_unregister(shp); | ||
4340 | continue; | ||
4341 | } | ||
4342 | #ifdef __ia64__ | ||
4343 | break; | ||
4344 | #else | ||
4345 | /* controller found and initialized */ | ||
4346 | printk("Configuring GDT-ISA HA at BIOS 0x%05X IRQ %u DRQ %u\n", | ||
4347 | isa_bios,ha->irq,ha->drq); | ||
4348 | |||
4349 | if (request_irq(ha->irq,gdth_interrupt,IRQF_DISABLED,"gdth",ha)) { | ||
4350 | printk("GDT-ISA: Unable to allocate IRQ\n"); | ||
4351 | scsi_unregister(shp); | ||
4352 | continue; | ||
4353 | } | ||
4354 | if (request_dma(ha->drq,"gdth")) { | ||
4355 | printk("GDT-ISA: Unable to allocate DMA channel\n"); | ||
4356 | free_irq(ha->irq,ha); | ||
4357 | scsi_unregister(shp); | ||
4358 | continue; | ||
4359 | } | ||
4360 | set_dma_mode(ha->drq,DMA_MODE_CASCADE); | ||
4361 | enable_dma(ha->drq); | ||
4362 | shp->unchecked_isa_dma = 1; | ||
4363 | shp->irq = ha->irq; | ||
4364 | shp->dma_channel = ha->drq; | ||
4365 | hanum = gdth_ctr_count; | ||
4366 | gdth_ctr_tab[gdth_ctr_count++] = shp; | ||
4367 | gdth_ctr_vtab[gdth_ctr_vcount++] = shp; | ||
4368 | |||
4369 | NUMDATA(shp)->hanum = (ushort)hanum; | ||
4370 | NUMDATA(shp)->busnum= 0; | ||
4371 | |||
4372 | ha->pccb = CMDDATA(shp); | ||
4373 | ha->ccb_phys = 0L; | ||
4374 | ha->pdev = NULL; | ||
4375 | ha->pscratch = pci_alloc_consistent(ha->pdev, GDTH_SCRATCH, | ||
4376 | &scratch_dma_handle); | ||
4377 | ha->scratch_phys = scratch_dma_handle; | ||
4378 | ha->pmsg = pci_alloc_consistent(ha->pdev, sizeof(gdth_msg_str), | ||
4379 | &scratch_dma_handle); | ||
4380 | ha->msg_phys = scratch_dma_handle; | ||
4381 | #ifdef INT_COAL | ||
4382 | ha->coal_stat = (gdth_coal_status *) | ||
4383 | pci_alloc_consistent(ha->pdev, sizeof(gdth_coal_status) * | ||
4384 | MAXOFFSETS, &scratch_dma_handle); | ||
4385 | ha->coal_stat_phys = scratch_dma_handle; | ||
4386 | #endif | ||
4387 | |||
4388 | ha->scratch_busy = FALSE; | ||
4389 | ha->req_first = NULL; | ||
4390 | ha->tid_cnt = MAX_HDRIVES; | ||
4391 | if (max_ids > 0 && max_ids < ha->tid_cnt) | ||
4392 | ha->tid_cnt = max_ids; | ||
4393 | for (i=0; i<GDTH_MAXCMDS; ++i) | ||
4394 | ha->cmd_tab[i].cmnd = UNUSED_CMND; | ||
4395 | ha->scan_mode = rescan ? 0x10 : 0; | ||
4396 | |||
4397 | if (ha->pscratch == NULL || ha->pmsg == NULL || | ||
4398 | !gdth_search_drives(hanum)) { | ||
4399 | printk("GDT-ISA: Error during device scan\n"); | ||
4400 | --gdth_ctr_count; | ||
4401 | --gdth_ctr_vcount; | ||
4402 | |||
4403 | #ifdef INT_COAL | ||
4404 | if (ha->coal_stat) | ||
4405 | pci_free_consistent(ha->pdev, sizeof(gdth_coal_status) * | ||
4406 | MAXOFFSETS, ha->coal_stat, | ||
4407 | ha->coal_stat_phys); | ||
4408 | #endif | ||
4409 | if (ha->pscratch) | ||
4410 | pci_free_consistent(ha->pdev, GDTH_SCRATCH, | ||
4411 | ha->pscratch, ha->scratch_phys); | ||
4412 | if (ha->pmsg) | ||
4413 | pci_free_consistent(ha->pdev, sizeof(gdth_msg_str), | ||
4414 | ha->pmsg, ha->msg_phys); | ||
4415 | |||
4416 | free_irq(ha->irq,ha); | ||
4417 | scsi_unregister(shp); | ||
4418 | continue; | ||
4419 | } | ||
4420 | if (hdr_channel < 0 || hdr_channel > ha->bus_cnt) | ||
4421 | hdr_channel = ha->bus_cnt; | ||
4422 | ha->virt_bus = hdr_channel; | ||
4423 | |||
4424 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,20) && \ | ||
4425 | LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) | ||
4426 | shp->highmem_io = 0; | ||
4427 | #endif | ||
4428 | if (ha->cache_feat & ha->raw_feat & ha->screen_feat & GDT_64BIT) | ||
4429 | shp->max_cmd_len = 16; | ||
4430 | |||
4431 | shp->max_id = ha->tid_cnt; | ||
4432 | shp->max_lun = MAXLUN; | ||
4433 | shp->max_channel = virt_ctr ? 0 : ha->bus_cnt; | ||
4434 | if (virt_ctr) { | ||
4435 | virt_ctr = 1; | ||
4436 | /* register addit. SCSI channels as virtual controllers */ | ||
4437 | for (b = 1; b < ha->bus_cnt + 1; ++b) { | ||
4438 | shp = scsi_register(shtp,sizeof(gdth_num_str)); | ||
4439 | shp->unchecked_isa_dma = 1; | ||
4440 | shp->irq = ha->irq; | ||
4441 | shp->dma_channel = ha->drq; | ||
4442 | gdth_ctr_vtab[gdth_ctr_vcount++] = shp; | ||
4443 | NUMDATA(shp)->hanum = (ushort)hanum; | ||
4444 | NUMDATA(shp)->busnum = b; | ||
4445 | } | ||
4446 | } | ||
4447 | |||
4448 | spin_lock_init(&ha->smp_lock); | ||
4449 | gdth_enable_int(hanum); | ||
4450 | #endif /* !__ia64__ */ | ||
4451 | } | ||
4452 | } | ||
4453 | |||
4454 | /* scanning for EISA controllers */ | ||
4455 | for (eisa_slot=0x1000; eisa_slot<=0x8000; eisa_slot+=0x1000) { | ||
4456 | dma_addr_t scratch_dma_handle; | ||
4457 | scratch_dma_handle = 0; | ||
4458 | |||
4459 | if (gdth_ctr_count >= MAXHA) | ||
4460 | break; | ||
4461 | if (gdth_search_eisa(eisa_slot)) { /* controller found */ | ||
4462 | shp = scsi_register(shtp,sizeof(gdth_ext_str)); | ||
4463 | if (shp == NULL) | ||
4464 | continue; | ||
4465 | |||
4466 | ha = HADATA(shp); | ||
4467 | if (!gdth_init_eisa(eisa_slot,ha)) { | ||
4468 | scsi_unregister(shp); | ||
4469 | continue; | ||
4470 | } | ||
4471 | /* controller found and initialized */ | ||
4472 | printk("Configuring GDT-EISA HA at Slot %d IRQ %u\n", | ||
4473 | eisa_slot>>12,ha->irq); | ||
4474 | |||
4475 | if (request_irq(ha->irq,gdth_interrupt,IRQF_DISABLED,"gdth",ha)) { | ||
4476 | printk("GDT-EISA: Unable to allocate IRQ\n"); | ||
4477 | scsi_unregister(shp); | ||
4478 | continue; | ||
4479 | } | ||
4480 | shp->unchecked_isa_dma = 0; | ||
4481 | shp->irq = ha->irq; | ||
4482 | shp->dma_channel = 0xff; | ||
4483 | hanum = gdth_ctr_count; | ||
4484 | gdth_ctr_tab[gdth_ctr_count++] = shp; | ||
4485 | gdth_ctr_vtab[gdth_ctr_vcount++] = shp; | ||
4486 | |||
4487 | NUMDATA(shp)->hanum = (ushort)hanum; | ||
4488 | NUMDATA(shp)->busnum= 0; | ||
4489 | TRACE2(("EISA detect Bus 0: hanum %d\n", | ||
4490 | NUMDATA(shp)->hanum)); | ||
4491 | |||
4492 | ha->pccb = CMDDATA(shp); | ||
4493 | ha->ccb_phys = 0L; | ||
4494 | |||
4495 | ha->pdev = NULL; | ||
4496 | ha->pscratch = pci_alloc_consistent(ha->pdev, GDTH_SCRATCH, | ||
4497 | &scratch_dma_handle); | ||
4498 | ha->scratch_phys = scratch_dma_handle; | ||
4499 | ha->pmsg = pci_alloc_consistent(ha->pdev, sizeof(gdth_msg_str), | ||
4500 | &scratch_dma_handle); | ||
4501 | ha->msg_phys = scratch_dma_handle; | ||
4502 | #ifdef INT_COAL | ||
4503 | ha->coal_stat = (gdth_coal_status *) | ||
4504 | pci_alloc_consistent(ha->pdev, sizeof(gdth_coal_status) * | ||
4505 | MAXOFFSETS, &scratch_dma_handle); | ||
4506 | ha->coal_stat_phys = scratch_dma_handle; | ||
4507 | #endif | ||
4508 | ha->ccb_phys = | ||
4509 | pci_map_single(ha->pdev,ha->pccb, | ||
4510 | sizeof(gdth_cmd_str),PCI_DMA_BIDIRECTIONAL); | ||
4511 | ha->scratch_busy = FALSE; | ||
4512 | ha->req_first = NULL; | ||
4513 | ha->tid_cnt = MAX_HDRIVES; | ||
4514 | if (max_ids > 0 && max_ids < ha->tid_cnt) | ||
4515 | ha->tid_cnt = max_ids; | ||
4516 | for (i=0; i<GDTH_MAXCMDS; ++i) | ||
4517 | ha->cmd_tab[i].cmnd = UNUSED_CMND; | ||
4518 | ha->scan_mode = rescan ? 0x10 : 0; | ||
4519 | |||
4520 | if (ha->pscratch == NULL || ha->pmsg == NULL || | ||
4521 | !gdth_search_drives(hanum)) { | ||
4522 | printk("GDT-EISA: Error during device scan\n"); | ||
4523 | --gdth_ctr_count; | ||
4524 | --gdth_ctr_vcount; | ||
4525 | #ifdef INT_COAL | ||
4526 | if (ha->coal_stat) | ||
4527 | pci_free_consistent(ha->pdev, sizeof(gdth_coal_status) * | ||
4528 | MAXOFFSETS, ha->coal_stat, | ||
4529 | ha->coal_stat_phys); | ||
4530 | #endif | ||
4531 | if (ha->pscratch) | ||
4532 | pci_free_consistent(ha->pdev, GDTH_SCRATCH, | ||
4533 | ha->pscratch, ha->scratch_phys); | ||
4534 | if (ha->pmsg) | ||
4535 | pci_free_consistent(ha->pdev, sizeof(gdth_msg_str), | ||
4536 | ha->pmsg, ha->msg_phys); | ||
4537 | if (ha->ccb_phys) | ||
4538 | pci_unmap_single(ha->pdev,ha->ccb_phys, | ||
4539 | sizeof(gdth_cmd_str),PCI_DMA_BIDIRECTIONAL); | ||
4540 | free_irq(ha->irq,ha); | ||
4541 | scsi_unregister(shp); | ||
4542 | continue; | ||
4543 | } | ||
4544 | if (hdr_channel < 0 || hdr_channel > ha->bus_cnt) | ||
4545 | hdr_channel = ha->bus_cnt; | ||
4546 | ha->virt_bus = hdr_channel; | ||
4547 | |||
4548 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,20) && \ | ||
4549 | LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) | ||
4550 | shp->highmem_io = 0; | ||
4551 | #endif | ||
4552 | if (ha->cache_feat & ha->raw_feat & ha->screen_feat & GDT_64BIT) | ||
4553 | shp->max_cmd_len = 16; | ||
4554 | |||
4555 | shp->max_id = ha->tid_cnt; | ||
4556 | shp->max_lun = MAXLUN; | ||
4557 | shp->max_channel = virt_ctr ? 0 : ha->bus_cnt; | ||
4558 | if (virt_ctr) { | ||
4559 | virt_ctr = 1; | ||
4560 | /* register addit. SCSI channels as virtual controllers */ | ||
4561 | for (b = 1; b < ha->bus_cnt + 1; ++b) { | ||
4562 | shp = scsi_register(shtp,sizeof(gdth_num_str)); | ||
4563 | shp->unchecked_isa_dma = 0; | ||
4564 | shp->irq = ha->irq; | ||
4565 | shp->dma_channel = 0xff; | ||
4566 | gdth_ctr_vtab[gdth_ctr_vcount++] = shp; | ||
4567 | NUMDATA(shp)->hanum = (ushort)hanum; | ||
4568 | NUMDATA(shp)->busnum = b; | ||
4569 | } | ||
4570 | } | ||
4571 | |||
4572 | spin_lock_init(&ha->smp_lock); | ||
4573 | gdth_enable_int(hanum); | ||
4574 | } | ||
4575 | } | ||
4576 | } | ||
4577 | |||
4578 | /* scanning for PCI controllers */ | ||
4579 | cnt = gdth_search_pci(pcistr); | ||
4580 | printk("GDT-HA: Found %d PCI Storage RAID Controllers\n",cnt); | ||
4581 | gdth_sort_pci(pcistr,cnt); | ||
4582 | for (ctr = 0; ctr < cnt; ++ctr) { | ||
4583 | dma_addr_t scratch_dma_handle; | ||
4584 | scratch_dma_handle = 0; | ||
4585 | |||
4586 | if (gdth_ctr_count >= MAXHA) | ||
4587 | break; | ||
4588 | shp = scsi_register(shtp,sizeof(gdth_ext_str)); | ||
4589 | if (shp == NULL) | ||
4590 | continue; | ||
4591 | |||
4592 | ha = HADATA(shp); | ||
4593 | if (!gdth_init_pci(&pcistr[ctr],ha)) { | ||
4594 | scsi_unregister(shp); | ||
4595 | continue; | ||
4596 | } | ||
4597 | /* controller found and initialized */ | ||
4598 | printk("Configuring GDT-PCI HA at %d/%d IRQ %u\n", | ||
4599 | pcistr[ctr].pdev->bus->number, | ||
4600 | PCI_SLOT(pcistr[ctr].pdev->devfn), ha->irq); | ||
4601 | |||
4602 | if (request_irq(ha->irq, gdth_interrupt, | ||
4603 | IRQF_DISABLED|IRQF_SHARED, "gdth", ha)) | ||
4604 | { | ||
4605 | printk("GDT-PCI: Unable to allocate IRQ\n"); | ||
4606 | scsi_unregister(shp); | ||
4607 | continue; | ||
4608 | } | ||
4609 | shp->unchecked_isa_dma = 0; | ||
4610 | shp->irq = ha->irq; | ||
4611 | shp->dma_channel = 0xff; | ||
4612 | hanum = gdth_ctr_count; | ||
4613 | gdth_ctr_tab[gdth_ctr_count++] = shp; | ||
4614 | gdth_ctr_vtab[gdth_ctr_vcount++] = shp; | ||
4615 | |||
4616 | NUMDATA(shp)->hanum = (ushort)hanum; | ||
4617 | NUMDATA(shp)->busnum= 0; | ||
4618 | |||
4619 | ha->pccb = CMDDATA(shp); | ||
4620 | ha->ccb_phys = 0L; | ||
4621 | |||
4622 | ha->pscratch = pci_alloc_consistent(ha->pdev, GDTH_SCRATCH, | ||
4623 | &scratch_dma_handle); | ||
4624 | ha->scratch_phys = scratch_dma_handle; | ||
4625 | ha->pmsg = pci_alloc_consistent(ha->pdev, sizeof(gdth_msg_str), | ||
4626 | &scratch_dma_handle); | ||
4627 | ha->msg_phys = scratch_dma_handle; | ||
4628 | #ifdef INT_COAL | ||
4629 | ha->coal_stat = (gdth_coal_status *) | ||
4630 | pci_alloc_consistent(ha->pdev, sizeof(gdth_coal_status) * | ||
4631 | MAXOFFSETS, &scratch_dma_handle); | ||
4632 | ha->coal_stat_phys = scratch_dma_handle; | ||
4633 | #endif | ||
4634 | ha->scratch_busy = FALSE; | ||
4635 | ha->req_first = NULL; | ||
4636 | ha->tid_cnt = pcistr[ctr].pdev->device >= 0x200 ? MAXID : MAX_HDRIVES; | ||
4637 | if (max_ids > 0 && max_ids < ha->tid_cnt) | ||
4638 | ha->tid_cnt = max_ids; | ||
4639 | for (i=0; i<GDTH_MAXCMDS; ++i) | ||
4640 | ha->cmd_tab[i].cmnd = UNUSED_CMND; | ||
4641 | ha->scan_mode = rescan ? 0x10 : 0; | ||
4642 | |||
4643 | err = FALSE; | ||
4644 | if (ha->pscratch == NULL || ha->pmsg == NULL || | ||
4645 | !gdth_search_drives(hanum)) { | ||
4646 | err = TRUE; | ||
4647 | } else { | ||
4648 | if (hdr_channel < 0 || hdr_channel > ha->bus_cnt) | ||
4649 | hdr_channel = ha->bus_cnt; | ||
4650 | ha->virt_bus = hdr_channel; | ||
4651 | |||
4652 | |||
4653 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) | ||
4654 | scsi_set_pci_device(shp, pcistr[ctr].pdev); | ||
4655 | #endif | ||
4656 | if (!(ha->cache_feat & ha->raw_feat & ha->screen_feat &GDT_64BIT)|| | ||
4657 | /* 64-bit DMA only supported from FW >= x.43 */ | ||
4658 | (!ha->dma64_support)) { | ||
4659 | if (pci_set_dma_mask(pcistr[ctr].pdev, DMA_32BIT_MASK)) { | ||
4660 | printk(KERN_WARNING "GDT-PCI %d: Unable to set 32-bit DMA\n", hanum); | ||
4661 | err = TRUE; | ||
4662 | } | ||
4663 | } else { | ||
4664 | shp->max_cmd_len = 16; | ||
4665 | if (!pci_set_dma_mask(pcistr[ctr].pdev, DMA_64BIT_MASK)) { | ||
4666 | printk("GDT-PCI %d: 64-bit DMA enabled\n", hanum); | ||
4667 | } else if (pci_set_dma_mask(pcistr[ctr].pdev, DMA_32BIT_MASK)) { | ||
4668 | printk(KERN_WARNING "GDT-PCI %d: Unable to set 64/32-bit DMA\n", hanum); | ||
4669 | err = TRUE; | ||
4670 | } | ||
4671 | } | ||
4672 | } | ||
4673 | |||
4674 | if (err) { | ||
4675 | printk("GDT-PCI %d: Error during device scan\n", hanum); | ||
4676 | --gdth_ctr_count; | ||
4677 | --gdth_ctr_vcount; | ||
4678 | #ifdef INT_COAL | ||
4679 | if (ha->coal_stat) | ||
4680 | pci_free_consistent(ha->pdev, sizeof(gdth_coal_status) * | ||
4681 | MAXOFFSETS, ha->coal_stat, | ||
4682 | ha->coal_stat_phys); | ||
4683 | #endif | ||
4684 | if (ha->pscratch) | ||
4685 | pci_free_consistent(ha->pdev, GDTH_SCRATCH, | ||
4686 | ha->pscratch, ha->scratch_phys); | ||
4687 | if (ha->pmsg) | ||
4688 | pci_free_consistent(ha->pdev, sizeof(gdth_msg_str), | ||
4689 | ha->pmsg, ha->msg_phys); | ||
4690 | free_irq(ha->irq,ha); | ||
4691 | scsi_unregister(shp); | ||
4692 | continue; | ||
4693 | } | ||
4694 | |||
4695 | shp->max_id = ha->tid_cnt; | ||
4696 | shp->max_lun = MAXLUN; | ||
4697 | shp->max_channel = virt_ctr ? 0 : ha->bus_cnt; | ||
4698 | if (virt_ctr) { | ||
4699 | virt_ctr = 1; | ||
4700 | /* register addit. SCSI channels as virtual controllers */ | ||
4701 | for (b = 1; b < ha->bus_cnt + 1; ++b) { | ||
4702 | shp = scsi_register(shtp,sizeof(gdth_num_str)); | ||
4703 | shp->unchecked_isa_dma = 0; | ||
4704 | shp->irq = ha->irq; | ||
4705 | shp->dma_channel = 0xff; | ||
4706 | gdth_ctr_vtab[gdth_ctr_vcount++] = shp; | ||
4707 | NUMDATA(shp)->hanum = (ushort)hanum; | ||
4708 | NUMDATA(shp)->busnum = b; | ||
4709 | } | ||
4710 | } | ||
4711 | |||
4712 | spin_lock_init(&ha->smp_lock); | ||
4713 | gdth_enable_int(hanum); | ||
4714 | } | ||
4715 | |||
4716 | TRACE2(("gdth_detect() %d controller detected\n",gdth_ctr_count)); | ||
4717 | if (gdth_ctr_count > 0) { | ||
4718 | #ifdef GDTH_STATISTICS | ||
4719 | TRACE2(("gdth_detect(): Initializing timer !\n")); | ||
4720 | init_timer(&gdth_timer); | ||
4721 | gdth_timer.expires = jiffies + HZ; | ||
4722 | gdth_timer.data = 0L; | ||
4723 | gdth_timer.function = gdth_timeout; | ||
4724 | add_timer(&gdth_timer); | ||
4725 | #endif | ||
4726 | major = register_chrdev(0,"gdth",&gdth_fops); | ||
4727 | notifier_disabled = 0; | ||
4728 | register_reboot_notifier(&gdth_notifier); | ||
4729 | } | ||
4730 | gdth_polling = FALSE; | ||
4731 | return gdth_ctr_vcount; | ||
4732 | } | ||
4733 | |||
4734 | static int gdth_release(struct Scsi_Host *shp) | ||
4735 | { | 3906 | { |
4736 | int hanum; | ||
4737 | gdth_ha_str *ha; | ||
4738 | |||
4739 | TRACE2(("gdth_release()\n")); | ||
4740 | if (NUMDATA(shp)->busnum == 0) { | ||
4741 | hanum = NUMDATA(shp)->hanum; | ||
4742 | ha = HADATA(gdth_ctr_tab[hanum]); | ||
4743 | if (ha->sdev) { | ||
4744 | scsi_free_host_dev(ha->sdev); | ||
4745 | ha->sdev = NULL; | ||
4746 | } | ||
4747 | gdth_flush(hanum); | ||
4748 | |||
4749 | if (shp->irq) { | ||
4750 | free_irq(shp->irq,ha); | ||
4751 | } | ||
4752 | #ifndef __ia64__ | ||
4753 | if (shp->dma_channel != 0xff) { | ||
4754 | free_dma(shp->dma_channel); | ||
4755 | } | ||
4756 | #endif | ||
4757 | #ifdef INT_COAL | ||
4758 | if (ha->coal_stat) | ||
4759 | pci_free_consistent(ha->pdev, sizeof(gdth_coal_status) * | ||
4760 | MAXOFFSETS, ha->coal_stat, ha->coal_stat_phys); | ||
4761 | #endif | ||
4762 | if (ha->pscratch) | ||
4763 | pci_free_consistent(ha->pdev, GDTH_SCRATCH, | ||
4764 | ha->pscratch, ha->scratch_phys); | ||
4765 | if (ha->pmsg) | ||
4766 | pci_free_consistent(ha->pdev, sizeof(gdth_msg_str), | ||
4767 | ha->pmsg, ha->msg_phys); | ||
4768 | if (ha->ccb_phys) | ||
4769 | pci_unmap_single(ha->pdev,ha->ccb_phys, | ||
4770 | sizeof(gdth_cmd_str),PCI_DMA_BIDIRECTIONAL); | ||
4771 | gdth_ctr_released++; | ||
4772 | TRACE2(("gdth_release(): HA %d of %d\n", | ||
4773 | gdth_ctr_released, gdth_ctr_count)); | ||
4774 | |||
4775 | if (gdth_ctr_released == gdth_ctr_count) { | ||
4776 | #ifdef GDTH_STATISTICS | ||
4777 | del_timer(&gdth_timer); | ||
4778 | #endif | ||
4779 | unregister_chrdev(major,"gdth"); | ||
4780 | unregister_reboot_notifier(&gdth_notifier); | ||
4781 | } | ||
4782 | } | ||
4783 | |||
4784 | scsi_unregister(shp); | ||
4785 | return 0; | ||
4786 | } | ||
4787 | |||
4788 | |||
4789 | static const char *gdth_ctr_name(int hanum) | ||
4790 | { | ||
4791 | gdth_ha_str *ha; | ||
4792 | |||
4793 | TRACE2(("gdth_ctr_name()\n")); | 3907 | TRACE2(("gdth_ctr_name()\n")); |
4794 | 3908 | ||
4795 | ha = HADATA(gdth_ctr_tab[hanum]); | ||
4796 | |||
4797 | if (ha->type == GDT_EISA) { | 3909 | if (ha->type == GDT_EISA) { |
4798 | switch (ha->stype) { | 3910 | switch (ha->stype) { |
4799 | case GDT3_ID: | 3911 | case GDT3_ID: |
@@ -4820,29 +3932,23 @@ static const char *gdth_ctr_name(int hanum) | |||
4820 | 3932 | ||
4821 | static const char *gdth_info(struct Scsi_Host *shp) | 3933 | static const char *gdth_info(struct Scsi_Host *shp) |
4822 | { | 3934 | { |
4823 | int hanum; | 3935 | gdth_ha_str *ha = shost_priv(shp); |
4824 | gdth_ha_str *ha; | ||
4825 | 3936 | ||
4826 | TRACE2(("gdth_info()\n")); | 3937 | TRACE2(("gdth_info()\n")); |
4827 | hanum = NUMDATA(shp)->hanum; | ||
4828 | ha = HADATA(gdth_ctr_tab[hanum]); | ||
4829 | |||
4830 | return ((const char *)ha->binfo.type_string); | 3938 | return ((const char *)ha->binfo.type_string); |
4831 | } | 3939 | } |
4832 | 3940 | ||
4833 | static int gdth_eh_bus_reset(Scsi_Cmnd *scp) | 3941 | static int gdth_eh_bus_reset(Scsi_Cmnd *scp) |
4834 | { | 3942 | { |
4835 | int i, hanum; | 3943 | gdth_ha_str *ha = shost_priv(scp->device->host); |
4836 | gdth_ha_str *ha; | 3944 | int i; |
4837 | ulong flags; | 3945 | ulong flags; |
4838 | Scsi_Cmnd *cmnd; | 3946 | Scsi_Cmnd *cmnd; |
4839 | unchar b; | 3947 | unchar b; |
4840 | 3948 | ||
4841 | TRACE2(("gdth_eh_bus_reset()\n")); | 3949 | TRACE2(("gdth_eh_bus_reset()\n")); |
4842 | 3950 | ||
4843 | hanum = NUMDATA(scp->device->host)->hanum; | 3951 | b = scp->device->channel; |
4844 | b = virt_ctr ? NUMDATA(scp->device->host)->busnum : scp->device->channel; | ||
4845 | ha = HADATA(gdth_ctr_tab[hanum]); | ||
4846 | 3952 | ||
4847 | /* clear command tab */ | 3953 | /* clear command tab */ |
4848 | spin_lock_irqsave(&ha->smp_lock, flags); | 3954 | spin_lock_irqsave(&ha->smp_lock, flags); |
@@ -4859,9 +3965,9 @@ static int gdth_eh_bus_reset(Scsi_Cmnd *scp) | |||
4859 | if (ha->hdr[i].present) { | 3965 | if (ha->hdr[i].present) { |
4860 | spin_lock_irqsave(&ha->smp_lock, flags); | 3966 | spin_lock_irqsave(&ha->smp_lock, flags); |
4861 | gdth_polling = TRUE; | 3967 | gdth_polling = TRUE; |
4862 | while (gdth_test_busy(hanum)) | 3968 | while (gdth_test_busy(ha)) |
4863 | gdth_delay(0); | 3969 | gdth_delay(0); |
4864 | if (gdth_internal_cmd(hanum, CACHESERVICE, | 3970 | if (gdth_internal_cmd(ha, CACHESERVICE, |
4865 | GDT_CLUST_RESET, i, 0, 0)) | 3971 | GDT_CLUST_RESET, i, 0, 0)) |
4866 | ha->hdr[i].cluster_type &= ~CLUSTER_RESERVED; | 3972 | ha->hdr[i].cluster_type &= ~CLUSTER_RESERVED; |
4867 | gdth_polling = FALSE; | 3973 | gdth_polling = FALSE; |
@@ -4874,9 +3980,9 @@ static int gdth_eh_bus_reset(Scsi_Cmnd *scp) | |||
4874 | for (i = 0; i < MAXID; ++i) | 3980 | for (i = 0; i < MAXID; ++i) |
4875 | ha->raw[BUS_L2P(ha,b)].io_cnt[i] = 0; | 3981 | ha->raw[BUS_L2P(ha,b)].io_cnt[i] = 0; |
4876 | gdth_polling = TRUE; | 3982 | gdth_polling = TRUE; |
4877 | while (gdth_test_busy(hanum)) | 3983 | while (gdth_test_busy(ha)) |
4878 | gdth_delay(0); | 3984 | gdth_delay(0); |
4879 | gdth_internal_cmd(hanum, SCSIRAWSERVICE, GDT_RESET_BUS, | 3985 | gdth_internal_cmd(ha, SCSIRAWSERVICE, GDT_RESET_BUS, |
4880 | BUS_L2P(ha,b), 0, 0); | 3986 | BUS_L2P(ha,b), 0, 0); |
4881 | gdth_polling = FALSE; | 3987 | gdth_polling = FALSE; |
4882 | spin_unlock_irqrestore(&ha->smp_lock, flags); | 3988 | spin_unlock_irqrestore(&ha->smp_lock, flags); |
@@ -4884,30 +3990,18 @@ static int gdth_eh_bus_reset(Scsi_Cmnd *scp) | |||
4884 | return SUCCESS; | 3990 | return SUCCESS; |
4885 | } | 3991 | } |
4886 | 3992 | ||
4887 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) | ||
4888 | static int gdth_bios_param(struct scsi_device *sdev,struct block_device *bdev,sector_t cap,int *ip) | 3993 | static int gdth_bios_param(struct scsi_device *sdev,struct block_device *bdev,sector_t cap,int *ip) |
4889 | #else | ||
4890 | static int gdth_bios_param(Disk *disk,kdev_t dev,int *ip) | ||
4891 | #endif | ||
4892 | { | 3994 | { |
4893 | unchar b, t; | 3995 | unchar b, t; |
4894 | int hanum; | 3996 | gdth_ha_str *ha = shost_priv(sdev->host); |
4895 | gdth_ha_str *ha; | ||
4896 | struct scsi_device *sd; | 3997 | struct scsi_device *sd; |
4897 | unsigned capacity; | 3998 | unsigned capacity; |
4898 | 3999 | ||
4899 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) | ||
4900 | sd = sdev; | 4000 | sd = sdev; |
4901 | capacity = cap; | 4001 | capacity = cap; |
4902 | #else | 4002 | b = sd->channel; |
4903 | sd = disk->device; | ||
4904 | capacity = disk->capacity; | ||
4905 | #endif | ||
4906 | hanum = NUMDATA(sd->host)->hanum; | ||
4907 | b = virt_ctr ? NUMDATA(sd->host)->busnum : sd->channel; | ||
4908 | t = sd->id; | 4003 | t = sd->id; |
4909 | TRACE2(("gdth_bios_param() ha %d bus %d target %d\n", hanum, b, t)); | 4004 | TRACE2(("gdth_bios_param() ha %d bus %d target %d\n", ha->hanum, b, t)); |
4910 | ha = HADATA(gdth_ctr_tab[hanum]); | ||
4911 | 4005 | ||
4912 | if (b != ha->virt_bus || ha->hdr[t].heads == 0) { | 4006 | if (b != ha->virt_bus || ha->hdr[t].heads == 0) { |
4913 | /* raw device or host drive without mapping information */ | 4007 | /* raw device or host drive without mapping information */ |
@@ -4925,33 +4019,42 @@ static int gdth_bios_param(Disk *disk,kdev_t dev,int *ip) | |||
4925 | } | 4019 | } |
4926 | 4020 | ||
4927 | 4021 | ||
4928 | static int gdth_queuecommand(Scsi_Cmnd *scp,void (*done)(Scsi_Cmnd *)) | 4022 | static int gdth_queuecommand(struct scsi_cmnd *scp, |
4023 | void (*done)(struct scsi_cmnd *)) | ||
4929 | { | 4024 | { |
4930 | int hanum; | 4025 | gdth_ha_str *ha = shost_priv(scp->device->host); |
4931 | int priority; | 4026 | struct gdth_cmndinfo *cmndinfo; |
4932 | 4027 | ||
4933 | TRACE(("gdth_queuecommand() cmd 0x%x\n", scp->cmnd[0])); | 4028 | TRACE(("gdth_queuecommand() cmd 0x%x\n", scp->cmnd[0])); |
4934 | 4029 | ||
4935 | scp->scsi_done = (void *)done; | 4030 | cmndinfo = gdth_get_cmndinfo(ha); |
4936 | scp->SCp.have_data_in = 1; | 4031 | BUG_ON(!cmndinfo); |
4937 | scp->SCp.phase = -1; | 4032 | |
4938 | scp->SCp.sent_command = -1; | 4033 | scp->scsi_done = done; |
4939 | scp->SCp.Status = GDTH_MAP_NONE; | 4034 | gdth_update_timeout(scp, scp->timeout_per_command * 6); |
4940 | scp->SCp.buffer = (struct scatterlist *)NULL; | 4035 | cmndinfo->priority = DEFAULT_PRI; |
4941 | 4036 | ||
4942 | hanum = NUMDATA(scp->device->host)->hanum; | 4037 | gdth_set_bufflen(scp, scsi_bufflen(scp)); |
4038 | gdth_set_sg_count(scp, scsi_sg_count(scp)); | ||
4039 | gdth_set_sglist(scp, scsi_sglist(scp)); | ||
4040 | |||
4041 | return __gdth_queuecommand(ha, scp, cmndinfo); | ||
4042 | } | ||
4043 | |||
4044 | static int __gdth_queuecommand(gdth_ha_str *ha, struct scsi_cmnd *scp, | ||
4045 | struct gdth_cmndinfo *cmndinfo) | ||
4046 | { | ||
4047 | scp->host_scribble = (unsigned char *)cmndinfo; | ||
4048 | cmndinfo->wait_for_completion = 1; | ||
4049 | cmndinfo->phase = -1; | ||
4050 | cmndinfo->OpCode = -1; | ||
4051 | |||
4943 | #ifdef GDTH_STATISTICS | 4052 | #ifdef GDTH_STATISTICS |
4944 | ++act_ios; | 4053 | ++act_ios; |
4945 | #endif | 4054 | #endif |
4946 | 4055 | ||
4947 | priority = DEFAULT_PRI; | 4056 | gdth_putq(ha, scp, cmndinfo->priority); |
4948 | if (scp->done == gdth_scsi_done) | 4057 | gdth_next(ha); |
4949 | priority = scp->SCp.this_residual; | ||
4950 | else | ||
4951 | gdth_update_timeout(hanum, scp, scp->timeout_per_command * 6); | ||
4952 | |||
4953 | gdth_putq( hanum, scp, priority ); | ||
4954 | gdth_next( hanum ); | ||
4955 | return 0; | 4058 | return 0; |
4956 | } | 4059 | } |
4957 | 4060 | ||
@@ -4959,12 +4062,10 @@ static int gdth_queuecommand(Scsi_Cmnd *scp,void (*done)(Scsi_Cmnd *)) | |||
4959 | static int gdth_open(struct inode *inode, struct file *filep) | 4062 | static int gdth_open(struct inode *inode, struct file *filep) |
4960 | { | 4063 | { |
4961 | gdth_ha_str *ha; | 4064 | gdth_ha_str *ha; |
4962 | int i; | ||
4963 | 4065 | ||
4964 | for (i = 0; i < gdth_ctr_count; i++) { | 4066 | list_for_each_entry(ha, &gdth_instances, list) { |
4965 | ha = HADATA(gdth_ctr_tab[i]); | ||
4966 | if (!ha->sdev) | 4067 | if (!ha->sdev) |
4967 | ha->sdev = scsi_get_host_dev(gdth_ctr_tab[i]); | 4068 | ha->sdev = scsi_get_host_dev(ha->shost); |
4968 | } | 4069 | } |
4969 | 4070 | ||
4970 | TRACE(("gdth_open()\n")); | 4071 | TRACE(("gdth_open()\n")); |
@@ -4983,10 +4084,11 @@ static int ioc_event(void __user *arg) | |||
4983 | gdth_ha_str *ha; | 4084 | gdth_ha_str *ha; |
4984 | ulong flags; | 4085 | ulong flags; |
4985 | 4086 | ||
4986 | if (copy_from_user(&evt, arg, sizeof(gdth_ioctl_event)) || | 4087 | if (copy_from_user(&evt, arg, sizeof(gdth_ioctl_event))) |
4987 | evt.ionode >= gdth_ctr_count) | 4088 | return -EFAULT; |
4089 | ha = gdth_find_ha(evt.ionode); | ||
4090 | if (!ha) | ||
4988 | return -EFAULT; | 4091 | return -EFAULT; |
4989 | ha = HADATA(gdth_ctr_tab[evt.ionode]); | ||
4990 | 4092 | ||
4991 | if (evt.erase == 0xff) { | 4093 | if (evt.erase == 0xff) { |
4992 | if (evt.event.event_source == ES_TEST) | 4094 | if (evt.event.event_source == ES_TEST) |
@@ -5020,11 +4122,12 @@ static int ioc_lockdrv(void __user *arg) | |||
5020 | ulong flags; | 4122 | ulong flags; |
5021 | gdth_ha_str *ha; | 4123 | gdth_ha_str *ha; |
5022 | 4124 | ||
5023 | if (copy_from_user(&ldrv, arg, sizeof(gdth_ioctl_lockdrv)) || | 4125 | if (copy_from_user(&ldrv, arg, sizeof(gdth_ioctl_lockdrv))) |
5024 | ldrv.ionode >= gdth_ctr_count) | ||
5025 | return -EFAULT; | 4126 | return -EFAULT; |
5026 | ha = HADATA(gdth_ctr_tab[ldrv.ionode]); | 4127 | ha = gdth_find_ha(ldrv.ionode); |
5027 | 4128 | if (!ha) | |
4129 | return -EFAULT; | ||
4130 | |||
5028 | for (i = 0; i < ldrv.drive_cnt && i < MAX_HDRIVES; ++i) { | 4131 | for (i = 0; i < ldrv.drive_cnt && i < MAX_HDRIVES; ++i) { |
5029 | j = ldrv.drives[i]; | 4132 | j = ldrv.drives[i]; |
5030 | if (j >= MAX_HDRIVES || !ha->hdr[j].present) | 4133 | if (j >= MAX_HDRIVES || !ha->hdr[j].present) |
@@ -5033,14 +4136,14 @@ static int ioc_lockdrv(void __user *arg) | |||
5033 | spin_lock_irqsave(&ha->smp_lock, flags); | 4136 | spin_lock_irqsave(&ha->smp_lock, flags); |
5034 | ha->hdr[j].lock = 1; | 4137 | ha->hdr[j].lock = 1; |
5035 | spin_unlock_irqrestore(&ha->smp_lock, flags); | 4138 | spin_unlock_irqrestore(&ha->smp_lock, flags); |
5036 | gdth_wait_completion(ldrv.ionode, ha->bus_cnt, j); | 4139 | gdth_wait_completion(ha, ha->bus_cnt, j); |
5037 | gdth_stop_timeout(ldrv.ionode, ha->bus_cnt, j); | 4140 | gdth_stop_timeout(ha, ha->bus_cnt, j); |
5038 | } else { | 4141 | } else { |
5039 | spin_lock_irqsave(&ha->smp_lock, flags); | 4142 | spin_lock_irqsave(&ha->smp_lock, flags); |
5040 | ha->hdr[j].lock = 0; | 4143 | ha->hdr[j].lock = 0; |
5041 | spin_unlock_irqrestore(&ha->smp_lock, flags); | 4144 | spin_unlock_irqrestore(&ha->smp_lock, flags); |
5042 | gdth_start_timeout(ldrv.ionode, ha->bus_cnt, j); | 4145 | gdth_start_timeout(ha, ha->bus_cnt, j); |
5043 | gdth_next(ldrv.ionode); | 4146 | gdth_next(ha); |
5044 | } | 4147 | } |
5045 | } | 4148 | } |
5046 | return 0; | 4149 | return 0; |
@@ -5050,16 +4153,16 @@ static int ioc_resetdrv(void __user *arg, char *cmnd) | |||
5050 | { | 4153 | { |
5051 | gdth_ioctl_reset res; | 4154 | gdth_ioctl_reset res; |
5052 | gdth_cmd_str cmd; | 4155 | gdth_cmd_str cmd; |
5053 | int hanum; | ||
5054 | gdth_ha_str *ha; | 4156 | gdth_ha_str *ha; |
5055 | int rval; | 4157 | int rval; |
5056 | 4158 | ||
5057 | if (copy_from_user(&res, arg, sizeof(gdth_ioctl_reset)) || | 4159 | if (copy_from_user(&res, arg, sizeof(gdth_ioctl_reset)) || |
5058 | res.ionode >= gdth_ctr_count || res.number >= MAX_HDRIVES) | 4160 | res.number >= MAX_HDRIVES) |
5059 | return -EFAULT; | 4161 | return -EFAULT; |
5060 | hanum = res.ionode; | 4162 | ha = gdth_find_ha(res.ionode); |
5061 | ha = HADATA(gdth_ctr_tab[hanum]); | 4163 | if (!ha) |
5062 | 4164 | return -EFAULT; | |
4165 | |||
5063 | if (!ha->hdr[res.number].present) | 4166 | if (!ha->hdr[res.number].present) |
5064 | return 0; | 4167 | return 0; |
5065 | memset(&cmd, 0, sizeof(gdth_cmd_str)); | 4168 | memset(&cmd, 0, sizeof(gdth_cmd_str)); |
@@ -5085,22 +4188,21 @@ static int ioc_general(void __user *arg, char *cmnd) | |||
5085 | gdth_ioctl_general gen; | 4188 | gdth_ioctl_general gen; |
5086 | char *buf = NULL; | 4189 | char *buf = NULL; |
5087 | ulong64 paddr; | 4190 | ulong64 paddr; |
5088 | int hanum; | ||
5089 | gdth_ha_str *ha; | 4191 | gdth_ha_str *ha; |
5090 | int rval; | 4192 | int rval; |
5091 | 4193 | ||
5092 | if (copy_from_user(&gen, arg, sizeof(gdth_ioctl_general)) || | 4194 | if (copy_from_user(&gen, arg, sizeof(gdth_ioctl_general))) |
5093 | gen.ionode >= gdth_ctr_count) | 4195 | return -EFAULT; |
4196 | ha = gdth_find_ha(gen.ionode); | ||
4197 | if (!ha) | ||
5094 | return -EFAULT; | 4198 | return -EFAULT; |
5095 | hanum = gen.ionode; | ||
5096 | ha = HADATA(gdth_ctr_tab[hanum]); | ||
5097 | if (gen.data_len + gen.sense_len != 0) { | 4199 | if (gen.data_len + gen.sense_len != 0) { |
5098 | if (!(buf = gdth_ioctl_alloc(hanum, gen.data_len + gen.sense_len, | 4200 | if (!(buf = gdth_ioctl_alloc(ha, gen.data_len + gen.sense_len, |
5099 | FALSE, &paddr))) | 4201 | FALSE, &paddr))) |
5100 | return -EFAULT; | 4202 | return -EFAULT; |
5101 | if (copy_from_user(buf, arg + sizeof(gdth_ioctl_general), | 4203 | if (copy_from_user(buf, arg + sizeof(gdth_ioctl_general), |
5102 | gen.data_len + gen.sense_len)) { | 4204 | gen.data_len + gen.sense_len)) { |
5103 | gdth_ioctl_free(hanum, gen.data_len+gen.sense_len, buf, paddr); | 4205 | gdth_ioctl_free(ha, gen.data_len+gen.sense_len, buf, paddr); |
5104 | return -EFAULT; | 4206 | return -EFAULT; |
5105 | } | 4207 | } |
5106 | 4208 | ||
@@ -5174,7 +4276,7 @@ static int ioc_general(void __user *arg, char *cmnd) | |||
5174 | gen.command.u.raw.sense_data = (ulong32)paddr + gen.data_len; | 4276 | gen.command.u.raw.sense_data = (ulong32)paddr + gen.data_len; |
5175 | } | 4277 | } |
5176 | } else { | 4278 | } else { |
5177 | gdth_ioctl_free(hanum, gen.data_len+gen.sense_len, buf, paddr); | 4279 | gdth_ioctl_free(ha, gen.data_len+gen.sense_len, buf, paddr); |
5178 | return -EFAULT; | 4280 | return -EFAULT; |
5179 | } | 4281 | } |
5180 | } | 4282 | } |
@@ -5186,15 +4288,15 @@ static int ioc_general(void __user *arg, char *cmnd) | |||
5186 | 4288 | ||
5187 | if (copy_to_user(arg + sizeof(gdth_ioctl_general), buf, | 4289 | if (copy_to_user(arg + sizeof(gdth_ioctl_general), buf, |
5188 | gen.data_len + gen.sense_len)) { | 4290 | gen.data_len + gen.sense_len)) { |
5189 | gdth_ioctl_free(hanum, gen.data_len+gen.sense_len, buf, paddr); | 4291 | gdth_ioctl_free(ha, gen.data_len+gen.sense_len, buf, paddr); |
5190 | return -EFAULT; | 4292 | return -EFAULT; |
5191 | } | 4293 | } |
5192 | if (copy_to_user(arg, &gen, | 4294 | if (copy_to_user(arg, &gen, |
5193 | sizeof(gdth_ioctl_general) - sizeof(gdth_cmd_str))) { | 4295 | sizeof(gdth_ioctl_general) - sizeof(gdth_cmd_str))) { |
5194 | gdth_ioctl_free(hanum, gen.data_len+gen.sense_len, buf, paddr); | 4296 | gdth_ioctl_free(ha, gen.data_len+gen.sense_len, buf, paddr); |
5195 | return -EFAULT; | 4297 | return -EFAULT; |
5196 | } | 4298 | } |
5197 | gdth_ioctl_free(hanum, gen.data_len+gen.sense_len, buf, paddr); | 4299 | gdth_ioctl_free(ha, gen.data_len+gen.sense_len, buf, paddr); |
5198 | return 0; | 4300 | return 0; |
5199 | } | 4301 | } |
5200 | 4302 | ||
@@ -5204,7 +4306,7 @@ static int ioc_hdrlist(void __user *arg, char *cmnd) | |||
5204 | gdth_cmd_str *cmd; | 4306 | gdth_cmd_str *cmd; |
5205 | gdth_ha_str *ha; | 4307 | gdth_ha_str *ha; |
5206 | unchar i; | 4308 | unchar i; |
5207 | int hanum, rc = -ENOMEM; | 4309 | int rc = -ENOMEM; |
5208 | u32 cluster_type = 0; | 4310 | u32 cluster_type = 0; |
5209 | 4311 | ||
5210 | rsc = kmalloc(sizeof(*rsc), GFP_KERNEL); | 4312 | rsc = kmalloc(sizeof(*rsc), GFP_KERNEL); |
@@ -5213,12 +4315,10 @@ static int ioc_hdrlist(void __user *arg, char *cmnd) | |||
5213 | goto free_fail; | 4315 | goto free_fail; |
5214 | 4316 | ||
5215 | if (copy_from_user(rsc, arg, sizeof(gdth_ioctl_rescan)) || | 4317 | if (copy_from_user(rsc, arg, sizeof(gdth_ioctl_rescan)) || |
5216 | rsc->ionode >= gdth_ctr_count) { | 4318 | (NULL == (ha = gdth_find_ha(rsc->ionode)))) { |
5217 | rc = -EFAULT; | 4319 | rc = -EFAULT; |
5218 | goto free_fail; | 4320 | goto free_fail; |
5219 | } | 4321 | } |
5220 | hanum = rsc->ionode; | ||
5221 | ha = HADATA(gdth_ctr_tab[hanum]); | ||
5222 | memset(cmd, 0, sizeof(gdth_cmd_str)); | 4322 | memset(cmd, 0, sizeof(gdth_cmd_str)); |
5223 | 4323 | ||
5224 | for (i = 0; i < MAX_HDRIVES; ++i) { | 4324 | for (i = 0; i < MAX_HDRIVES; ++i) { |
@@ -5259,7 +4359,7 @@ static int ioc_rescan(void __user *arg, char *cmnd) | |||
5259 | gdth_cmd_str *cmd; | 4359 | gdth_cmd_str *cmd; |
5260 | ushort i, status, hdr_cnt; | 4360 | ushort i, status, hdr_cnt; |
5261 | ulong32 info; | 4361 | ulong32 info; |
5262 | int hanum, cyls, hds, secs; | 4362 | int cyls, hds, secs; |
5263 | int rc = -ENOMEM; | 4363 | int rc = -ENOMEM; |
5264 | ulong flags; | 4364 | ulong flags; |
5265 | gdth_ha_str *ha; | 4365 | gdth_ha_str *ha; |
@@ -5270,12 +4370,10 @@ static int ioc_rescan(void __user *arg, char *cmnd) | |||
5270 | goto free_fail; | 4370 | goto free_fail; |
5271 | 4371 | ||
5272 | if (copy_from_user(rsc, arg, sizeof(gdth_ioctl_rescan)) || | 4372 | if (copy_from_user(rsc, arg, sizeof(gdth_ioctl_rescan)) || |
5273 | rsc->ionode >= gdth_ctr_count) { | 4373 | (NULL == (ha = gdth_find_ha(rsc->ionode)))) { |
5274 | rc = -EFAULT; | 4374 | rc = -EFAULT; |
5275 | goto free_fail; | 4375 | goto free_fail; |
5276 | } | 4376 | } |
5277 | hanum = rsc->ionode; | ||
5278 | ha = HADATA(gdth_ctr_tab[hanum]); | ||
5279 | memset(cmd, 0, sizeof(gdth_cmd_str)); | 4377 | memset(cmd, 0, sizeof(gdth_cmd_str)); |
5280 | 4378 | ||
5281 | if (rsc->flag == 0) { | 4379 | if (rsc->flag == 0) { |
@@ -5432,9 +4530,9 @@ static int gdth_ioctl(struct inode *inode, struct file *filep, | |||
5432 | gdth_ioctl_ctrtype ctrt; | 4530 | gdth_ioctl_ctrtype ctrt; |
5433 | 4531 | ||
5434 | if (copy_from_user(&ctrt, argp, sizeof(gdth_ioctl_ctrtype)) || | 4532 | if (copy_from_user(&ctrt, argp, sizeof(gdth_ioctl_ctrtype)) || |
5435 | ctrt.ionode >= gdth_ctr_count) | 4533 | (NULL == (ha = gdth_find_ha(ctrt.ionode)))) |
5436 | return -EFAULT; | 4534 | return -EFAULT; |
5437 | ha = HADATA(gdth_ctr_tab[ctrt.ionode]); | 4535 | |
5438 | if (ha->type == GDT_ISA || ha->type == GDT_EISA) { | 4536 | if (ha->type == GDT_ISA || ha->type == GDT_EISA) { |
5439 | ctrt.type = (unchar)((ha->stype>>20) - 0x10); | 4537 | ctrt.type = (unchar)((ha->stype>>20) - 0x10); |
5440 | } else { | 4538 | } else { |
@@ -5473,10 +4571,9 @@ static int gdth_ioctl(struct inode *inode, struct file *filep, | |||
5473 | unchar i, j; | 4571 | unchar i, j; |
5474 | 4572 | ||
5475 | if (copy_from_user(&lchn, argp, sizeof(gdth_ioctl_lockchn)) || | 4573 | if (copy_from_user(&lchn, argp, sizeof(gdth_ioctl_lockchn)) || |
5476 | lchn.ionode >= gdth_ctr_count) | 4574 | (NULL == (ha = gdth_find_ha(lchn.ionode)))) |
5477 | return -EFAULT; | 4575 | return -EFAULT; |
5478 | ha = HADATA(gdth_ctr_tab[lchn.ionode]); | 4576 | |
5479 | |||
5480 | i = lchn.channel; | 4577 | i = lchn.channel; |
5481 | if (i < ha->bus_cnt) { | 4578 | if (i < ha->bus_cnt) { |
5482 | if (lchn.lock) { | 4579 | if (lchn.lock) { |
@@ -5484,16 +4581,16 @@ static int gdth_ioctl(struct inode *inode, struct file *filep, | |||
5484 | ha->raw[i].lock = 1; | 4581 | ha->raw[i].lock = 1; |
5485 | spin_unlock_irqrestore(&ha->smp_lock, flags); | 4582 | spin_unlock_irqrestore(&ha->smp_lock, flags); |
5486 | for (j = 0; j < ha->tid_cnt; ++j) { | 4583 | for (j = 0; j < ha->tid_cnt; ++j) { |
5487 | gdth_wait_completion(lchn.ionode, i, j); | 4584 | gdth_wait_completion(ha, i, j); |
5488 | gdth_stop_timeout(lchn.ionode, i, j); | 4585 | gdth_stop_timeout(ha, i, j); |
5489 | } | 4586 | } |
5490 | } else { | 4587 | } else { |
5491 | spin_lock_irqsave(&ha->smp_lock, flags); | 4588 | spin_lock_irqsave(&ha->smp_lock, flags); |
5492 | ha->raw[i].lock = 0; | 4589 | ha->raw[i].lock = 0; |
5493 | spin_unlock_irqrestore(&ha->smp_lock, flags); | 4590 | spin_unlock_irqrestore(&ha->smp_lock, flags); |
5494 | for (j = 0; j < ha->tid_cnt; ++j) { | 4591 | for (j = 0; j < ha->tid_cnt; ++j) { |
5495 | gdth_start_timeout(lchn.ionode, i, j); | 4592 | gdth_start_timeout(ha, i, j); |
5496 | gdth_next(lchn.ionode); | 4593 | gdth_next(ha); |
5497 | } | 4594 | } |
5498 | } | 4595 | } |
5499 | } | 4596 | } |
@@ -5509,37 +4606,22 @@ static int gdth_ioctl(struct inode *inode, struct file *filep, | |||
5509 | case GDTIOCTL_RESET_BUS: | 4606 | case GDTIOCTL_RESET_BUS: |
5510 | { | 4607 | { |
5511 | gdth_ioctl_reset res; | 4608 | gdth_ioctl_reset res; |
5512 | int hanum, rval; | 4609 | int rval; |
5513 | 4610 | ||
5514 | if (copy_from_user(&res, argp, sizeof(gdth_ioctl_reset)) || | 4611 | if (copy_from_user(&res, argp, sizeof(gdth_ioctl_reset)) || |
5515 | res.ionode >= gdth_ctr_count) | 4612 | (NULL == (ha = gdth_find_ha(res.ionode)))) |
5516 | return -EFAULT; | 4613 | return -EFAULT; |
5517 | hanum = res.ionode; | ||
5518 | ha = HADATA(gdth_ctr_tab[hanum]); | ||
5519 | 4614 | ||
5520 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) | 4615 | scp = kzalloc(sizeof(*scp), GFP_KERNEL); |
5521 | scp = kmalloc(sizeof(*scp), GFP_KERNEL); | ||
5522 | if (!scp) | 4616 | if (!scp) |
5523 | return -ENOMEM; | 4617 | return -ENOMEM; |
5524 | memset(scp, 0, sizeof(*scp)); | ||
5525 | scp->device = ha->sdev; | 4618 | scp->device = ha->sdev; |
5526 | scp->cmd_len = 12; | 4619 | scp->cmd_len = 12; |
5527 | scp->use_sg = 0; | 4620 | scp->device->channel = res.number; |
5528 | scp->device->channel = virt_ctr ? 0 : res.number; | ||
5529 | rval = gdth_eh_bus_reset(scp); | 4621 | rval = gdth_eh_bus_reset(scp); |
5530 | res.status = (rval == SUCCESS ? S_OK : S_GENERR); | 4622 | res.status = (rval == SUCCESS ? S_OK : S_GENERR); |
5531 | kfree(scp); | 4623 | kfree(scp); |
5532 | #else | 4624 | |
5533 | scp = scsi_allocate_device(ha->sdev, 1, FALSE); | ||
5534 | if (!scp) | ||
5535 | return -ENOMEM; | ||
5536 | scp->cmd_len = 12; | ||
5537 | scp->use_sg = 0; | ||
5538 | scp->channel = virt_ctr ? 0 : res.number; | ||
5539 | rval = gdth_eh_bus_reset(scp); | ||
5540 | res.status = (rval == SUCCESS ? S_OK : S_GENERR); | ||
5541 | scsi_release_command(scp); | ||
5542 | #endif | ||
5543 | if (copy_to_user(argp, &res, sizeof(gdth_ioctl_reset))) | 4625 | if (copy_to_user(argp, &res, sizeof(gdth_ioctl_reset))) |
5544 | return -EFAULT; | 4626 | return -EFAULT; |
5545 | break; | 4627 | break; |
@@ -5556,16 +4638,14 @@ static int gdth_ioctl(struct inode *inode, struct file *filep, | |||
5556 | 4638 | ||
5557 | 4639 | ||
5558 | /* flush routine */ | 4640 | /* flush routine */ |
5559 | static void gdth_flush(int hanum) | 4641 | static void gdth_flush(gdth_ha_str *ha) |
5560 | { | 4642 | { |
5561 | int i; | 4643 | int i; |
5562 | gdth_ha_str *ha; | ||
5563 | gdth_cmd_str gdtcmd; | 4644 | gdth_cmd_str gdtcmd; |
5564 | char cmnd[MAX_COMMAND_SIZE]; | 4645 | char cmnd[MAX_COMMAND_SIZE]; |
5565 | memset(cmnd, 0xff, MAX_COMMAND_SIZE); | 4646 | memset(cmnd, 0xff, MAX_COMMAND_SIZE); |
5566 | 4647 | ||
5567 | TRACE2(("gdth_flush() hanum %d\n",hanum)); | 4648 | TRACE2(("gdth_flush() hanum %d\n", ha->hanum)); |
5568 | ha = HADATA(gdth_ctr_tab[hanum]); | ||
5569 | 4649 | ||
5570 | for (i = 0; i < MAX_HDRIVES; ++i) { | 4650 | for (i = 0; i < MAX_HDRIVES; ++i) { |
5571 | if (ha->hdr[i].present) { | 4651 | if (ha->hdr[i].present) { |
@@ -5581,9 +4661,9 @@ static void gdth_flush(int hanum) | |||
5581 | gdtcmd.u.cache.BlockNo = 1; | 4661 | gdtcmd.u.cache.BlockNo = 1; |
5582 | gdtcmd.u.cache.sg_canz = 0; | 4662 | gdtcmd.u.cache.sg_canz = 0; |
5583 | } | 4663 | } |
5584 | TRACE2(("gdth_flush(): flush ha %d drive %d\n", hanum, i)); | 4664 | TRACE2(("gdth_flush(): flush ha %d drive %d\n", ha->hanum, i)); |
5585 | 4665 | ||
5586 | gdth_execute(gdth_ctr_tab[hanum], &gdtcmd, cmnd, 30, NULL); | 4666 | gdth_execute(ha->shost, &gdtcmd, cmnd, 30, NULL); |
5587 | } | 4667 | } |
5588 | } | 4668 | } |
5589 | } | 4669 | } |
@@ -5591,7 +4671,7 @@ static void gdth_flush(int hanum) | |||
5591 | /* shutdown routine */ | 4671 | /* shutdown routine */ |
5592 | static int gdth_halt(struct notifier_block *nb, ulong event, void *buf) | 4672 | static int gdth_halt(struct notifier_block *nb, ulong event, void *buf) |
5593 | { | 4673 | { |
5594 | int hanum; | 4674 | gdth_ha_str *ha; |
5595 | #ifndef __alpha__ | 4675 | #ifndef __alpha__ |
5596 | gdth_cmd_str gdtcmd; | 4676 | gdth_cmd_str gdtcmd; |
5597 | char cmnd[MAX_COMMAND_SIZE]; | 4677 | char cmnd[MAX_COMMAND_SIZE]; |
@@ -5606,8 +4686,8 @@ static int gdth_halt(struct notifier_block *nb, ulong event, void *buf) | |||
5606 | 4686 | ||
5607 | notifier_disabled = 1; | 4687 | notifier_disabled = 1; |
5608 | printk("GDT-HA: Flushing all host drives .. "); | 4688 | printk("GDT-HA: Flushing all host drives .. "); |
5609 | for (hanum = 0; hanum < gdth_ctr_count; ++hanum) { | 4689 | list_for_each_entry(ha, &gdth_instances, list) { |
5610 | gdth_flush(hanum); | 4690 | gdth_flush(ha); |
5611 | 4691 | ||
5612 | #ifndef __alpha__ | 4692 | #ifndef __alpha__ |
5613 | /* controller reset */ | 4693 | /* controller reset */ |
@@ -5615,8 +4695,8 @@ static int gdth_halt(struct notifier_block *nb, ulong event, void *buf) | |||
5615 | gdtcmd.BoardNode = LOCALBOARD; | 4695 | gdtcmd.BoardNode = LOCALBOARD; |
5616 | gdtcmd.Service = CACHESERVICE; | 4696 | gdtcmd.Service = CACHESERVICE; |
5617 | gdtcmd.OpCode = GDT_RESET; | 4697 | gdtcmd.OpCode = GDT_RESET; |
5618 | TRACE2(("gdth_halt(): reset controller %d\n", hanum)); | 4698 | TRACE2(("gdth_halt(): reset controller %d\n", ha->hanum)); |
5619 | gdth_execute(gdth_ctr_tab[hanum], &gdtcmd, cmnd, 10, NULL); | 4699 | gdth_execute(ha->shost, &gdtcmd, cmnd, 10, NULL); |
5620 | #endif | 4700 | #endif |
5621 | } | 4701 | } |
5622 | printk("Done.\n"); | 4702 | printk("Done.\n"); |
@@ -5627,7 +4707,6 @@ static int gdth_halt(struct notifier_block *nb, ulong event, void *buf) | |||
5627 | return NOTIFY_OK; | 4707 | return NOTIFY_OK; |
5628 | } | 4708 | } |
5629 | 4709 | ||
5630 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) | ||
5631 | /* configure lun */ | 4710 | /* configure lun */ |
5632 | static int gdth_slave_configure(struct scsi_device *sdev) | 4711 | static int gdth_slave_configure(struct scsi_device *sdev) |
5633 | { | 4712 | { |
@@ -5636,40 +4715,536 @@ static int gdth_slave_configure(struct scsi_device *sdev) | |||
5636 | sdev->skip_ms_page_8 = 1; | 4715 | sdev->skip_ms_page_8 = 1; |
5637 | return 0; | 4716 | return 0; |
5638 | } | 4717 | } |
5639 | #endif | ||
5640 | 4718 | ||
5641 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) | 4719 | static struct scsi_host_template gdth_template = { |
5642 | static struct scsi_host_template driver_template = { | ||
5643 | #else | ||
5644 | static Scsi_Host_Template driver_template = { | ||
5645 | #endif | ||
5646 | .proc_name = "gdth", | ||
5647 | .proc_info = gdth_proc_info, | ||
5648 | .name = "GDT SCSI Disk Array Controller", | 4720 | .name = "GDT SCSI Disk Array Controller", |
5649 | .detect = gdth_detect, | ||
5650 | .release = gdth_release, | ||
5651 | .info = gdth_info, | 4721 | .info = gdth_info, |
5652 | .queuecommand = gdth_queuecommand, | 4722 | .queuecommand = gdth_queuecommand, |
5653 | .eh_bus_reset_handler = gdth_eh_bus_reset, | 4723 | .eh_bus_reset_handler = gdth_eh_bus_reset, |
4724 | .slave_configure = gdth_slave_configure, | ||
5654 | .bios_param = gdth_bios_param, | 4725 | .bios_param = gdth_bios_param, |
4726 | .proc_info = gdth_proc_info, | ||
4727 | .proc_name = "gdth", | ||
5655 | .can_queue = GDTH_MAXCMDS, | 4728 | .can_queue = GDTH_MAXCMDS, |
5656 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) | ||
5657 | .slave_configure = gdth_slave_configure, | ||
5658 | #endif | ||
5659 | .this_id = -1, | 4729 | .this_id = -1, |
5660 | .sg_tablesize = GDTH_MAXSG, | 4730 | .sg_tablesize = GDTH_MAXSG, |
5661 | .cmd_per_lun = GDTH_MAXC_P_L, | 4731 | .cmd_per_lun = GDTH_MAXC_P_L, |
5662 | .unchecked_isa_dma = 1, | 4732 | .unchecked_isa_dma = 1, |
5663 | .use_clustering = ENABLE_CLUSTERING, | 4733 | .use_clustering = ENABLE_CLUSTERING, |
5664 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) | 4734 | }; |
5665 | .use_new_eh_code = 1, | 4735 | |
5666 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,20) | 4736 | #ifdef CONFIG_ISA |
5667 | .highmem_io = 1, | 4737 | static int gdth_isa_probe_one(ulong32 isa_bios) |
4738 | { | ||
4739 | struct Scsi_Host *shp; | ||
4740 | gdth_ha_str *ha; | ||
4741 | dma_addr_t scratch_dma_handle = 0; | ||
4742 | int error, i; | ||
4743 | |||
4744 | if (!gdth_search_isa(isa_bios)) | ||
4745 | return -ENXIO; | ||
4746 | |||
4747 | shp = scsi_host_alloc(&gdth_template, sizeof(gdth_ha_str)); | ||
4748 | if (!shp) | ||
4749 | return -ENOMEM; | ||
4750 | ha = shost_priv(shp); | ||
4751 | |||
4752 | error = -ENODEV; | ||
4753 | if (!gdth_init_isa(isa_bios,ha)) | ||
4754 | goto out_host_put; | ||
4755 | |||
4756 | /* controller found and initialized */ | ||
4757 | printk("Configuring GDT-ISA HA at BIOS 0x%05X IRQ %u DRQ %u\n", | ||
4758 | isa_bios, ha->irq, ha->drq); | ||
4759 | |||
4760 | error = request_irq(ha->irq, gdth_interrupt, IRQF_DISABLED, "gdth", ha); | ||
4761 | if (error) { | ||
4762 | printk("GDT-ISA: Unable to allocate IRQ\n"); | ||
4763 | goto out_host_put; | ||
4764 | } | ||
4765 | |||
4766 | error = request_dma(ha->drq, "gdth"); | ||
4767 | if (error) { | ||
4768 | printk("GDT-ISA: Unable to allocate DMA channel\n"); | ||
4769 | goto out_free_irq; | ||
4770 | } | ||
4771 | |||
4772 | set_dma_mode(ha->drq,DMA_MODE_CASCADE); | ||
4773 | enable_dma(ha->drq); | ||
4774 | shp->unchecked_isa_dma = 1; | ||
4775 | shp->irq = ha->irq; | ||
4776 | shp->dma_channel = ha->drq; | ||
4777 | |||
4778 | ha->hanum = gdth_ctr_count++; | ||
4779 | ha->shost = shp; | ||
4780 | |||
4781 | ha->pccb = &ha->cmdext; | ||
4782 | ha->ccb_phys = 0L; | ||
4783 | ha->pdev = NULL; | ||
4784 | |||
4785 | error = -ENOMEM; | ||
4786 | |||
4787 | ha->pscratch = pci_alloc_consistent(ha->pdev, GDTH_SCRATCH, | ||
4788 | &scratch_dma_handle); | ||
4789 | if (!ha->pscratch) | ||
4790 | goto out_dec_counters; | ||
4791 | ha->scratch_phys = scratch_dma_handle; | ||
4792 | |||
4793 | ha->pmsg = pci_alloc_consistent(ha->pdev, sizeof(gdth_msg_str), | ||
4794 | &scratch_dma_handle); | ||
4795 | if (!ha->pmsg) | ||
4796 | goto out_free_pscratch; | ||
4797 | ha->msg_phys = scratch_dma_handle; | ||
4798 | |||
4799 | #ifdef INT_COAL | ||
4800 | ha->coal_stat = pci_alloc_consistent(ha->pdev, | ||
4801 | sizeof(gdth_coal_status) * MAXOFFSETS, | ||
4802 | &scratch_dma_handle); | ||
4803 | if (!ha->coal_stat) | ||
4804 | goto out_free_pmsg; | ||
4805 | ha->coal_stat_phys = scratch_dma_handle; | ||
4806 | #endif | ||
4807 | |||
4808 | ha->scratch_busy = FALSE; | ||
4809 | ha->req_first = NULL; | ||
4810 | ha->tid_cnt = MAX_HDRIVES; | ||
4811 | if (max_ids > 0 && max_ids < ha->tid_cnt) | ||
4812 | ha->tid_cnt = max_ids; | ||
4813 | for (i = 0; i < GDTH_MAXCMDS; ++i) | ||
4814 | ha->cmd_tab[i].cmnd = UNUSED_CMND; | ||
4815 | ha->scan_mode = rescan ? 0x10 : 0; | ||
4816 | |||
4817 | error = -ENODEV; | ||
4818 | if (!gdth_search_drives(ha)) { | ||
4819 | printk("GDT-ISA: Error during device scan\n"); | ||
4820 | goto out_free_coal_stat; | ||
4821 | } | ||
4822 | |||
4823 | if (hdr_channel < 0 || hdr_channel > ha->bus_cnt) | ||
4824 | hdr_channel = ha->bus_cnt; | ||
4825 | ha->virt_bus = hdr_channel; | ||
4826 | |||
4827 | if (ha->cache_feat & ha->raw_feat & ha->screen_feat & GDT_64BIT) | ||
4828 | shp->max_cmd_len = 16; | ||
4829 | |||
4830 | shp->max_id = ha->tid_cnt; | ||
4831 | shp->max_lun = MAXLUN; | ||
4832 | shp->max_channel = ha->bus_cnt; | ||
4833 | |||
4834 | spin_lock_init(&ha->smp_lock); | ||
4835 | gdth_enable_int(ha); | ||
4836 | |||
4837 | error = scsi_add_host(shp, NULL); | ||
4838 | if (error) | ||
4839 | goto out_free_coal_stat; | ||
4840 | list_add_tail(&ha->list, &gdth_instances); | ||
4841 | return 0; | ||
4842 | |||
4843 | out_free_coal_stat: | ||
4844 | #ifdef INT_COAL | ||
4845 | pci_free_consistent(ha->pdev, sizeof(gdth_coal_status) * MAXOFFSETS, | ||
4846 | ha->coal_stat, ha->coal_stat_phys); | ||
4847 | out_free_pmsg: | ||
4848 | #endif | ||
4849 | pci_free_consistent(ha->pdev, sizeof(gdth_msg_str), | ||
4850 | ha->pmsg, ha->msg_phys); | ||
4851 | out_free_pscratch: | ||
4852 | pci_free_consistent(ha->pdev, GDTH_SCRATCH, | ||
4853 | ha->pscratch, ha->scratch_phys); | ||
4854 | out_dec_counters: | ||
4855 | gdth_ctr_count--; | ||
4856 | out_free_irq: | ||
4857 | free_irq(ha->irq, ha); | ||
4858 | out_host_put: | ||
4859 | scsi_host_put(shp); | ||
4860 | return error; | ||
4861 | } | ||
4862 | #endif /* CONFIG_ISA */ | ||
4863 | |||
4864 | #ifdef CONFIG_EISA | ||
4865 | static int gdth_eisa_probe_one(ushort eisa_slot) | ||
4866 | { | ||
4867 | struct Scsi_Host *shp; | ||
4868 | gdth_ha_str *ha; | ||
4869 | dma_addr_t scratch_dma_handle = 0; | ||
4870 | int error, i; | ||
4871 | |||
4872 | if (!gdth_search_eisa(eisa_slot)) | ||
4873 | return -ENXIO; | ||
4874 | |||
4875 | shp = scsi_host_alloc(&gdth_template, sizeof(gdth_ha_str)); | ||
4876 | if (!shp) | ||
4877 | return -ENOMEM; | ||
4878 | ha = shost_priv(shp); | ||
4879 | |||
4880 | error = -ENODEV; | ||
4881 | if (!gdth_init_eisa(eisa_slot,ha)) | ||
4882 | goto out_host_put; | ||
4883 | |||
4884 | /* controller found and initialized */ | ||
4885 | printk("Configuring GDT-EISA HA at Slot %d IRQ %u\n", | ||
4886 | eisa_slot >> 12, ha->irq); | ||
4887 | |||
4888 | error = request_irq(ha->irq, gdth_interrupt, IRQF_DISABLED, "gdth", ha); | ||
4889 | if (error) { | ||
4890 | printk("GDT-EISA: Unable to allocate IRQ\n"); | ||
4891 | goto out_host_put; | ||
4892 | } | ||
4893 | |||
4894 | shp->unchecked_isa_dma = 0; | ||
4895 | shp->irq = ha->irq; | ||
4896 | shp->dma_channel = 0xff; | ||
4897 | |||
4898 | ha->hanum = gdth_ctr_count++; | ||
4899 | ha->shost = shp; | ||
4900 | |||
4901 | TRACE2(("EISA detect Bus 0: hanum %d\n", ha->hanum)); | ||
4902 | |||
4903 | ha->pccb = &ha->cmdext; | ||
4904 | ha->ccb_phys = 0L; | ||
4905 | |||
4906 | error = -ENOMEM; | ||
4907 | |||
4908 | ha->pdev = NULL; | ||
4909 | ha->pscratch = pci_alloc_consistent(ha->pdev, GDTH_SCRATCH, | ||
4910 | &scratch_dma_handle); | ||
4911 | if (!ha->pscratch) | ||
4912 | goto out_free_irq; | ||
4913 | ha->scratch_phys = scratch_dma_handle; | ||
4914 | |||
4915 | ha->pmsg = pci_alloc_consistent(ha->pdev, sizeof(gdth_msg_str), | ||
4916 | &scratch_dma_handle); | ||
4917 | if (!ha->pmsg) | ||
4918 | goto out_free_pscratch; | ||
4919 | ha->msg_phys = scratch_dma_handle; | ||
4920 | |||
4921 | #ifdef INT_COAL | ||
4922 | ha->coal_stat = pci_alloc_consistent(ha->pdev, | ||
4923 | sizeof(gdth_coal_status) * MAXOFFSETS, | ||
4924 | &scratch_dma_handle); | ||
4925 | if (!ha->coal_stat) | ||
4926 | goto out_free_pmsg; | ||
4927 | ha->coal_stat_phys = scratch_dma_handle; | ||
5668 | #endif | 4928 | #endif |
4929 | |||
4930 | ha->ccb_phys = pci_map_single(ha->pdev,ha->pccb, | ||
4931 | sizeof(gdth_cmd_str), PCI_DMA_BIDIRECTIONAL); | ||
4932 | if (!ha->ccb_phys) | ||
4933 | goto out_free_coal_stat; | ||
4934 | |||
4935 | ha->scratch_busy = FALSE; | ||
4936 | ha->req_first = NULL; | ||
4937 | ha->tid_cnt = MAX_HDRIVES; | ||
4938 | if (max_ids > 0 && max_ids < ha->tid_cnt) | ||
4939 | ha->tid_cnt = max_ids; | ||
4940 | for (i = 0; i < GDTH_MAXCMDS; ++i) | ||
4941 | ha->cmd_tab[i].cmnd = UNUSED_CMND; | ||
4942 | ha->scan_mode = rescan ? 0x10 : 0; | ||
4943 | |||
4944 | if (!gdth_search_drives(ha)) { | ||
4945 | printk("GDT-EISA: Error during device scan\n"); | ||
4946 | error = -ENODEV; | ||
4947 | goto out_free_ccb_phys; | ||
4948 | } | ||
4949 | |||
4950 | if (hdr_channel < 0 || hdr_channel > ha->bus_cnt) | ||
4951 | hdr_channel = ha->bus_cnt; | ||
4952 | ha->virt_bus = hdr_channel; | ||
4953 | |||
4954 | if (ha->cache_feat & ha->raw_feat & ha->screen_feat & GDT_64BIT) | ||
4955 | shp->max_cmd_len = 16; | ||
4956 | |||
4957 | shp->max_id = ha->tid_cnt; | ||
4958 | shp->max_lun = MAXLUN; | ||
4959 | shp->max_channel = ha->bus_cnt; | ||
4960 | |||
4961 | spin_lock_init(&ha->smp_lock); | ||
4962 | gdth_enable_int(ha); | ||
4963 | |||
4964 | error = scsi_add_host(shp, NULL); | ||
4965 | if (error) | ||
4966 | goto out_free_coal_stat; | ||
4967 | list_add_tail(&ha->list, &gdth_instances); | ||
4968 | return 0; | ||
4969 | |||
4970 | out_free_ccb_phys: | ||
4971 | pci_unmap_single(ha->pdev,ha->ccb_phys, sizeof(gdth_cmd_str), | ||
4972 | PCI_DMA_BIDIRECTIONAL); | ||
4973 | out_free_coal_stat: | ||
4974 | #ifdef INT_COAL | ||
4975 | pci_free_consistent(ha->pdev, sizeof(gdth_coal_status) * MAXOFFSETS, | ||
4976 | ha->coal_stat, ha->coal_stat_phys); | ||
4977 | out_free_pmsg: | ||
5669 | #endif | 4978 | #endif |
5670 | }; | 4979 | pci_free_consistent(ha->pdev, sizeof(gdth_msg_str), |
4980 | ha->pmsg, ha->msg_phys); | ||
4981 | out_free_pscratch: | ||
4982 | pci_free_consistent(ha->pdev, GDTH_SCRATCH, | ||
4983 | ha->pscratch, ha->scratch_phys); | ||
4984 | out_free_irq: | ||
4985 | free_irq(ha->irq, ha); | ||
4986 | gdth_ctr_count--; | ||
4987 | out_host_put: | ||
4988 | scsi_host_put(shp); | ||
4989 | return error; | ||
4990 | } | ||
4991 | #endif /* CONFIG_EISA */ | ||
4992 | |||
4993 | #ifdef CONFIG_PCI | ||
4994 | static int gdth_pci_probe_one(gdth_pci_str *pcistr, int ctr) | ||
4995 | { | ||
4996 | struct Scsi_Host *shp; | ||
4997 | gdth_ha_str *ha; | ||
4998 | dma_addr_t scratch_dma_handle = 0; | ||
4999 | int error, i; | ||
5000 | |||
5001 | shp = scsi_host_alloc(&gdth_template, sizeof(gdth_ha_str)); | ||
5002 | if (!shp) | ||
5003 | return -ENOMEM; | ||
5004 | ha = shost_priv(shp); | ||
5005 | |||
5006 | error = -ENODEV; | ||
5007 | if (!gdth_init_pci(&pcistr[ctr],ha)) | ||
5008 | goto out_host_put; | ||
5009 | |||
5010 | /* controller found and initialized */ | ||
5011 | printk("Configuring GDT-PCI HA at %d/%d IRQ %u\n", | ||
5012 | pcistr[ctr].pdev->bus->number, | ||
5013 | PCI_SLOT(pcistr[ctr].pdev->devfn), | ||
5014 | ha->irq); | ||
5015 | |||
5016 | error = request_irq(ha->irq, gdth_interrupt, | ||
5017 | IRQF_DISABLED|IRQF_SHARED, "gdth", ha); | ||
5018 | if (error) { | ||
5019 | printk("GDT-PCI: Unable to allocate IRQ\n"); | ||
5020 | goto out_host_put; | ||
5021 | } | ||
5022 | |||
5023 | shp->unchecked_isa_dma = 0; | ||
5024 | shp->irq = ha->irq; | ||
5025 | shp->dma_channel = 0xff; | ||
5026 | |||
5027 | ha->hanum = gdth_ctr_count++; | ||
5028 | ha->shost = shp; | ||
5029 | |||
5030 | ha->pccb = &ha->cmdext; | ||
5031 | ha->ccb_phys = 0L; | ||
5032 | |||
5033 | error = -ENOMEM; | ||
5034 | |||
5035 | ha->pscratch = pci_alloc_consistent(ha->pdev, GDTH_SCRATCH, | ||
5036 | &scratch_dma_handle); | ||
5037 | if (!ha->pscratch) | ||
5038 | goto out_free_irq; | ||
5039 | ha->scratch_phys = scratch_dma_handle; | ||
5040 | |||
5041 | ha->pmsg = pci_alloc_consistent(ha->pdev, sizeof(gdth_msg_str), | ||
5042 | &scratch_dma_handle); | ||
5043 | if (!ha->pmsg) | ||
5044 | goto out_free_pscratch; | ||
5045 | ha->msg_phys = scratch_dma_handle; | ||
5046 | |||
5047 | #ifdef INT_COAL | ||
5048 | ha->coal_stat = pci_alloc_consistent(ha->pdev, | ||
5049 | sizeof(gdth_coal_status) * MAXOFFSETS, | ||
5050 | &scratch_dma_handle); | ||
5051 | if (!ha->coal_stat) | ||
5052 | goto out_free_pmsg; | ||
5053 | ha->coal_stat_phys = scratch_dma_handle; | ||
5054 | #endif | ||
5055 | |||
5056 | ha->scratch_busy = FALSE; | ||
5057 | ha->req_first = NULL; | ||
5058 | ha->tid_cnt = pcistr[ctr].pdev->device >= 0x200 ? MAXID : MAX_HDRIVES; | ||
5059 | if (max_ids > 0 && max_ids < ha->tid_cnt) | ||
5060 | ha->tid_cnt = max_ids; | ||
5061 | for (i = 0; i < GDTH_MAXCMDS; ++i) | ||
5062 | ha->cmd_tab[i].cmnd = UNUSED_CMND; | ||
5063 | ha->scan_mode = rescan ? 0x10 : 0; | ||
5064 | |||
5065 | error = -ENODEV; | ||
5066 | if (!gdth_search_drives(ha)) { | ||
5067 | printk("GDT-PCI %d: Error during device scan\n", ha->hanum); | ||
5068 | goto out_free_coal_stat; | ||
5069 | } | ||
5070 | |||
5071 | if (hdr_channel < 0 || hdr_channel > ha->bus_cnt) | ||
5072 | hdr_channel = ha->bus_cnt; | ||
5073 | ha->virt_bus = hdr_channel; | ||
5074 | |||
5075 | /* 64-bit DMA only supported from FW >= x.43 */ | ||
5076 | if (!(ha->cache_feat & ha->raw_feat & ha->screen_feat & GDT_64BIT) || | ||
5077 | !ha->dma64_support) { | ||
5078 | if (pci_set_dma_mask(pcistr[ctr].pdev, DMA_32BIT_MASK)) { | ||
5079 | printk(KERN_WARNING "GDT-PCI %d: " | ||
5080 | "Unable to set 32-bit DMA\n", ha->hanum); | ||
5081 | goto out_free_coal_stat; | ||
5082 | } | ||
5083 | } else { | ||
5084 | shp->max_cmd_len = 16; | ||
5085 | if (!pci_set_dma_mask(pcistr[ctr].pdev, DMA_64BIT_MASK)) { | ||
5086 | printk("GDT-PCI %d: 64-bit DMA enabled\n", ha->hanum); | ||
5087 | } else if (pci_set_dma_mask(pcistr[ctr].pdev, DMA_32BIT_MASK)) { | ||
5088 | printk(KERN_WARNING "GDT-PCI %d: " | ||
5089 | "Unable to set 64/32-bit DMA\n", ha->hanum); | ||
5090 | goto out_free_coal_stat; | ||
5091 | } | ||
5092 | } | ||
5093 | |||
5094 | shp->max_id = ha->tid_cnt; | ||
5095 | shp->max_lun = MAXLUN; | ||
5096 | shp->max_channel = ha->bus_cnt; | ||
5097 | |||
5098 | spin_lock_init(&ha->smp_lock); | ||
5099 | gdth_enable_int(ha); | ||
5100 | |||
5101 | error = scsi_add_host(shp, &pcistr[ctr].pdev->dev); | ||
5102 | if (error) | ||
5103 | goto out_free_coal_stat; | ||
5104 | list_add_tail(&ha->list, &gdth_instances); | ||
5105 | return 0; | ||
5106 | |||
5107 | out_free_coal_stat: | ||
5108 | #ifdef INT_COAL | ||
5109 | pci_free_consistent(ha->pdev, sizeof(gdth_coal_status) * MAXOFFSETS, | ||
5110 | ha->coal_stat, ha->coal_stat_phys); | ||
5111 | out_free_pmsg: | ||
5112 | #endif | ||
5113 | pci_free_consistent(ha->pdev, sizeof(gdth_msg_str), | ||
5114 | ha->pmsg, ha->msg_phys); | ||
5115 | out_free_pscratch: | ||
5116 | pci_free_consistent(ha->pdev, GDTH_SCRATCH, | ||
5117 | ha->pscratch, ha->scratch_phys); | ||
5118 | out_free_irq: | ||
5119 | free_irq(ha->irq, ha); | ||
5120 | gdth_ctr_count--; | ||
5121 | out_host_put: | ||
5122 | scsi_host_put(shp); | ||
5123 | return error; | ||
5124 | } | ||
5125 | #endif /* CONFIG_PCI */ | ||
5126 | |||
5127 | static void gdth_remove_one(gdth_ha_str *ha) | ||
5128 | { | ||
5129 | struct Scsi_Host *shp = ha->shost; | ||
5130 | |||
5131 | TRACE2(("gdth_remove_one()\n")); | ||
5132 | |||
5133 | scsi_remove_host(shp); | ||
5134 | |||
5135 | if (ha->sdev) { | ||
5136 | scsi_free_host_dev(ha->sdev); | ||
5137 | ha->sdev = NULL; | ||
5138 | } | ||
5139 | |||
5140 | gdth_flush(ha); | ||
5141 | |||
5142 | if (shp->irq) | ||
5143 | free_irq(shp->irq,ha); | ||
5144 | |||
5145 | #ifdef CONFIG_ISA | ||
5146 | if (shp->dma_channel != 0xff) | ||
5147 | free_dma(shp->dma_channel); | ||
5148 | #endif | ||
5149 | #ifdef INT_COAL | ||
5150 | if (ha->coal_stat) | ||
5151 | pci_free_consistent(ha->pdev, sizeof(gdth_coal_status) * | ||
5152 | MAXOFFSETS, ha->coal_stat, ha->coal_stat_phys); | ||
5153 | #endif | ||
5154 | if (ha->pscratch) | ||
5155 | pci_free_consistent(ha->pdev, GDTH_SCRATCH, | ||
5156 | ha->pscratch, ha->scratch_phys); | ||
5157 | if (ha->pmsg) | ||
5158 | pci_free_consistent(ha->pdev, sizeof(gdth_msg_str), | ||
5159 | ha->pmsg, ha->msg_phys); | ||
5160 | if (ha->ccb_phys) | ||
5161 | pci_unmap_single(ha->pdev,ha->ccb_phys, | ||
5162 | sizeof(gdth_cmd_str),PCI_DMA_BIDIRECTIONAL); | ||
5163 | |||
5164 | scsi_host_put(shp); | ||
5165 | } | ||
5166 | |||
5167 | static int __init gdth_init(void) | ||
5168 | { | ||
5169 | if (disable) { | ||
5170 | printk("GDT-HA: Controller driver disabled from" | ||
5171 | " command line !\n"); | ||
5172 | return 0; | ||
5173 | } | ||
5174 | |||
5175 | printk("GDT-HA: Storage RAID Controller Driver. Version: %s\n", | ||
5176 | GDTH_VERSION_STR); | ||
5177 | |||
5178 | /* initializations */ | ||
5179 | gdth_polling = TRUE; | ||
5180 | gdth_clear_events(); | ||
5181 | |||
5182 | /* As default we do not probe for EISA or ISA controllers */ | ||
5183 | if (probe_eisa_isa) { | ||
5184 | /* scanning for controllers, at first: ISA controller */ | ||
5185 | #ifdef CONFIG_ISA | ||
5186 | ulong32 isa_bios; | ||
5187 | for (isa_bios = 0xc8000UL; isa_bios <= 0xd8000UL; | ||
5188 | isa_bios += 0x8000UL) | ||
5189 | gdth_isa_probe_one(isa_bios); | ||
5190 | #endif | ||
5191 | #ifdef CONFIG_EISA | ||
5192 | { | ||
5193 | ushort eisa_slot; | ||
5194 | for (eisa_slot = 0x1000; eisa_slot <= 0x8000; | ||
5195 | eisa_slot += 0x1000) | ||
5196 | gdth_eisa_probe_one(eisa_slot); | ||
5197 | } | ||
5198 | #endif | ||
5199 | } | ||
5200 | |||
5201 | #ifdef CONFIG_PCI | ||
5202 | /* scanning for PCI controllers */ | ||
5203 | { | ||
5204 | gdth_pci_str pcistr[MAXHA]; | ||
5205 | int cnt,ctr; | ||
5206 | |||
5207 | cnt = gdth_search_pci(pcistr); | ||
5208 | printk("GDT-HA: Found %d PCI Storage RAID Controllers\n", cnt); | ||
5209 | gdth_sort_pci(pcistr,cnt); | ||
5210 | for (ctr = 0; ctr < cnt; ++ctr) | ||
5211 | gdth_pci_probe_one(pcistr, ctr); | ||
5212 | } | ||
5213 | #endif /* CONFIG_PCI */ | ||
5214 | |||
5215 | TRACE2(("gdth_detect() %d controller detected\n", gdth_ctr_count)); | ||
5216 | #ifdef GDTH_STATISTICS | ||
5217 | TRACE2(("gdth_detect(): Initializing timer !\n")); | ||
5218 | init_timer(&gdth_timer); | ||
5219 | gdth_timer.expires = jiffies + HZ; | ||
5220 | gdth_timer.data = 0L; | ||
5221 | gdth_timer.function = gdth_timeout; | ||
5222 | add_timer(&gdth_timer); | ||
5223 | #endif | ||
5224 | major = register_chrdev(0,"gdth", &gdth_fops); | ||
5225 | notifier_disabled = 0; | ||
5226 | register_reboot_notifier(&gdth_notifier); | ||
5227 | gdth_polling = FALSE; | ||
5228 | return 0; | ||
5229 | } | ||
5230 | |||
5231 | static void __exit gdth_exit(void) | ||
5232 | { | ||
5233 | gdth_ha_str *ha; | ||
5234 | |||
5235 | list_for_each_entry(ha, &gdth_instances, list) | ||
5236 | gdth_remove_one(ha); | ||
5237 | |||
5238 | #ifdef GDTH_STATISTICS | ||
5239 | del_timer(&gdth_timer); | ||
5240 | #endif | ||
5241 | unregister_chrdev(major,"gdth"); | ||
5242 | unregister_reboot_notifier(&gdth_notifier); | ||
5243 | } | ||
5244 | |||
5245 | module_init(gdth_init); | ||
5246 | module_exit(gdth_exit); | ||
5671 | 5247 | ||
5672 | #include "scsi_module.c" | ||
5673 | #ifndef MODULE | 5248 | #ifndef MODULE |
5674 | __setup("gdth=", option_setup); | 5249 | __setup("gdth=", option_setup); |
5675 | #endif | 5250 | #endif |