aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Bottomley <jejb@mulgrave.(none)>2005-04-21 22:50:33 -0400
committerJames Bottomley <jejb@mulgrave.(none)>2005-05-20 13:53:15 -0400
commit099175c94a221fa2723b7273883c98cd32efe900 (patch)
tree367d0e08d62906aff04087d426d2dc8fccf7eb35
parent608648cb40f01c337be69f965cf7740f8189c31c (diff)
[SCSI] remove PCI2000 and PCI2220i drivers
From: Christoph Hellwig <hch@lst.de> Both drivers are marked broken and haven't compiled since very early 2.5.x. And they're for IDE hardware so they shouldn't have been written to the SCSI layer at all. Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
-rw-r--r--drivers/scsi/Kconfig22
-rw-r--r--drivers/scsi/Makefile2
-rw-r--r--drivers/scsi/pci2000.c836
-rw-r--r--drivers/scsi/pci2220i.c2915
-rw-r--r--drivers/scsi/pci2220i.h39
-rw-r--r--drivers/scsi/psi_dale.h564
-rw-r--r--drivers/scsi/psi_roy.h331
7 files changed, 0 insertions, 4709 deletions
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
index 750b11cefd93..2ef5aee86b29 100644
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -1192,28 +1192,6 @@ config SCSI_PAS16
1192 To compile this driver as a module, choose M here: the 1192 To compile this driver as a module, choose M here: the
1193 module will be called pas16. 1193 module will be called pas16.
1194 1194
1195config SCSI_PCI2000
1196 tristate "PCI2000 support"
1197 depends on PCI && SCSI && BROKEN
1198 help
1199 This is support for the PCI2000I EIDE interface card which acts as a
1200 SCSI host adapter. Please read the SCSI-HOWTO, available from
1201 <http://www.tldp.org/docs.html#howto>.
1202
1203 To compile this driver as a module, choose M here: the
1204 module will be called pci2000.
1205
1206config SCSI_PCI2220I
1207 tristate "PCI2220i support"
1208 depends on PCI && SCSI && BROKEN
1209 help
1210 This is support for the PCI2220i EIDE interface card which acts as a
1211 SCSI host adapter. Please read the SCSI-HOWTO, available from
1212 <http://www.tldp.org/docs.html#howto>.
1213
1214 To compile this driver as a module, choose M here: the
1215 module will be called pci2220i.
1216
1217config SCSI_PSI240I 1195config SCSI_PSI240I
1218 tristate "PSI240i support" 1196 tristate "PSI240i support"
1219 depends on ISA && SCSI 1197 depends on ISA && SCSI
diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile
index 9cb9fe7d623a..51d9c1e1884b 100644
--- a/drivers/scsi/Makefile
+++ b/drivers/scsi/Makefile
@@ -50,8 +50,6 @@ obj-$(CONFIG_MVME16x_SCSI) += mvme16x.o 53c7xx.o
50obj-$(CONFIG_BVME6000_SCSI) += bvme6000.o 53c7xx.o 50obj-$(CONFIG_BVME6000_SCSI) += bvme6000.o 53c7xx.o
51obj-$(CONFIG_SCSI_SIM710) += 53c700.o sim710.o 51obj-$(CONFIG_SCSI_SIM710) += 53c700.o sim710.o
52obj-$(CONFIG_SCSI_ADVANSYS) += advansys.o 52obj-$(CONFIG_SCSI_ADVANSYS) += advansys.o
53obj-$(CONFIG_SCSI_PCI2000) += pci2000.o
54obj-$(CONFIG_SCSI_PCI2220I) += pci2220i.o
55obj-$(CONFIG_SCSI_PSI240I) += psi240i.o 53obj-$(CONFIG_SCSI_PSI240I) += psi240i.o
56obj-$(CONFIG_SCSI_BUSLOGIC) += BusLogic.o 54obj-$(CONFIG_SCSI_BUSLOGIC) += BusLogic.o
57obj-$(CONFIG_SCSI_DPT_I2O) += dpt_i2o.o 55obj-$(CONFIG_SCSI_DPT_I2O) += dpt_i2o.o
diff --git a/drivers/scsi/pci2000.c b/drivers/scsi/pci2000.c
deleted file mode 100644
index 377a4666b568..000000000000
--- a/drivers/scsi/pci2000.c
+++ /dev/null
@@ -1,836 +0,0 @@
1/****************************************************************************
2 * Perceptive Solutions, Inc. PCI-2000 device driver for Linux.
3 *
4 * pci2000.c - Linux Host Driver for PCI-2000 IntelliCache SCSI Adapters
5 *
6 * Copyright (c) 1997-1999 Perceptive Solutions, Inc.
7 * All Rights Reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that redistributions of source
11 * code retain the above copyright notice and this comment without
12 * modification.
13 *
14 * Technical updates and product information at:
15 * http://www.psidisk.com
16 *
17 * Please send questions, comments, bug reports to:
18 * tech@psidisk.com Technical Support
19 *
20 *
21 * Revisions 1.10 Jan-21-1999
22 * - Fixed sign on message to reflect proper controller name.
23 * - Added support for RAID status monitoring and control.
24 *
25 * Revisions 1.11 Mar-22-1999
26 * - Fixed control timeout to not lock up the entire system if
27 * controller goes offline completely.
28 *
29 * Revisions 1.12 Mar-26-1999
30 * - Fixed spinlock and PCI configuration.
31 *
32 * Revisions 1.20 Mar-27-2000
33 * - Added support for dynamic DMA
34 *
35 ****************************************************************************/
36#define PCI2000_VERSION "1.20"
37
38#include <linux/blkdev.h>
39#include <linux/interrupt.h>
40#include <linux/module.h>
41#include <linux/kernel.h>
42#include <linux/types.h>
43#include <linux/string.h>
44#include <linux/pci.h>
45#include <linux/ioport.h>
46#include <linux/delay.h>
47#include <linux/sched.h>
48#include <linux/proc_fs.h>
49#include <linux/stat.h>
50#include <linux/spinlock.h>
51
52#include <asm/dma.h>
53#include <asm/system.h>
54#include <asm/io.h>
55
56#include "scsi.h"
57#include <scsi/scsi_host.h>
58#include "pci2000.h"
59#include "psi_roy.h"
60
61
62//#define DEBUG 1
63
64#ifdef DEBUG
65#define DEB(x) x
66#define STOP_HERE {int st;for(st=0;st<100;st++){st=1;}}
67#else
68#define DEB(x)
69#define STOP_HERE
70#endif
71
72typedef struct
73 {
74 unsigned int address;
75 unsigned int length;
76 } SCATGATH, *PSCATGATH;
77
78typedef struct
79 {
80 Scsi_Cmnd *SCpnt;
81 PSCATGATH scatGath;
82 dma_addr_t scatGathDma;
83 UCHAR *cdb;
84 dma_addr_t cdbDma;
85 UCHAR tag;
86 } DEV2000, *PDEV2000;
87
88typedef struct
89 {
90 ULONG basePort;
91 ULONG mb0;
92 ULONG mb1;
93 ULONG mb2;
94 ULONG mb3;
95 ULONG mb4;
96 ULONG cmd;
97 ULONG tag;
98 ULONG irqOwned;
99 struct pci_dev *pdev;
100 DEV2000 dev[MAX_BUS][MAX_UNITS];
101 } ADAPTER2000, *PADAPTER2000;
102
103#define HOSTDATA(host) ((PADAPTER2000)&host->hostdata)
104#define consistentLen (MAX_BUS * MAX_UNITS * (16 * sizeof (SCATGATH) + MAX_COMMAND_SIZE))
105
106
107static struct Scsi_Host *PsiHost[MAXADAPTER] = {NULL,}; // One for each adapter
108static int NumAdapters = 0;
109/****************************************************************
110 * Name: WaitReady :LOCAL
111 *
112 * Description: Wait for controller ready.
113 *
114 * Parameters: padapter - Pointer adapter data structure.
115 *
116 * Returns: TRUE on not ready.
117 *
118 ****************************************************************/
119static int WaitReady (PADAPTER2000 padapter)
120 {
121 ULONG z;
122
123 for ( z = 0; z < (TIMEOUT_COMMAND * 4); z++ )
124 {
125 if ( !inb_p (padapter->cmd) )
126 return FALSE;
127 udelay (250);
128 };
129 return TRUE;
130 }
131/****************************************************************
132 * Name: WaitReadyLong :LOCAL
133 *
134 * Description: Wait for controller ready.
135 *
136 * Parameters: padapter - Pointer adapter data structure.
137 *
138 * Returns: TRUE on not ready.
139 *
140 ****************************************************************/
141static int WaitReadyLong (PADAPTER2000 padapter)
142 {
143 ULONG z;
144
145 for ( z = 0; z < (5000 * 4); z++ )
146 {
147 if ( !inb_p (padapter->cmd) )
148 return FALSE;
149 udelay (250);
150 };
151 return TRUE;
152 }
153/****************************************************************
154 * Name: OpDone :LOCAL
155 *
156 * Description: Clean up operation and issue done to caller.
157 *
158 * Parameters: SCpnt - Pointer to SCSI command structure.
159 * status - Caller status.
160 *
161 * Returns: Nothing.
162 *
163 ****************************************************************/
164static void OpDone (Scsi_Cmnd *SCpnt, ULONG status)
165 {
166 SCpnt->result = status;
167 SCpnt->scsi_done (SCpnt);
168 }
169/****************************************************************
170 * Name: Command :LOCAL
171 *
172 * Description: Issue queued command to the PCI-2000.
173 *
174 * Parameters: padapter - Pointer to adapter information structure.
175 * cmd - PCI-2000 command byte.
176 *
177 * Returns: Non-zero command tag if operation is accepted.
178 *
179 ****************************************************************/
180static UCHAR Command (PADAPTER2000 padapter, UCHAR cmd)
181 {
182 outb_p (cmd, padapter->cmd);
183 if ( WaitReady (padapter) )
184 return 0;
185
186 if ( inw_p (padapter->mb0) )
187 return 0;
188
189 return inb_p (padapter->mb1);
190 }
191/****************************************************************
192 * Name: BuildSgList :LOCAL
193 *
194 * Description: Build the scatter gather list for controller.
195 *
196 * Parameters: SCpnt - Pointer to SCSI command structure.
197 * padapter - Pointer to adapter information structure.
198 * pdev - Pointer to adapter device structure.
199 *
200 * Returns: Non-zero in not scatter gather.
201 *
202 ****************************************************************/
203static int BuildSgList (Scsi_Cmnd *SCpnt, PADAPTER2000 padapter, PDEV2000 pdev)
204 {
205 int z;
206 int zc;
207 struct scatterlist *sg;
208
209 if ( SCpnt->use_sg )
210 {
211 sg = (struct scatterlist *)SCpnt->request_buffer;
212 zc = pci_map_sg (padapter->pdev, sg, SCpnt->use_sg, SCpnt->sc_data_direction);
213 for ( z = 0; z < zc; z++ )
214 {
215 pdev->scatGath[z].address = cpu_to_le32 (sg_dma_address (sg));
216 pdev->scatGath[z].length = cpu_to_le32 (sg_dma_len (sg++));
217 }
218 outl (pdev->scatGathDma, padapter->mb2);
219 outl ((zc << 24) | SCpnt->request_bufflen, padapter->mb3);
220 return FALSE;
221 }
222 if ( !SCpnt->request_bufflen)
223 {
224 outl (0, padapter->mb2);
225 outl (0, padapter->mb3);
226 return TRUE;
227 }
228 SCpnt->SCp.have_data_in = pci_map_single (padapter->pdev,
229 SCpnt->request_buffer, SCpnt->request_bufflen,
230 SCpnt->sc_data_direction);
231 outl (SCpnt->SCp.have_data_in, padapter->mb2);
232 outl (SCpnt->request_bufflen, padapter->mb3);
233 return TRUE;
234 }
235/*********************************************************************
236 * Name: PsiRaidCmd
237 *
238 * Description: Execute a simple command.
239 *
240 * Parameters: padapter - Pointer to adapter control structure.
241 * cmd - Roy command byte.
242 *
243 * Returns: Return error status.
244 *
245 ********************************************************************/
246static int PsiRaidCmd (PADAPTER2000 padapter, char cmd)
247 {
248 if ( WaitReady (padapter) ) // test for command register ready
249 return DID_TIME_OUT;
250 outb_p (cmd, padapter->cmd); // issue command
251 if ( WaitReadyLong (padapter) ) // wait for adapter ready
252 return DID_TIME_OUT;
253 return DID_OK;
254 }
255/****************************************************************
256 * Name: Irq_Handler :LOCAL
257 *
258 * Description: Interrupt handler.
259 *
260 * Parameters: irq - Hardware IRQ number.
261 * dev_id -
262 * regs -
263 *
264 * Returns: TRUE if drive is not ready in time.
265 *
266 ****************************************************************/
267static irqreturn_t Irq_Handler (int irq, void *dev_id, struct pt_regs *regs)
268 {
269 struct Scsi_Host *shost = NULL; // Pointer to host data block
270 PADAPTER2000 padapter; // Pointer to adapter control structure
271 PDEV2000 pdev;
272 Scsi_Cmnd *SCpnt;
273 UCHAR tag = 0;
274 UCHAR tag0;
275 ULONG error;
276 int pun;
277 int bus;
278 int z;
279 unsigned long flags;
280 int handled = 0;
281
282 DEB(printk ("\npci2000 received interrupt "));
283 for ( z = 0; z < NumAdapters; z++ ) // scan for interrupt to process
284 {
285 if ( PsiHost[z]->irq == (UCHAR)(irq & 0xFF) )
286 {
287 tag = inb_p (HOSTDATA(PsiHost[z])->tag);
288 if ( tag )
289 {
290 shost = PsiHost[z];
291 break;
292 }
293 }
294 }
295
296 if ( !shost )
297 {
298 DEB (printk ("\npci2000: not my interrupt"));
299 goto out;
300 }
301
302 handled = 1;
303 spin_lock_irqsave(shost->host_lock, flags);
304 padapter = HOSTDATA(shost);
305
306 tag0 = tag & 0x7F; // mask off the error bit
307 for ( bus = 0; bus < MAX_BUS; bus++ ) // scan the busses
308 {
309 for ( pun = 0; pun < MAX_UNITS; pun++ ) // scan the targets
310 {
311 pdev = &padapter->dev[bus][pun];
312 if ( !pdev->tag )
313 continue;
314 if ( pdev->tag == tag0 ) // is this it?
315 {
316 pdev->tag = 0;
317 SCpnt = pdev->SCpnt;
318 goto unmapProceed;
319 }
320 }
321 }
322
323 outb_p (0xFF, padapter->tag); // clear the op interrupt
324 outb_p (CMD_DONE, padapter->cmd); // complete the op
325 goto irq_return; // done, but, with what?
326
327unmapProceed:;
328 if ( !bus )
329 {
330 switch ( SCpnt->cmnd[0] )
331 {
332 case SCSIOP_TEST_UNIT_READY:
333 pci_unmap_single (padapter->pdev, SCpnt->SCp.have_data_in, sizeof (SCpnt->sense_buffer), PCI_DMA_FROMDEVICE);
334 goto irqProceed;
335 case SCSIOP_READ_CAPACITY:
336 pci_unmap_single (padapter->pdev, SCpnt->SCp.have_data_in, 8, PCI_DMA_FROMDEVICE);
337 goto irqProceed;
338 case SCSIOP_VERIFY:
339 case SCSIOP_START_STOP_UNIT:
340 case SCSIOP_MEDIUM_REMOVAL:
341 goto irqProceed;
342 }
343 }
344 if ( SCpnt->SCp.have_data_in )
345 pci_unmap_single (padapter->pdev, SCpnt->SCp.have_data_in, SCpnt->request_bufflen, SCpnt->sc_data_direction);
346 else
347 {
348 if ( SCpnt->use_sg )
349 pci_unmap_sg (padapter->pdev, (struct scatterlist *)SCpnt->request_buffer, SCpnt->use_sg, SCpnt->sc_data_direction);
350 }
351
352irqProceed:;
353 if ( tag & ERR08_TAGGED ) // is there an error here?
354 {
355 if ( WaitReady (padapter) )
356 {
357 OpDone (SCpnt, DID_TIME_OUT << 16);
358 goto irq_return;
359 }
360
361 outb_p (tag0, padapter->mb0); // get real error code
362 outb_p (CMD_ERROR, padapter->cmd);
363 if ( WaitReady (padapter) ) // wait for controller to suck up the op
364 {
365 OpDone (SCpnt, DID_TIME_OUT << 16);
366 goto irq_return;
367 }
368
369 error = inl (padapter->mb0); // get error data
370 outb_p (0xFF, padapter->tag); // clear the op interrupt
371 outb_p (CMD_DONE, padapter->cmd); // complete the op
372
373 DEB (printk ("status: %lX ", error));
374 if ( error == 0x00020002 ) // is this error a check condition?
375 {
376 if ( bus ) // are we doint SCSI commands?
377 {
378 OpDone (SCpnt, (DID_OK << 16) | 2);
379 goto irq_return;
380 }
381 if ( *SCpnt->cmnd == SCSIOP_TEST_UNIT_READY )
382 OpDone (SCpnt, (DRIVER_SENSE << 24) | (DID_OK << 16) | 2); // test caller we have sense data too
383 else
384 OpDone (SCpnt, DID_ERROR << 16);
385 goto irq_return;
386 }
387 OpDone (SCpnt, DID_ERROR << 16);
388 goto irq_return;
389 }
390
391 outb_p (0xFF, padapter->tag); // clear the op interrupt
392 outb_p (CMD_DONE, padapter->cmd); // complete the op
393 OpDone (SCpnt, DID_OK << 16);
394
395irq_return:
396 spin_unlock_irqrestore(shost->host_lock, flags);
397out:
398 return IRQ_RETVAL(handled);
399}
400/****************************************************************
401 * Name: Pci2000_QueueCommand
402 *
403 * Description: Process a queued command from the SCSI manager.
404 *
405 * Parameters: SCpnt - Pointer to SCSI command structure.
406 * done - Pointer to done function to call.
407 *
408 * Returns: Status code.
409 *
410 ****************************************************************/
411int Pci2000_QueueCommand (Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
412 {
413 UCHAR *cdb = (UCHAR *)SCpnt->cmnd; // Pointer to SCSI CDB
414 PADAPTER2000 padapter = HOSTDATA(SCpnt->device->host); // Pointer to adapter control structure
415 int rc = -1; // command return code
416 UCHAR bus = SCpnt->device->channel;
417 UCHAR pun = SCpnt->device->id;
418 UCHAR lun = SCpnt->device->lun;
419 UCHAR cmd;
420 PDEV2000 pdev = &padapter->dev[bus][pun];
421
422 if ( !done )
423 {
424 printk("pci2000_queuecommand: %02X: done can't be NULL\n", *cdb);
425 return 0;
426 }
427
428 SCpnt->scsi_done = done;
429 SCpnt->SCp.have_data_in = 0;
430 pdev->SCpnt = SCpnt; // Save this command data
431
432 if ( WaitReady (padapter) )
433 {
434 rc = DID_ERROR;
435 goto finished;
436 }
437
438 outw_p (pun | (lun << 8), padapter->mb0);
439
440 if ( bus )
441 {
442 DEB (if(*cdb) printk ("\nCDB: %X- %X %X %X %X %X %X %X %X %X %X ", SCpnt->cmd_len, cdb[0], cdb[1], cdb[2], cdb[3], cdb[4], cdb[5], cdb[6], cdb[7], cdb[8], cdb[9]));
443 DEB (if(*cdb) printk ("\ntimeout_per_command: %d, timeout_total: %d, timeout: %d", SCpnt->timeout_per_command,
444 SCpnt->timeout_total, SCpnt->timeout));
445 outl (SCpnt->timeout_per_command, padapter->mb1);
446 outb_p (CMD_SCSI_TIMEOUT, padapter->cmd);
447 if ( WaitReady (padapter) )
448 {
449 rc = DID_ERROR;
450 goto finished;
451 }
452
453 outw_p (pun | (lun << 8), padapter->mb0);
454 outw_p (SCpnt->cmd_len << 8, padapter->mb0 + 2);
455 memcpy (pdev->cdb, cdb, MAX_COMMAND_SIZE);
456
457 outl (pdev->cdbDma, padapter->mb1);
458 if ( BuildSgList (SCpnt, padapter, pdev) )
459 cmd = CMD_SCSI_THRU;
460 else
461 cmd = CMD_SCSI_THRU_SG;
462 if ( (pdev->tag = Command (padapter, cmd)) == 0 )
463 rc = DID_TIME_OUT;
464 goto finished;
465 }
466 else
467 {
468 if ( lun )
469 {
470 rc = DID_BAD_TARGET;
471 goto finished;
472 }
473 }
474
475 switch ( *cdb )
476 {
477 case SCSIOP_INQUIRY: // inquiry CDB
478 if ( cdb[2] == SC_MY_RAID )
479 {
480 switch ( cdb[3] )
481 {
482 case MY_SCSI_REBUILD:
483 OpDone (SCpnt, PsiRaidCmd (padapter, CMD_RAID_REBUILD) << 16);
484 return 0;
485 case MY_SCSI_ALARMMUTE:
486 OpDone (SCpnt, PsiRaidCmd (padapter, CMD_RAID_MUTE) << 16);
487 return 0;
488 case MY_SCSI_DEMOFAIL:
489 OpDone (SCpnt, PsiRaidCmd (padapter, CMD_RAID_FAIL) << 16);
490 return 0;
491 default:
492 if ( SCpnt->use_sg )
493 {
494 rc = DID_ERROR;
495 goto finished;
496 }
497 else
498 {
499 SCpnt->SCp.have_data_in = pci_map_single (padapter->pdev, SCpnt->request_buffer, SCpnt->request_bufflen,
500 SCpnt->sc_data_direction);
501 outl (SCpnt->SCp.have_data_in, padapter->mb2);
502 }
503 outl (cdb[5], padapter->mb0);
504 outl (cdb[3], padapter->mb3);
505 cmd = CMD_DASD_RAID_RQ;
506 break;
507 }
508 break;
509 }
510
511 if ( SCpnt->use_sg )
512 {
513 SCpnt->SCp.have_data_in = pci_map_single (padapter->pdev,
514 ((struct scatterlist *)SCpnt->request_buffer)->address,
515 SCpnt->request_bufflen,
516 SCpnt->sc_data_direction);
517 }
518 else
519 {
520 SCpnt->SCp.have_data_in = pci_map_single (padapter->pdev, SCpnt->request_buffer,
521 SCpnt->request_bufflen,
522 SCpnt->sc_data_direction);
523 }
524 outl (SCpnt->SCp.have_data_in, padapter->mb2);
525 outl (SCpnt->request_bufflen, padapter->mb3);
526 cmd = CMD_DASD_SCSI_INQ;
527 break;
528
529 case SCSIOP_TEST_UNIT_READY: // test unit ready CDB
530 SCpnt->SCp.have_data_in = pci_map_single (padapter->pdev, SCpnt->sense_buffer, sizeof (SCpnt->sense_buffer), PCI_DMA_FROMDEVICE);
531 outl (SCpnt->SCp.have_data_in, padapter->mb2);
532 outl (sizeof (SCpnt->sense_buffer), padapter->mb3);
533 cmd = CMD_TEST_READY;
534 break;
535
536 case SCSIOP_READ_CAPACITY: // read capacity CDB
537 if ( SCpnt->use_sg )
538 {
539 SCpnt->SCp.have_data_in = pci_map_single (padapter->pdev, ((struct scatterlist *)(SCpnt->request_buffer))->address,
540 8, PCI_DMA_FROMDEVICE);
541 }
542 else
543 SCpnt->SCp.have_data_in = pci_map_single (padapter->pdev, SCpnt->request_buffer, 8, PCI_DMA_FROMDEVICE);
544 outl (SCpnt->SCp.have_data_in, padapter->mb2);
545 outl (8, padapter->mb3);
546 cmd = CMD_DASD_CAP;
547 break;
548 case SCSIOP_VERIFY: // verify CDB
549 outw_p ((USHORT)cdb[8] | ((USHORT)cdb[7] << 8), padapter->mb0 + 2);
550 outl (XSCSI2LONG (&cdb[2]), padapter->mb1);
551 cmd = CMD_READ_SG;
552 break;
553 case SCSIOP_READ: // read10 CDB
554 outw_p ((USHORT)cdb[8] | ((USHORT)cdb[7] << 8), padapter->mb0 + 2);
555 outl (XSCSI2LONG (&cdb[2]), padapter->mb1);
556 if ( BuildSgList (SCpnt, padapter, pdev) )
557 cmd = CMD_READ;
558 else
559 cmd = CMD_READ_SG;
560 break;
561 case SCSIOP_READ6: // read6 CDB
562 outw_p (cdb[4], padapter->mb0 + 2);
563 outl ((SCSI2LONG (&cdb[1])) & 0x001FFFFF, padapter->mb1);
564 if ( BuildSgList (SCpnt, padapter, pdev) )
565 cmd = CMD_READ;
566 else
567 cmd = CMD_READ_SG;
568 break;
569 case SCSIOP_WRITE: // write10 CDB
570 outw_p ((USHORT)cdb[8] | ((USHORT)cdb[7] << 8), padapter->mb0 + 2);
571 outl (XSCSI2LONG (&cdb[2]), padapter->mb1);
572 if ( BuildSgList (SCpnt, padapter, pdev) )
573 cmd = CMD_WRITE;
574 else
575 cmd = CMD_WRITE_SG;
576 break;
577 case SCSIOP_WRITE6: // write6 CDB
578 outw_p (cdb[4], padapter->mb0 + 2);
579 outl ((SCSI2LONG (&cdb[1])) & 0x001FFFFF, padapter->mb1);
580 if ( BuildSgList (SCpnt, padapter, pdev) )
581 cmd = CMD_WRITE;
582 else
583 cmd = CMD_WRITE_SG;
584 break;
585 case SCSIOP_START_STOP_UNIT:
586 cmd = CMD_EJECT_MEDIA;
587 break;
588 case SCSIOP_MEDIUM_REMOVAL:
589 switch ( cdb[4] )
590 {
591 case 0:
592 cmd = CMD_UNLOCK_DOOR;
593 break;
594 case 1:
595 cmd = CMD_LOCK_DOOR;
596 break;
597 default:
598 cmd = 0;
599 break;
600 }
601 if ( cmd )
602 break;
603 default:
604 DEB (printk ("pci2000_queuecommand: Unsupported command %02X\n", *cdb));
605 OpDone (SCpnt, DID_ERROR << 16);
606 return 0;
607 }
608
609 if ( (pdev->tag = Command (padapter, cmd)) == 0 )
610 rc = DID_TIME_OUT;
611finished:;
612 if ( rc != -1 )
613 OpDone (SCpnt, rc << 16);
614 return 0;
615 }
616/****************************************************************
617 * Name: Pci2000_Detect
618 *
619 * Description: Detect and initialize our boards.
620 *
621 * Parameters: tpnt - Pointer to SCSI host template structure.
622 *
623 * Returns: Number of adapters installed.
624 *
625 ****************************************************************/
626int Pci2000_Detect (Scsi_Host_Template *tpnt)
627 {
628 int found = 0;
629 int installed = 0;
630 struct Scsi_Host *pshost;
631 PADAPTER2000 padapter;
632 int z, zz;
633 int setirq;
634 struct pci_dev *pdev = NULL;
635 UCHAR *consistent;
636 dma_addr_t consistentDma;
637
638 while ( (pdev = pci_find_device (VENDOR_PSI, DEVICE_ROY_1, pdev)) != NULL )
639 {
640 if (pci_enable_device(pdev))
641 continue;
642 pshost = scsi_register (tpnt, sizeof(ADAPTER2000));
643 if(pshost == NULL)
644 continue;
645 padapter = HOSTDATA(pshost);
646
647 padapter->basePort = pci_resource_start (pdev, 1);
648 DEB (printk ("\nBase Regs = %#04X", padapter->basePort)); // get the base I/O port address
649 padapter->mb0 = padapter->basePort + RTR_MAILBOX; // get the 32 bit mail boxes
650 padapter->mb1 = padapter->basePort + RTR_MAILBOX + 4;
651 padapter->mb2 = padapter->basePort + RTR_MAILBOX + 8;
652 padapter->mb3 = padapter->basePort + RTR_MAILBOX + 12;
653 padapter->mb4 = padapter->basePort + RTR_MAILBOX + 16;
654 padapter->cmd = padapter->basePort + RTR_LOCAL_DOORBELL; // command register
655 padapter->tag = padapter->basePort + RTR_PCI_DOORBELL; // tag/response register
656 padapter->pdev = pdev;
657
658 if ( WaitReady (padapter) )
659 goto unregister;
660 outb_p (0x84, padapter->mb0);
661 outb_p (CMD_SPECIFY, padapter->cmd);
662 if ( WaitReady (padapter) )
663 goto unregister;
664
665 consistent = pci_alloc_consistent (pdev, consistentLen, &consistentDma);
666 if ( !consistent )
667 {
668 printk ("Unable to allocate DMA memory for PCI-2000 controller.\n");
669 goto unregister;
670 }
671
672 scsi_set_device(pshost, &pdev->dev);
673 pshost->irq = pdev->irq;
674 setirq = 1;
675 padapter->irqOwned = 0;
676 for ( z = 0; z < installed; z++ ) // scan for shared interrupts
677 {
678 if ( PsiHost[z]->irq == pshost->irq ) // if shared then, don't posses
679 setirq = 0;
680 }
681 if ( setirq ) // if not shared, posses
682 {
683 if ( request_irq (pshost->irq, Irq_Handler, SA_SHIRQ, "pci2000", padapter) < 0 )
684 {
685 if ( request_irq (pshost->irq, Irq_Handler, SA_INTERRUPT | SA_SHIRQ, "pci2000", padapter) < 0 )
686 {
687 printk ("Unable to allocate IRQ for PCI-2000 controller.\n");
688 pci_free_consistent (pdev, consistentLen, consistent, consistentDma);
689 goto unregister;
690 }
691 }
692 padapter->irqOwned = pshost->irq; // set IRQ as owned
693 }
694 PsiHost[installed] = pshost; // save SCSI_HOST pointer
695
696 pshost->io_port = padapter->basePort;
697 pshost->n_io_port = 0xFF;
698 pshost->unique_id = padapter->basePort;
699 pshost->max_id = 16;
700 pshost->max_channel = 1;
701
702 for ( zz = 0; zz < MAX_BUS; zz++ )
703 for ( z = 0; z < MAX_UNITS; z++ )
704 {
705 padapter->dev[zz][z].tag = 0;
706 padapter->dev[zz][z].scatGath = (PSCATGATH)consistent;
707 padapter->dev[zz][z].scatGathDma = consistentDma;
708 consistent += 16 * sizeof (SCATGATH);
709 consistentDma += 16 * sizeof (SCATGATH);
710 padapter->dev[zz][z].cdb = (UCHAR *)consistent;
711 padapter->dev[zz][z].cdbDma = consistentDma;
712 consistent += MAX_COMMAND_SIZE;
713 consistentDma += MAX_COMMAND_SIZE;
714 }
715
716 printk("\nPSI-2000 Intelligent Storage SCSI CONTROLLER: at I/O = %lX IRQ = %d\n", padapter->basePort, pshost->irq);
717 printk("Version %s, Compiled %s %s\n\n", PCI2000_VERSION, __DATE__, __TIME__);
718 found++;
719 if ( ++installed < MAXADAPTER )
720 continue;
721 break;
722unregister:;
723 scsi_unregister (pshost);
724 found++;
725 }
726 NumAdapters = installed;
727 return installed;
728 }
729/****************************************************************
730 * Name: Pci2000_Abort
731 *
732 * Description: Process the Abort command from the SCSI manager.
733 *
734 * Parameters: SCpnt - Pointer to SCSI command structure.
735 *
736 * Returns: Allways snooze.
737 *
738 ****************************************************************/
739int Pci2000_Abort (Scsi_Cmnd *SCpnt)
740 {
741 DEB (printk ("pci2000_abort\n"));
742 return SCSI_ABORT_SNOOZE;
743 }
744/****************************************************************
745 * Name: Pci2000_Reset
746 *
747 * Description: Process the Reset command from the SCSI manager.
748 *
749 * Parameters: SCpnt - Pointer to SCSI command structure.
750 * flags - Flags about the reset command
751 *
752 * Returns: No active command at this time, so this means
753 * that each time we got some kind of response the
754 * last time through. Tell the mid-level code to
755 * request sense information in order to decide what
756 * to do next.
757 *
758 ****************************************************************/
759int Pci2000_Reset (Scsi_Cmnd *SCpnt, unsigned int reset_flags)
760 {
761 return SCSI_RESET_PUNT;
762 }
763/****************************************************************
764 * Name: Pci2000_Release
765 *
766 * Description: Release resources allocated for a single each adapter.
767 *
768 * Parameters: pshost - Pointer to SCSI command structure.
769 *
770 * Returns: zero.
771 *
772 ****************************************************************/
773int Pci2000_Release (struct Scsi_Host *pshost)
774 {
775 PADAPTER2000 padapter = HOSTDATA (pshost);
776
777 if ( padapter->irqOwned )
778 free_irq (pshost->irq, padapter);
779 pci_free_consistent (padapter->pdev, consistentLen, padapter->dev[0][0].scatGath, padapter->dev[0][0].scatGathDma);
780 release_region (pshost->io_port, pshost->n_io_port);
781 scsi_unregister(pshost);
782 return 0;
783 }
784
785/****************************************************************
786 * Name: Pci2000_BiosParam
787 *
788 * Description: Process the biosparam request from the SCSI manager to
789 * return C/H/S data.
790 *
791 * Parameters: disk - Pointer to SCSI disk structure.
792 * dev - Major/minor number from kernel.
793 * geom - Pointer to integer array to place geometry data.
794 *
795 * Returns: zero.
796 *
797 ****************************************************************/
798int Pci2000_BiosParam (struct scsi_device *sdev, struct block_device *dev,
799 sector_t capacity, int geom[])
800 {
801 PADAPTER2000 padapter;
802
803 padapter = HOSTDATA(sdev->host);
804
805 if ( WaitReady (padapter) )
806 return 0;
807 outb_p (sdev->id, padapter->mb0);
808 outb_p (CMD_GET_PARMS, padapter->cmd);
809 if ( WaitReady (padapter) )
810 return 0;
811
812 geom[0] = inb_p (padapter->mb2 + 3);
813 geom[1] = inb_p (padapter->mb2 + 2);
814 geom[2] = inw_p (padapter->mb2);
815 return 0;
816 }
817
818
819MODULE_LICENSE("Dual BSD/GPL");
820
821static Scsi_Host_Template driver_template = {
822 .proc_name = "pci2000",
823 .name = "PCI-2000 SCSI Intelligent Disk Controller",
824 .detect = Pci2000_Detect,
825 .release = Pci2000_Release,
826 .queuecommand = Pci2000_QueueCommand,
827 .abort = Pci2000_Abort,
828 .reset = Pci2000_Reset,
829 .bios_param = Pci2000_BiosParam,
830 .can_queue = 16,
831 .this_id = -1,
832 .sg_tablesize = 16,
833 .cmd_per_lun = 1,
834 .use_clustering = DISABLE_CLUSTERING,
835};
836#include "scsi_module.c"
diff --git a/drivers/scsi/pci2220i.c b/drivers/scsi/pci2220i.c
deleted file mode 100644
index e395e4203154..000000000000
--- a/drivers/scsi/pci2220i.c
+++ /dev/null
@@ -1,2915 +0,0 @@
1/****************************************************************************
2 * Perceptive Solutions, Inc. PCI-2220I device driver for Linux.
3 *
4 * pci2220i.c - Linux Host Driver for PCI-2220I EIDE RAID Adapters
5 *
6 * Copyright (c) 1997-1999 Perceptive Solutions, Inc.
7 * All Rights Reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that redistributions of source
11 * code retain the above copyright notice and this comment without
12 * modification.
13 *
14 * Technical updates and product information at:
15 * http://www.psidisk.com
16 *
17 * Please send questions, comments, bug reports to:
18 * tech@psidisk.com Technical Support
19 *
20 *
21 * Revisions 1.10 Mar-26-1999
22 * - Updated driver for RAID and hot reconstruct support.
23 *
24 * Revisions 1.11 Mar-26-1999
25 * - Fixed spinlock and PCI configuration.
26 *
27 * Revision 2.00 December-1-1999
28 * - Added code for the PCI-2240I controller
29 * - Added code for ATAPI devices.
30 * - Double buffer for scatter/gather support
31 *
32 * Revision 2.10 March-27-2000
33 * - Added support for dynamic DMA
34 *
35 ****************************************************************************/
36
37#error Convert me to understand page+offset based scatterlists
38
39//#define DEBUG 1
40
41#include <linux/interrupt.h>
42#include <linux/module.h>
43#include <linux/kernel.h>
44#include <linux/types.h>
45#include <linux/string.h>
46#include <linux/slab.h>
47#include <linux/pci.h>
48#include <linux/ioport.h>
49#include <linux/delay.h>
50#include <linux/sched.h>
51#include <linux/proc_fs.h>
52#include <linux/stat.h>
53#include <linux/blkdev.h>
54#include <linux/timer.h>
55#include <linux/spinlock.h>
56
57#include <asm/dma.h>
58#include <asm/system.h>
59#include <asm/io.h>
60
61#include "scsi.h"
62#include <scsi/scsi_host.h>
63#include "pci2220i.h"
64#include "psi_dale.h"
65
66
67#define PCI2220I_VERSION "2.10"
68#define READ_CMD IDE_CMD_READ_MULTIPLE
69#define WRITE_CMD IDE_CMD_WRITE_MULTIPLE
70#define MAX_BUS_MASTER_BLOCKS SECTORSXFER // This is the maximum we can bus master
71
72#ifdef DEBUG
73#define DEB(x) x
74#define STOP_HERE() {int st;for(st=0;st<100;st++){st=1;}}
75#else
76#define DEB(x)
77#define STOP_HERE()
78#endif
79
80#define MAXADAPTER 4 // Increase this and the sizes of the arrays below, if you need more.
81
82
83typedef struct
84 {
85 UCHAR byte6; // device select register image
86 UCHAR spigot; // spigot number
87 UCHAR spigots[2]; // RAID spigots
88 UCHAR deviceID[2]; // device ID codes
89 USHORT sectors; // number of sectors per track
90 USHORT heads; // number of heads
91 USHORT cylinders; // number of cylinders for this device
92 USHORT spareword; // placeholder
93 ULONG blocks; // number of blocks on device
94 DISK_MIRROR DiskMirror[2]; // RAID status and control
95 ULONG lastsectorlba[2]; // last addressable sector on the drive
96 USHORT raid; // RAID active flag
97 USHORT mirrorRecon;
98 UCHAR reconOn;
99 USHORT reconCount;
100 USHORT reconIsStarting; // indicate hot reconstruct is starting
101 UCHAR cmdDrqInt; // flag for command interrupt
102 UCHAR packet; // command packet size in bytes
103 } OUR_DEVICE, *POUR_DEVICE;
104
105typedef struct
106 {
107 USHORT bigD; // identity is a PCI-2240I if true, otherwise a PCI-2220I
108 USHORT atapi; // this interface is for ATAPI devices only
109 ULONG regDmaDesc; // address of the DMA discriptor register for direction of transfer
110 ULONG regDmaCmdStat; // Byte #1 of DMA command status register
111 ULONG regDmaAddrPci; // 32 bit register for PCI address of DMA
112 ULONG regDmaAddrLoc; // 32 bit register for local bus address of DMA
113 ULONG regDmaCount; // 32 bit register for DMA transfer count
114 ULONG regDmaMode; // 32 bit register for DMA mode control
115 ULONG regRemap; // 32 bit local space remap
116 ULONG regDesc; // 32 bit local region descriptor
117 ULONG regRange; // 32 bit local range
118 ULONG regIrqControl; // 16 bit Interrupt enable/disable and status
119 ULONG regScratchPad; // scratch pad I/O base address
120 ULONG regBase; // Base I/O register for data space
121 ULONG regData; // data register I/O address
122 ULONG regError; // error register I/O address
123 ULONG regSectCount; // sector count register I/O address
124 ULONG regLba0; // least significant byte of LBA
125 ULONG regLba8; // next least significant byte of LBA
126 ULONG regLba16; // next most significan byte of LBA
127 ULONG regLba24; // head and most 4 significant bits of LBA
128 ULONG regStatCmd; // status on read and command on write register
129 ULONG regStatSel; // board status on read and spigot select on write register
130 ULONG regFail; // fail bits control register
131 ULONG regAltStat; // alternate status and drive control register
132 ULONG basePort; // PLX base I/O port
133 USHORT timingMode; // timing mode currently set for adapter
134 USHORT timingPIO; // TRUE if PIO timing is active
135 struct pci_dev *pcidev;
136 ULONG timingAddress; // address to use on adapter for current timing mode
137 ULONG irqOwned; // owned IRQ or zero if shared
138 UCHAR numberOfDrives; // saved number of drives on this controller
139 UCHAR failRegister; // current inverted data in fail register
140 OUR_DEVICE device[BIGD_MAXDRIVES];
141 DISK_MIRROR *raidData[BIGD_MAXDRIVES];
142 ULONG startSector;
143 USHORT sectorCount;
144 ULONG readCount;
145 UCHAR *currentSgBuffer;
146 ULONG currentSgCount;
147 USHORT nextSg;
148 UCHAR cmd;
149 Scsi_Cmnd *SCpnt;
150 POUR_DEVICE pdev; // current device opearating on
151 USHORT devInReconIndex;
152 USHORT expectingIRQ;
153 USHORT reconOn; // Hot reconstruct is to be done.
154 USHORT reconPhase; // Hot reconstruct operation is in progress.
155 ULONG reconSize;
156 USHORT demoFail; // flag for RAID failure demonstration
157 USHORT survivor;
158 USHORT failinprog;
159 struct timer_list reconTimer;
160 struct timer_list timer;
161 UCHAR *kBuffer;
162 dma_addr_t kBufferDma;
163 UCHAR reqSense;
164 UCHAR atapiCdb[16];
165 UCHAR atapiSpecial;
166 } ADAPTER2220I, *PADAPTER2220I;
167
168#define HOSTDATA(host) ((PADAPTER2220I)&host->hostdata)
169
170#define RECON_PHASE_READY 0x01
171#define RECON_PHASE_COPY 0x02
172#define RECON_PHASE_UPDATE 0x03
173#define RECON_PHASE_LAST 0x04
174#define RECON_PHASE_END 0x07
175#define RECON_PHASE_MARKING 0x80
176#define RECON_PHASE_FAILOVER 0xFF
177
178static struct Scsi_Host *PsiHost[MAXADAPTER] = {NULL,}; // One for each adapter
179static int NumAdapters = 0;
180static int Installed = 0;
181static SETUP DaleSetup;
182static DISK_MIRROR DiskMirror[BIGD_MAXDRIVES];
183static ULONG ModeArray[] = {DALE_DATA_MODE2, DALE_DATA_MODE3, DALE_DATA_MODE4, DALE_DATA_MODE5};
184static ULONG ModeArray2[] = {BIGD_DATA_MODE2, BIGD_DATA_MODE3, BIGD_DATA_MODE4, BIGD_DATA_MODE5};
185
186static void ReconTimerExpiry (unsigned long data);
187
188/*******************************************************************************************************
189 * Name: Alarm
190 *
191 * Description: Sound the for the given device
192 *
193 * Parameters: padapter - Pointer adapter data structure.
194 * device - Device number.
195 *
196 * Returns: Nothing.
197 *
198 ******************************************************************************************************/
199static void Alarm (PADAPTER2220I padapter, UCHAR device)
200 {
201 UCHAR zc;
202
203 if ( padapter->bigD )
204 {
205 zc = device | (FAIL_ANY | FAIL_AUDIBLE);
206 if ( padapter->failRegister & FAIL_ANY )
207 zc |= FAIL_MULTIPLE;
208
209 padapter->failRegister = zc;
210 outb_p (~zc, padapter->regFail);
211 }
212 else
213 outb_p (0x3C | (1 << device), padapter->regFail); // sound alarm and set fail light
214 }
215/****************************************************************
216 * Name: MuteAlarm :LOCAL
217 *
218 * Description: Mute the audible alarm.
219 *
220 * Parameters: padapter - Pointer adapter data structure.
221 *
222 * Returns: TRUE if drive does not assert DRQ in time.
223 *
224 ****************************************************************/
225static void MuteAlarm (PADAPTER2220I padapter)
226 {
227 UCHAR old;
228
229 if ( padapter->bigD )
230 {
231 padapter->failRegister &= ~FAIL_AUDIBLE;
232 outb_p (~padapter->failRegister, padapter->regFail);
233 }
234 else
235 {
236 old = (inb_p (padapter->regStatSel) >> 3) | (inb_p (padapter->regStatSel) & 0x83);
237 outb_p (old | 0x40, padapter->regFail);
238 }
239 }
240/****************************************************************
241 * Name: WaitReady :LOCAL
242 *
243 * Description: Wait for device ready.
244 *
245 * Parameters: padapter - Pointer adapter data structure.
246 *
247 * Returns: TRUE if drive does not assert DRQ in time.
248 *
249 ****************************************************************/
250static int WaitReady (PADAPTER2220I padapter)
251 {
252 ULONG z;
253 UCHAR status;
254
255 for ( z = 0; z < (TIMEOUT_READY * 4); z++ )
256 {
257 status = inb_p (padapter->regStatCmd);
258 if ( (status & (IDE_STATUS_DRDY | IDE_STATUS_BUSY)) == IDE_STATUS_DRDY )
259 return 0;
260 udelay (250);
261 }
262 return status;
263 }
264/****************************************************************
265 * Name: WaitReadyReset :LOCAL
266 *
267 * Description: Wait for device ready.
268 *
269 * Parameters: padapter - Pointer adapter data structure.
270 *
271 * Returns: TRUE if drive does not assert DRQ in time.
272 *
273 ****************************************************************/
274static int WaitReadyReset (PADAPTER2220I padapter)
275 {
276 ULONG z;
277 UCHAR status;
278
279 for ( z = 0; z < (125 * 16); z++ ) // wait up to 1/4 second
280 {
281 status = inb_p (padapter->regStatCmd);
282 if ( (status & (IDE_STATUS_DRDY | IDE_STATUS_BUSY)) == IDE_STATUS_DRDY )
283 {
284 DEB (printk ("\nPCI2220I: Reset took %ld mSec to be ready", z / 8));
285 return 0;
286 }
287 udelay (125);
288 }
289 DEB (printk ("\nPCI2220I: Reset took more than 2 Seconds to come ready, Disk Failure"));
290 return status;
291 }
292/****************************************************************
293 * Name: WaitDrq :LOCAL
294 *
295 * Description: Wait for device ready for data transfer.
296 *
297 * Parameters: padapter - Pointer adapter data structure.
298 *
299 * Returns: TRUE if drive does not assert DRQ in time.
300 *
301 ****************************************************************/
302static int WaitDrq (PADAPTER2220I padapter)
303 {
304 ULONG z;
305 UCHAR status;
306
307 for ( z = 0; z < (TIMEOUT_DRQ * 4); z++ )
308 {
309 status = inb_p (padapter->regStatCmd);
310 if ( status & IDE_STATUS_DRQ )
311 return 0;
312 udelay (250);
313 }
314 return status;
315 }
316/****************************************************************
317 * Name: AtapiWaitReady :LOCAL
318 *
319 * Description: Wait for device busy and DRQ to be cleared.
320 *
321 * Parameters: padapter - Pointer adapter data structure.
322 * msec - Number of milliseconds to wait.
323 *
324 * Returns: TRUE if drive does not clear busy in time.
325 *
326 ****************************************************************/
327static int AtapiWaitReady (PADAPTER2220I padapter, int msec)
328 {
329 int z;
330
331 for ( z = 0; z < (msec * 16); z++ )
332 {
333 if ( !(inb_p (padapter->regStatCmd) & (IDE_STATUS_BUSY | IDE_STATUS_DRQ)) )
334 return FALSE;
335 udelay (125);
336 }
337 return TRUE;
338 }
339/****************************************************************
340 * Name: AtapiWaitDrq :LOCAL
341 *
342 * Description: Wait for device ready for data transfer.
343 *
344 * Parameters: padapter - Pointer adapter data structure.
345 * msec - Number of milliseconds to wait.
346 *
347 * Returns: TRUE if drive does not assert DRQ in time.
348 *
349 ****************************************************************/
350static int AtapiWaitDrq (PADAPTER2220I padapter, int msec)
351 {
352 ULONG z;
353
354 for ( z = 0; z < (msec * 16); z++ )
355 {
356 if ( inb_p (padapter->regStatCmd) & IDE_STATUS_DRQ )
357 return 0;
358 udelay (128);
359 }
360 return TRUE;
361 }
362/****************************************************************
363 * Name: HardReset :LOCAL
364 *
365 * Description: Wait for device ready for data transfer.
366 *
367 * Parameters: padapter - Pointer adapter data structure.
368 * pdev - Pointer to device.
369 * spigot - Spigot number.
370 *
371 * Returns: TRUE if drive does not assert DRQ in time.
372 *
373 ****************************************************************/
374static int HardReset (PADAPTER2220I padapter, POUR_DEVICE pdev, UCHAR spigot)
375 {
376 DEB (printk ("\npci2220i:RESET spigot = %X devices = %d, %d", spigot, pdev->deviceID[0], pdev->deviceID[1]));
377 mdelay (100); // just wait 100 mSec to let drives flush
378 SelectSpigot (padapter, spigot | SEL_IRQ_OFF);
379
380 outb_p (0x0E, padapter->regAltStat); // reset the suvivor
381 udelay (100); // wait a little
382 outb_p (0x08, padapter->regAltStat); // clear the reset
383 udelay (100);
384
385 outb_p (0xA0, padapter->regLba24); // select the master drive
386 if ( WaitReadyReset (padapter) )
387 {
388 DEB (printk ("\npci2220i: master not ready after reset"));
389 return TRUE;
390 }
391 outb_p (0xB0, padapter->regLba24); // try the slave drive
392 if ( (inb_p (padapter->regStatCmd) & (IDE_STATUS_DRDY | IDE_STATUS_BUSY)) == IDE_STATUS_DRDY )
393 {
394 DEB (printk ("\nPCI2220I: initializing slave drive on spigot %X", spigot));
395 outb_p (SECTORSXFER, padapter->regSectCount);
396 WriteCommand (padapter, IDE_CMD_SET_MULTIPLE);
397 if ( WaitReady (padapter) )
398 {
399 DEB (printk ("\npci2220i: slave not ready after set multiple"));
400 return TRUE;
401 }
402 }
403
404 outb_p (0xA0, padapter->regLba24); // select the drive
405 outb_p (SECTORSXFER, padapter->regSectCount);
406 WriteCommand (padapter, IDE_CMD_SET_MULTIPLE);
407 if ( WaitReady (padapter) )
408 {
409 DEB (printk ("\npci2220i: master not ready after set multiple"));
410 return TRUE;
411 }
412 return FALSE;
413 }
414/****************************************************************
415 * Name: AtapiReset :LOCAL
416 *
417 * Description: Wait for device ready for data transfer.
418 *
419 * Parameters: padapter - Pointer adapter data structure.
420 * pdev - Pointer to device.
421 *
422 * Returns: TRUE if drive does not come ready.
423 *
424 ****************************************************************/
425static int AtapiReset (PADAPTER2220I padapter, POUR_DEVICE pdev)
426 {
427 SelectSpigot (padapter, pdev->spigot);
428 AtapiDevice (padapter, pdev->byte6);
429 AtapiCountLo (padapter, 0);
430 AtapiCountHi (padapter, 0);
431 WriteCommand (padapter, IDE_COMMAND_ATAPI_RESET);
432 udelay (125);
433 if ( AtapiWaitReady (padapter, 1000) )
434 return TRUE;
435 if ( inb_p (padapter->regStatCmd) || (inb_p (padapter->regLba8) != 0x14) || (inb_p (padapter->regLba16) != 0xEB) )
436 return TRUE;
437 return FALSE;
438 }
439/****************************************************************
440 * Name: WalkScatGath :LOCAL
441 *
442 * Description: Transfer data to/from scatter/gather buffers.
443 *
444 * Parameters: padapter - Pointer adapter data structure.
445 * datain - TRUE if data read.
446 * length - Number of bytes to transfer.
447 *
448 * Returns: Nothing.
449 *
450 ****************************************************************/
451static void WalkScatGath (PADAPTER2220I padapter, UCHAR datain, ULONG length)
452 {
453 ULONG count;
454 UCHAR *buffer = padapter->kBuffer;
455
456 while ( length )
457 {
458 count = ( length > padapter->currentSgCount ) ? padapter->currentSgCount : length;
459
460 if ( datain )
461 memcpy (padapter->currentSgBuffer, buffer, count);
462 else
463 memcpy (buffer, padapter->currentSgBuffer, count);
464
465 padapter->currentSgCount -= count;
466 if ( !padapter->currentSgCount )
467 {
468 if ( padapter->nextSg < padapter->SCpnt->use_sg )
469 {
470 padapter->currentSgBuffer = ((struct scatterlist *)padapter->SCpnt->request_buffer)[padapter->nextSg].address;
471 padapter->currentSgCount = ((struct scatterlist *)padapter->SCpnt->request_buffer)[padapter->nextSg].length;
472 padapter->nextSg++;
473 }
474 }
475 else
476 padapter->currentSgBuffer += count;
477
478 length -= count;
479 buffer += count;
480 }
481 }
482/****************************************************************
483 * Name: BusMaster :LOCAL
484 *
485 * Description: Do a bus master I/O.
486 *
487 * Parameters: padapter - Pointer adapter data structure.
488 * datain - TRUE if data read.
489 * irq - TRUE if bus master interrupt expected.
490 *
491 * Returns: Nothing.
492 *
493 ****************************************************************/
494static void BusMaster (PADAPTER2220I padapter, UCHAR datain, UCHAR irq)
495 {
496 ULONG zl;
497
498 zl = ( padapter->sectorCount > MAX_BUS_MASTER_BLOCKS ) ? MAX_BUS_MASTER_BLOCKS : padapter->sectorCount;
499 padapter->sectorCount -= zl;
500 zl *= (ULONG)BYTES_PER_SECTOR;
501
502 if ( datain )
503 {
504 padapter->readCount = zl;
505 outb_p (8, padapter->regDmaDesc); // read operation
506 if ( padapter->bigD )
507 {
508 if ( irq && !padapter->sectorCount )
509 outb_p (0x0C, padapter->regDmaMode); // interrupt on
510 else
511 outb_p (0x08, padapter->regDmaMode); // no interrupt
512 }
513 else
514 {
515 if ( irq && !padapter->sectorCount )
516 outb_p (0x05, padapter->regDmaMode); // interrupt on
517 else
518 outb_p (0x01, padapter->regDmaMode); // no interrupt
519 }
520 }
521 else
522 {
523 outb_p (0x00, padapter->regDmaDesc); // write operation
524 if ( padapter->bigD )
525 outb_p (0x08, padapter->regDmaMode); // no interrupt
526 else
527 outb_p (0x01, padapter->regDmaMode); // no interrupt
528 WalkScatGath (padapter, FALSE, zl);
529 }
530
531 outl (padapter->timingAddress, padapter->regDmaAddrLoc);
532 outl (padapter->kBufferDma, padapter->regDmaAddrPci);
533 outl (zl, padapter->regDmaCount);
534 outb_p (0x03, padapter->regDmaCmdStat); // kick the DMA engine in gear
535 }
536/****************************************************************
537 * Name: AtapiBusMaster :LOCAL
538 *
539 * Description: Do a bus master I/O.
540 *
541 * Parameters: padapter - Pointer adapter data structure.
542 * datain - TRUE if data read.
543 * length - Number of bytes to transfer.
544 *
545 * Returns: Nothing.
546 *
547 ****************************************************************/
548static void AtapiBusMaster (PADAPTER2220I padapter, UCHAR datain, ULONG length)
549 {
550 outl (padapter->timingAddress, padapter->regDmaAddrLoc);
551 outl (padapter->kBufferDma, padapter->regDmaAddrPci);
552 outl (length, padapter->regDmaCount);
553 if ( datain )
554 {
555 if ( padapter->readCount )
556 WalkScatGath (padapter, TRUE, padapter->readCount);
557 outb_p (0x08, padapter->regDmaDesc); // read operation
558 outb_p (0x08, padapter->regDmaMode); // no interrupt
559 padapter->readCount = length;
560 }
561 else
562 {
563 outb_p (0x00, padapter->regDmaDesc); // write operation
564 outb_p (0x08, padapter->regDmaMode); // no interrupt
565 if ( !padapter->atapiSpecial )
566 WalkScatGath (padapter, FALSE, length);
567 }
568 outb_p (0x03, padapter->regDmaCmdStat); // kick the DMA engine in gear
569 }
570/****************************************************************
571 * Name: WriteData :LOCAL
572 *
573 * Description: Write data to device.
574 *
575 * Parameters: padapter - Pointer adapter data structure.
576 *
577 * Returns: TRUE if drive does not assert DRQ in time.
578 *
579 ****************************************************************/
580static int WriteData (PADAPTER2220I padapter)
581 {
582 ULONG zl;
583
584 if ( !WaitDrq (padapter) )
585 {
586 if ( padapter->timingPIO )
587 {
588 zl = (padapter->sectorCount > MAX_BUS_MASTER_BLOCKS) ? MAX_BUS_MASTER_BLOCKS : padapter->sectorCount;
589 WalkScatGath (padapter, FALSE, zl * BYTES_PER_SECTOR);
590 outsw (padapter->regData, padapter->kBuffer, zl * (BYTES_PER_SECTOR / 2));
591 padapter->sectorCount -= zl;
592 }
593 else
594 BusMaster (padapter, 0, 0);
595 return 0;
596 }
597 padapter->cmd = 0; // null out the command byte
598 return 1;
599 }
600/****************************************************************
601 * Name: WriteDataBoth :LOCAL
602 *
603 * Description: Write data to device.
604 *
605 * Parameters: padapter - Pointer to adapter structure.
606 * pdev - Pointer to device structure
607 *
608 * Returns: Index + 1 of drive not failed or zero for OK.
609 *
610 ****************************************************************/
611static int WriteDataBoth (PADAPTER2220I padapter, POUR_DEVICE pdev)
612 {
613 ULONG zl;
614 UCHAR status0, status1;
615
616 SelectSpigot (padapter, pdev->spigots[0]);
617 status0 = WaitDrq (padapter);
618 if ( !status0 )
619 {
620 SelectSpigot (padapter, pdev->spigots[1]);
621 status1 = WaitDrq (padapter);
622 if ( !status1 )
623 {
624 SelectSpigot (padapter, pdev->spigots[0] | pdev->spigots[1] | padapter->bigD);
625 if ( padapter->timingPIO )
626 {
627 zl = (padapter->sectorCount > MAX_BUS_MASTER_BLOCKS) ? MAX_BUS_MASTER_BLOCKS : padapter->sectorCount;
628 WalkScatGath (padapter, FALSE, zl * BYTES_PER_SECTOR);
629 outsw (padapter->regData, padapter->kBuffer, zl * (BYTES_PER_SECTOR / 2));
630 padapter->sectorCount -= zl;
631 }
632 else
633 BusMaster (padapter, 0, 0);
634 return 0;
635 }
636 }
637 padapter->cmd = 0; // null out the command byte
638 if ( status0 )
639 return 2;
640 return 1;
641 }
642/****************************************************************
643 * Name: IdeCmd :LOCAL
644 *
645 * Description: Process an IDE command.
646 *
647 * Parameters: padapter - Pointer adapter data structure.
648 * pdev - Pointer to device.
649 *
650 * Returns: Zero if no error or status register contents on error.
651 *
652 ****************************************************************/
653static UCHAR IdeCmd (PADAPTER2220I padapter, POUR_DEVICE pdev)
654 {
655 UCHAR status;
656
657 SelectSpigot (padapter, pdev->spigot | padapter->bigD); // select the spigot
658 outb_p (pdev->byte6 | ((UCHAR *)(&padapter->startSector))[3], padapter->regLba24); // select the drive
659 status = WaitReady (padapter);
660 if ( !status )
661 {
662 outb_p (padapter->sectorCount, padapter->regSectCount);
663 outb_p (((UCHAR *)(&padapter->startSector))[0], padapter->regLba0);
664 outb_p (((UCHAR *)(&padapter->startSector))[1], padapter->regLba8);
665 outb_p (((UCHAR *)(&padapter->startSector))[2], padapter->regLba16);
666 padapter->expectingIRQ = TRUE;
667 WriteCommand (padapter, padapter->cmd);
668 return 0;
669 }
670
671 padapter->cmd = 0; // null out the command byte
672 return status;
673 }
674/****************************************************************
675 * Name: IdeCmdBoth :LOCAL
676 *
677 * Description: Process an IDE command to both drivers.
678 *
679 * Parameters: padapter - Pointer adapter data structure.
680 * pdev - Pointer to device structure
681 *
682 * Returns: Index + 1 of drive not failed or zero for OK.
683 *
684 ****************************************************************/
685static UCHAR IdeCmdBoth (PADAPTER2220I padapter, POUR_DEVICE pdev)
686 {
687 UCHAR status0;
688 UCHAR status1;
689
690 SelectSpigot (padapter, pdev->spigots[0] | pdev->spigots[1]); // select the spigots
691 outb_p (padapter->pdev->byte6 | ((UCHAR *)(&padapter->startSector))[3], padapter->regLba24);// select the drive
692 SelectSpigot (padapter, pdev->spigots[0]);
693 status0 = WaitReady (padapter);
694 if ( !status0 )
695 {
696 SelectSpigot (padapter, pdev->spigots[1]);
697 status1 = WaitReady (padapter);
698 if ( !status1 )
699 {
700 SelectSpigot (padapter, pdev->spigots[0] | pdev->spigots[1] | padapter->bigD);
701 outb_p (padapter->sectorCount, padapter->regSectCount);
702 outb_p (((UCHAR *)(&padapter->startSector))[0], padapter->regLba0);
703 outb_p (((UCHAR *)(&padapter->startSector))[1], padapter->regLba8);
704 outb_p (((UCHAR *)(&padapter->startSector))[2], padapter->regLba16);
705 padapter->expectingIRQ = TRUE;
706 WriteCommand (padapter, padapter->cmd);
707 return 0;
708 }
709 }
710 padapter->cmd = 0; // null out the command byte
711 if ( status0 )
712 return 2;
713 return 1;
714 }
715/****************************************************************
716 * Name: OpDone :LOCAL
717 *
718 * Description: Complete an operatoin done sequence.
719 *
720 * Parameters: padapter - Pointer to host data block.
721 * spigot - Spigot select code.
722 * device - Device byte code.
723 *
724 * Returns: Nothing.
725 *
726 ****************************************************************/
727static void OpDone (PADAPTER2220I padapter, ULONG result)
728 {
729 Scsi_Cmnd *SCpnt = padapter->SCpnt;
730
731 if ( padapter->reconPhase )
732 {
733 padapter->reconPhase = 0;
734 if ( padapter->SCpnt )
735 {
736 Pci2220i_QueueCommand (SCpnt, SCpnt->scsi_done);
737 }
738 else
739 {
740 if ( padapter->reconOn )
741 {
742 ReconTimerExpiry ((unsigned long)padapter);
743 }
744 }
745 }
746 else
747 {
748 padapter->cmd = 0;
749 padapter->SCpnt = NULL;
750 padapter->pdev = NULL;
751 SCpnt->result = result;
752 SCpnt->scsi_done (SCpnt);
753 if ( padapter->reconOn && !padapter->reconTimer.data )
754 {
755 padapter->reconTimer.expires = jiffies + (HZ / 4); // start in 1/4 second
756 padapter->reconTimer.data = (unsigned long)padapter;
757 add_timer (&padapter->reconTimer);
758 }
759 }
760 }
761/****************************************************************
762 * Name: InlineIdentify :LOCAL
763 *
764 * Description: Do an intline inquiry on a drive.
765 *
766 * Parameters: padapter - Pointer to host data block.
767 * spigot - Spigot select code.
768 * device - Device byte code.
769 *
770 * Returns: Last addressable sector or zero if none.
771 *
772 ****************************************************************/
773static ULONG InlineIdentify (PADAPTER2220I padapter, UCHAR spigot, UCHAR device)
774 {
775 PIDENTIFY_DATA pid = (PIDENTIFY_DATA)padapter->kBuffer;
776
777 SelectSpigot (padapter, spigot | SEL_IRQ_OFF); // select the spigot
778 outb_p ((device << 4) | 0xA0, padapter->regLba24); // select the drive
779 if ( WaitReady (padapter) )
780 return 0;
781 WriteCommand (padapter, IDE_COMMAND_IDENTIFY);
782 if ( WaitDrq (padapter) )
783 return 0;
784 insw (padapter->regData, padapter->kBuffer, sizeof (IDENTIFY_DATA) >> 1);
785 return (pid->LBATotalSectors - 1);
786 }
787/****************************************************************
788 * Name: AtapiIdentify :LOCAL
789 *
790 * Description: Do an intline inquiry on a drive.
791 *
792 * Parameters: padapter - Pointer to host data block.
793 * pdev - Pointer to device table.
794 *
795 * Returns: TRUE on error.
796 *
797 ****************************************************************/
798static ULONG AtapiIdentify (PADAPTER2220I padapter, POUR_DEVICE pdev)
799 {
800 ATAPI_GENERAL_0 ag0;
801 USHORT zs;
802 int z;
803
804 AtapiDevice (padapter, pdev->byte6);
805 WriteCommand (padapter, IDE_COMMAND_ATAPI_IDENTIFY);
806 if ( AtapiWaitDrq (padapter, 3000) )
807 return TRUE;
808
809 *(USHORT *)&ag0 = inw_p (padapter->regData);
810 for ( z = 0; z < 255; z++ )
811 zs = inw_p (padapter->regData);
812
813 if ( ag0.ProtocolType == 2 )
814 {
815 if ( ag0.CmdDrqType == 1 )
816 pdev->cmdDrqInt = TRUE;
817 switch ( ag0.CmdPacketSize )
818 {
819 case 0:
820 pdev->packet = 6;
821 break;
822 case 1:
823 pdev->packet = 8;
824 break;
825 default:
826 pdev->packet = 6;
827 break;
828 }
829 return FALSE;
830 }
831 return TRUE;
832 }
833/****************************************************************
834 * Name: Atapi2Scsi
835 *
836 * Description: Convert ATAPI data to SCSI data.
837 *
838 * Parameters: padapter - Pointer adapter data structure.
839 * SCpnt - Pointer to SCSI command structure.
840 *
841 * Returns: Nothing.
842 *
843 ****************************************************************/
844void Atapi2Scsi (PADAPTER2220I padapter, Scsi_Cmnd *SCpnt)
845 {
846 UCHAR *buff = padapter->currentSgBuffer;
847
848 switch ( SCpnt->cmnd[0] )
849 {
850 case SCSIOP_MODE_SENSE:
851 buff[0] = padapter->kBuffer[1];
852 buff[1] = padapter->kBuffer[2];
853 buff[2] = padapter->kBuffer[3];
854 buff[3] = padapter->kBuffer[7];
855 memcpy (&buff[4], &padapter->kBuffer[8], padapter->atapiCdb[8] - 8);
856 break;
857 case SCSIOP_INQUIRY:
858 padapter->kBuffer[2] = 2;
859 memcpy (buff, padapter->kBuffer, padapter->currentSgCount);
860 break;
861 default:
862 if ( padapter->readCount )
863 WalkScatGath (padapter, TRUE, padapter->readCount);
864 break;
865 }
866 }
867/****************************************************************
868 * Name: Scsi2Atapi
869 *
870 * Description: Convert SCSI packet command to Atapi packet command.
871 *
872 * Parameters: padapter - Pointer adapter data structure.
873 * SCpnt - Pointer to SCSI command structure.
874 *
875 * Returns: Nothing.
876 *
877 ****************************************************************/
878static void Scsi2Atapi (PADAPTER2220I padapter, Scsi_Cmnd *SCpnt)
879 {
880 UCHAR *cdb = SCpnt->cmnd;
881 UCHAR *buff = padapter->currentSgBuffer;
882
883 switch (cdb[0])
884 {
885 case SCSIOP_READ6:
886 padapter->atapiCdb[0] = SCSIOP_READ;
887 padapter->atapiCdb[1] = cdb[1] & 0xE0;
888 padapter->atapiCdb[3] = cdb[1] & 0x1F;
889 padapter->atapiCdb[4] = cdb[2];
890 padapter->atapiCdb[5] = cdb[3];
891 padapter->atapiCdb[8] = cdb[4];
892 padapter->atapiCdb[9] = cdb[5];
893 break;
894 case SCSIOP_WRITE6:
895 padapter->atapiCdb[0] = SCSIOP_WRITE;
896 padapter->atapiCdb[1] = cdb[1] & 0xE0;
897 padapter->atapiCdb[3] = cdb[1] & 0x1F;
898 padapter->atapiCdb[4] = cdb[2];
899 padapter->atapiCdb[5] = cdb[3];
900 padapter->atapiCdb[8] = cdb[4];
901 padapter->atapiCdb[9] = cdb[5];
902 break;
903 case SCSIOP_MODE_SENSE:
904 padapter->atapiCdb[0] = SCSIOP_MODE_SENSE10;
905 padapter->atapiCdb[2] = cdb[2];
906 padapter->atapiCdb[8] = cdb[4] + 4;
907 break;
908
909 case SCSIOP_MODE_SELECT:
910 padapter->atapiSpecial = TRUE;
911 padapter->atapiCdb[0] = SCSIOP_MODE_SELECT10;
912 padapter->atapiCdb[1] = cdb[1] | 0x10;
913 memcpy (padapter->kBuffer, buff, 4);
914 padapter->kBuffer[4] = padapter->kBuffer[5] = 0;
915 padapter->kBuffer[6] = padapter->kBuffer[7] = 0;
916 memcpy (&padapter->kBuffer[8], &buff[4], cdb[4] - 4);
917 padapter->atapiCdb[8] = cdb[4] + 4;
918 break;
919 }
920 }
921/****************************************************************
922 * Name: AtapiSendCdb
923 *
924 * Description: Send the CDB packet to the device.
925 *
926 * Parameters: padapter - Pointer adapter data structure.
927 * pdev - Pointer to device.
928 * cdb - Pointer to 16 byte SCSI cdb.
929 *
930 * Returns: Nothing.
931 *
932 ****************************************************************/
933static void AtapiSendCdb (PADAPTER2220I padapter, POUR_DEVICE pdev, CHAR *cdb)
934 {
935 DEB (printk ("\nPCI2242I: CDB: %X %X %X %X %X %X %X %X %X %X %X %X", cdb[0], cdb[1], cdb[2], cdb[3], cdb[4], cdb[5], cdb[6], cdb[7], cdb[8], cdb[9], cdb[10], cdb[11]));
936 outsw (padapter->regData, cdb, pdev->packet);
937 }
938/****************************************************************
939 * Name: AtapiRequestSense
940 *
941 * Description: Send the CDB packet to the device.
942 *
943 * Parameters: padapter - Pointer adapter data structure.
944 * pdev - Pointer to device.
945 * SCpnt - Pointer to SCSI command structure.
946 * pass - If true then this is the second pass to send cdb.
947 *
948 * Returns: TRUE on error.
949 *
950 ****************************************************************/
951static int AtapiRequestSense (PADAPTER2220I padapter, POUR_DEVICE pdev, Scsi_Cmnd *SCpnt, UCHAR pass)
952 {
953 UCHAR cdb[16] = {SCSIOP_REQUEST_SENSE,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0};
954
955 DEB (printk ("\nPCI2242I: AUTO REQUEST SENSE"));
956 cdb[4] = (UCHAR)(sizeof (SCpnt->sense_buffer));
957 if ( !pass )
958 {
959 padapter->reqSense = TRUE;
960 AtapiCountLo (padapter, cdb[4]);
961 AtapiCountHi (padapter, 0);
962 outb_p (0, padapter->regError);
963 WriteCommand (padapter, IDE_COMMAND_ATAPI_PACKET);
964 if ( pdev->cmdDrqInt )
965 return FALSE;
966
967 if ( AtapiWaitDrq (padapter, 500) )
968 return TRUE;
969 }
970 AtapiSendCdb (padapter, pdev, cdb);
971 return FALSE;
972 }
973/****************************************************************
974 * Name: InlineReadSignature :LOCAL
975 *
976 * Description: Do an inline read RAID sigature.
977 *
978 * Parameters: padapter - Pointer adapter data structure.
979 * pdev - Pointer to device.
980 * index - index of data to read.
981 *
982 * Returns: Zero if no error or status register contents on error.
983 *
984 ****************************************************************/
985static UCHAR InlineReadSignature (PADAPTER2220I padapter, POUR_DEVICE pdev, int index)
986 {
987 UCHAR status;
988 ULONG zl = pdev->lastsectorlba[index];
989
990 SelectSpigot (padapter, pdev->spigots[index] | SEL_IRQ_OFF); // select the spigot without interrupts
991 outb_p (pdev->byte6 | ((UCHAR *)&zl)[3], padapter->regLba24);
992 status = WaitReady (padapter);
993 if ( !status )
994 {
995 outb_p (((UCHAR *)&zl)[2], padapter->regLba16);
996 outb_p (((UCHAR *)&zl)[1], padapter->regLba8);
997 outb_p (((UCHAR *)&zl)[0], padapter->regLba0);
998 outb_p (1, padapter->regSectCount);
999 WriteCommand (padapter, IDE_COMMAND_READ);
1000 status = WaitDrq (padapter);
1001 if ( !status )
1002 {
1003 insw (padapter->regData, padapter->kBuffer, BYTES_PER_SECTOR / 2);
1004 ((ULONG *)(&pdev->DiskMirror[index]))[0] = ((ULONG *)(&padapter->kBuffer[DISK_MIRROR_POSITION]))[0];
1005 ((ULONG *)(&pdev->DiskMirror[index]))[1] = ((ULONG *)(&padapter->kBuffer[DISK_MIRROR_POSITION]))[1];
1006 // some drives assert DRQ before IRQ so let's make sure we clear the IRQ
1007 WaitReady (padapter);
1008 return 0;
1009 }
1010 }
1011 return status;
1012 }
1013/****************************************************************
1014 * Name: DecodeError :LOCAL
1015 *
1016 * Description: Decode and process device errors.
1017 *
1018 * Parameters: padapter - Pointer to adapter data.
1019 * status - Status register code.
1020 *
1021 * Returns: The driver status code.
1022 *
1023 ****************************************************************/
1024static ULONG DecodeError (PADAPTER2220I padapter, UCHAR status)
1025 {
1026 UCHAR error;
1027
1028 padapter->expectingIRQ = 0;
1029 if ( status & IDE_STATUS_WRITE_FAULT )
1030 {
1031 return DID_PARITY << 16;
1032 }
1033 if ( status & IDE_STATUS_BUSY )
1034 return DID_BUS_BUSY << 16;
1035
1036 error = inb_p (padapter->regError);
1037 DEB(printk ("\npci2220i error register: %x", error));
1038 switch ( error )
1039 {
1040 case IDE_ERROR_AMNF:
1041 case IDE_ERROR_TKONF:
1042 case IDE_ERROR_ABRT:
1043 case IDE_ERROR_IDFN:
1044 case IDE_ERROR_UNC:
1045 case IDE_ERROR_BBK:
1046 default:
1047 return DID_ERROR << 16;
1048 }
1049 return DID_ERROR << 16;
1050 }
1051/****************************************************************
1052 * Name: StartTimer :LOCAL
1053 *
1054 * Description: Start the timer.
1055 *
1056 * Parameters: ipadapter - Pointer adapter data structure.
1057 *
1058 * Returns: Nothing.
1059 *
1060 ****************************************************************/
1061static void StartTimer (PADAPTER2220I padapter)
1062 {
1063 padapter->timer.expires = jiffies + TIMEOUT_DATA;
1064 add_timer (&padapter->timer);
1065 }
1066/****************************************************************
1067 * Name: WriteSignature :LOCAL
1068 *
1069 * Description: Start the timer.
1070 *
1071 * Parameters: padapter - Pointer adapter data structure.
1072 * pdev - Pointer to our device.
1073 * spigot - Selected spigot.
1074 * index - index of mirror signature on device.
1075 *
1076 * Returns: TRUE on any error.
1077 *
1078 ****************************************************************/
1079static int WriteSignature (PADAPTER2220I padapter, POUR_DEVICE pdev, UCHAR spigot, int index)
1080 {
1081 ULONG zl;
1082
1083 SelectSpigot (padapter, spigot);
1084 zl = pdev->lastsectorlba[index];
1085 outb_p (pdev->byte6 | ((UCHAR *)&zl)[3], padapter->regLba24);
1086 outb_p (((UCHAR *)&zl)[2], padapter->regLba16);
1087 outb_p (((UCHAR *)&zl)[1], padapter->regLba8);
1088 outb_p (((UCHAR *)&zl)[0], padapter->regLba0);
1089 outb_p (1, padapter->regSectCount);
1090
1091 WriteCommand (padapter, IDE_COMMAND_WRITE);
1092 if ( WaitDrq (padapter) )
1093 return TRUE;
1094 StartTimer (padapter);
1095 padapter->expectingIRQ = TRUE;
1096
1097 ((ULONG *)(&padapter->kBuffer[DISK_MIRROR_POSITION]))[0] = ((ULONG *)(&pdev->DiskMirror[index]))[0];
1098 ((ULONG *)(&padapter->kBuffer[DISK_MIRROR_POSITION]))[1] = ((ULONG *)(&pdev->DiskMirror[index]))[1];
1099 outsw (padapter->regData, padapter->kBuffer, BYTES_PER_SECTOR / 2);
1100 return FALSE;
1101 }
1102/*******************************************************************************************************
1103 * Name: InitFailover
1104 *
1105 * Description: This is the beginning of the failover routine
1106 *
1107 * Parameters: SCpnt - Pointer to SCSI command structure.
1108 * padapter - Pointer adapter data structure.
1109 * pdev - Pointer to our device.
1110 *
1111 * Returns: TRUE on error.
1112 *
1113 ******************************************************************************************************/
1114static int InitFailover (PADAPTER2220I padapter, POUR_DEVICE pdev)
1115 {
1116 UCHAR spigot;
1117
1118 DEB (printk ("\npci2220i: Initialize failover process - survivor = %d", pdev->deviceID[padapter->survivor]));
1119 pdev->raid = FALSE; //initializes system for non raid mode
1120 pdev->reconOn = FALSE;
1121 spigot = pdev->spigots[padapter->survivor];
1122
1123 if ( pdev->DiskMirror[padapter->survivor].status & UCBF_REBUILD )
1124 {
1125 DEB (printk ("\n failed, is survivor"));
1126 return (TRUE);
1127 }
1128
1129 if ( HardReset (padapter, pdev, spigot) )
1130 {
1131 DEB (printk ("\n failed, reset"));
1132 return TRUE;
1133 }
1134
1135 Alarm (padapter, pdev->deviceID[padapter->survivor ^ 1]);
1136 pdev->DiskMirror[padapter->survivor].status = UCBF_MIRRORED | UCBF_SURVIVOR; //clear present status
1137
1138 if ( WriteSignature (padapter, pdev, spigot, padapter->survivor) )
1139 {
1140 DEB (printk ("\n failed, write signature"));
1141 return TRUE;
1142 }
1143 padapter->failinprog = TRUE;
1144 return FALSE;
1145 }
1146/****************************************************************
1147 * Name: TimerExpiry :LOCAL
1148 *
1149 * Description: Timer expiry routine.
1150 *
1151 * Parameters: data - Pointer adapter data structure.
1152 *
1153 * Returns: Nothing.
1154 *
1155 ****************************************************************/
1156static void TimerExpiry (unsigned long data)
1157 {
1158 PADAPTER2220I padapter = (PADAPTER2220I)data;
1159 struct Scsi_Host *host = padapter->SCpnt->device->host;
1160 POUR_DEVICE pdev = padapter->pdev;
1161 UCHAR status = IDE_STATUS_BUSY;
1162 UCHAR temp, temp1;
1163 unsigned long flags;
1164
1165 /*
1166 * Disable interrupts, if they aren't already disabled and acquire
1167 * the I/O spinlock.
1168 */
1169 spin_lock_irqsave (host->host_lock, flags);
1170 DEB (printk ("\nPCI2220I: Timeout expired "));
1171
1172 if ( padapter->failinprog )
1173 {
1174 DEB (printk ("in failover process"));
1175 OpDone (padapter, DecodeError (padapter, inb_p (padapter->regStatCmd)));
1176 goto timerExpiryDone;
1177 }
1178
1179 while ( padapter->reconPhase )
1180 {
1181 DEB (printk ("in recon phase %X", padapter->reconPhase));
1182 switch ( padapter->reconPhase )
1183 {
1184 case RECON_PHASE_MARKING:
1185 case RECON_PHASE_LAST:
1186 padapter->survivor = ( pdev->spigot == pdev->spigots[0] ) ? 1 : 0;
1187 DEB (printk ("\npci2220i: FAILURE 1"));
1188 if ( InitFailover (padapter, pdev) )
1189 OpDone (padapter, DID_ERROR << 16);
1190 goto timerExpiryDone;
1191
1192 case RECON_PHASE_READY:
1193 OpDone (padapter, DID_ERROR << 16);
1194 goto timerExpiryDone;
1195
1196 case RECON_PHASE_COPY:
1197 padapter->survivor = ( pdev->spigot == pdev->spigots[0] ) ? 0 : 1;
1198 DEB (printk ("\npci2220i: FAILURE 2"));
1199 DEB (printk ("\n spig/stat = %X", inb_p (padapter->regStatSel));
1200 if ( InitFailover (padapter, pdev) )
1201 OpDone (padapter, DID_ERROR << 16);
1202 goto timerExpiryDone;
1203
1204 case RECON_PHASE_UPDATE:
1205 padapter->survivor = ( pdev->spigot == pdev->spigots[0] ) ? 0 : 1;
1206 DEB (printk ("\npci2220i: FAILURE 3")));
1207 if ( InitFailover (padapter, pdev) )
1208 OpDone (padapter, DID_ERROR << 16);
1209 goto timerExpiryDone;
1210
1211 case RECON_PHASE_END:
1212 padapter->survivor = ( pdev->spigot == pdev->spigots[0] ) ? 0 : 1;
1213 DEB (printk ("\npci2220i: FAILURE 4"));
1214 if ( InitFailover (padapter, pdev) )
1215 OpDone (padapter, DID_ERROR << 16);
1216 goto timerExpiryDone;
1217
1218 default:
1219 goto timerExpiryDone;
1220 }
1221 }
1222
1223 while ( padapter->cmd )
1224 {
1225 outb_p (0x08, padapter->regDmaCmdStat); // cancel interrupt from DMA engine
1226 if ( pdev->raid )
1227 {
1228 if ( padapter->cmd == WRITE_CMD )
1229 {
1230 DEB (printk ("in RAID write operation"));
1231 temp = ( pdev->spigot & (SEL_1 | SEL_2) ) ? SEL_1 : SEL_3;
1232 if ( inb_p (padapter->regStatSel) & temp )
1233 {
1234 DEB (printk ("\npci2220i: Determined A OK"));
1235 SelectSpigot (padapter, temp | SEL_IRQ_OFF); // Masking the interrupt during spigot select
1236 temp = inb_p (padapter->regStatCmd);
1237 }
1238 else
1239 temp = IDE_STATUS_BUSY;
1240
1241 temp1 = ( pdev->spigot & (SEL_1 | SEL_2) ) ? SEL_2 : SEL_4;
1242 if ( inb (padapter->regStatSel) & temp1 )
1243 {
1244 DEB (printk ("\npci2220i: Determined B OK"));
1245 SelectSpigot (padapter, temp1 | SEL_IRQ_OFF); // Masking the interrupt during spigot select
1246 temp1 = inb_p (padapter->regStatCmd);
1247 }
1248 else
1249 temp1 = IDE_STATUS_BUSY;
1250
1251 if ( (temp & IDE_STATUS_BUSY) || (temp1 & IDE_STATUS_BUSY) )
1252 {
1253 DEB (printk ("\npci2220i: Status A: %X B: %X", temp & 0xFF, temp1 & 0xFF));
1254 if ( (temp & IDE_STATUS_BUSY) && (temp1 & IDE_STATUS_BUSY) )
1255 {
1256 status = temp;
1257 break;
1258 }
1259 else
1260 {
1261 if ( temp & IDE_STATUS_BUSY )
1262 padapter->survivor = 1;
1263 else
1264 padapter->survivor = 0;
1265 if ( InitFailover (padapter, pdev) )
1266 {
1267 status = inb_p (padapter->regStatCmd);
1268 break;
1269 }
1270 goto timerExpiryDone;
1271 }
1272 }
1273 }
1274 else
1275 {
1276 DEB (printk ("in RAID read operation"));
1277 padapter->survivor = ( pdev->spigot == pdev->spigots[0] ) ? 0 : 1;
1278 DEB (printk ("\npci2220i: FAILURE 6"));
1279 if ( InitFailover (padapter, pdev) )
1280 {
1281 status = inb_p (padapter->regStatCmd);
1282 break;
1283 }
1284 goto timerExpiryDone;
1285 }
1286 }
1287 else
1288 {
1289 DEB (printk ("in I/O operation"));
1290 status = inb_p (padapter->regStatCmd);
1291 }
1292 break;
1293 }
1294
1295 OpDone (padapter, DecodeError (padapter, status));
1296
1297timerExpiryDone:;
1298 /*
1299 * Release the I/O spinlock and restore the original flags
1300 * which will enable interrupts if and only if they were
1301 * enabled on entry.
1302 */
1303 spin_unlock_irqrestore (host->host_lock, flags);
1304 }
1305/****************************************************************
1306 * Name: SetReconstruct :LOCAL
1307 *
1308 * Description: Set the reconstruct up.
1309 *
1310 * Parameters: pdev - Pointer to device structure.
1311 * index - Mirror index number.
1312 *
1313 * Returns: Number of sectors on new disk required.
1314 *
1315 ****************************************************************/
1316static LONG SetReconstruct (POUR_DEVICE pdev, int index)
1317 {
1318 pdev->DiskMirror[index].status = UCBF_MIRRORED; // setup the flags
1319 pdev->DiskMirror[index ^ 1].status = UCBF_MIRRORED | UCBF_REBUILD;
1320 pdev->DiskMirror[index ^ 1].reconstructPoint = 0; // start the reconstruct
1321 pdev->reconCount = 1990; // mark target drive early
1322 return pdev->DiskMirror[index].reconstructPoint;
1323 }
1324/****************************************************************
1325 * Name: ReconTimerExpiry :LOCAL
1326 *
1327 * Description: Reconstruct timer expiry routine.
1328 *
1329 * Parameters: data - Pointer adapter data structure.
1330 *
1331 * Returns: Nothing.
1332 *
1333 ****************************************************************/
1334static void ReconTimerExpiry (unsigned long data)
1335 {
1336 PADAPTER2220I padapter = (PADAPTER2220I)data;
1337 struct Scsi_Host *host = padapter->SCpnt->device->host;
1338 POUR_DEVICE pdev;
1339 ULONG testsize = 0;
1340 PIDENTIFY_DATA pid;
1341 USHORT minmode;
1342 ULONG zl;
1343 UCHAR zc;
1344 USHORT z;
1345 unsigned long flags;
1346
1347 /*
1348 * Disable interrupts, if they aren't already disabled and acquire
1349 * the I/O spinlock.
1350 */
1351 spin_lock_irqsave(host->host_lock, flags);
1352
1353 if ( padapter->SCpnt )
1354 goto reconTimerExpiry;
1355
1356 padapter->reconTimer.data = 0;
1357 for ( z = padapter->devInReconIndex + 1; z < BIGD_MAXDRIVES; z++ )
1358 {
1359 if ( padapter->device[z].reconOn )
1360 break;
1361 }
1362 if ( z < BIGD_MAXDRIVES )
1363 pdev = &padapter->device[z];
1364 else
1365 {
1366 for ( z = 0; z < BIGD_MAXDRIVES; z++ )
1367 {
1368 if ( padapter->device[z].reconOn )
1369 break;
1370 }
1371 if ( z < BIGD_MAXDRIVES )
1372 pdev = &padapter->device[z];
1373 else
1374 {
1375 padapter->reconOn = FALSE;
1376 goto reconTimerExpiry;
1377 }
1378 }
1379
1380 padapter->devInReconIndex = z;
1381 pid = (PIDENTIFY_DATA)padapter->kBuffer;
1382 padapter->pdev = pdev;
1383 if ( pdev->reconIsStarting )
1384 {
1385 pdev->reconIsStarting = FALSE;
1386 pdev->reconOn = FALSE;
1387
1388 while ( (pdev->DiskMirror[0].signature == SIGNATURE) && (pdev->DiskMirror[1].signature == SIGNATURE) &&
1389 (pdev->DiskMirror[0].pairIdentifier == (pdev->DiskMirror[1].pairIdentifier ^ 1)) )
1390 {
1391 if ( (pdev->DiskMirror[0].status & UCBF_MATCHED) && (pdev->DiskMirror[1].status & UCBF_MATCHED) )
1392 break;
1393
1394 if ( pdev->DiskMirror[0].status & UCBF_SURVIVOR ) // is first drive survivor?
1395 testsize = SetReconstruct (pdev, 0);
1396 else
1397 if ( pdev->DiskMirror[1].status & UCBF_SURVIVOR ) // is second drive survivor?
1398 testsize = SetReconstruct (pdev, 1);
1399
1400 if ( (pdev->DiskMirror[0].status & UCBF_REBUILD) || (pdev->DiskMirror[1].status & UCBF_REBUILD) )
1401 {
1402 if ( pdev->DiskMirror[0].status & UCBF_REBUILD )
1403 pdev->mirrorRecon = 0;
1404 else
1405 pdev->mirrorRecon = 1;
1406 pdev->reconOn = TRUE;
1407 }
1408 break;
1409 }
1410
1411 if ( !pdev->reconOn )
1412 goto reconTimerExpiry;
1413
1414 if ( padapter->bigD )
1415 {
1416 padapter->failRegister = 0;
1417 outb_p (~padapter->failRegister, padapter->regFail);
1418 }
1419 else
1420 {
1421 zc = ((inb_p (padapter->regStatSel) >> 3) | inb_p (padapter->regStatSel)) & 0x83; // mute the alarm
1422 outb_p (0xFF, padapter->regFail);
1423 }
1424
1425 while ( 1 )
1426 {
1427 DEB (printk ("\npci2220i: hard reset issue"));
1428 if ( HardReset (padapter, pdev, pdev->spigots[pdev->mirrorRecon]) )
1429 {
1430 DEB (printk ("\npci2220i: sub 1"));
1431 break;
1432 }
1433
1434 pdev->lastsectorlba[pdev->mirrorRecon] = InlineIdentify (padapter, pdev->spigots[pdev->mirrorRecon], pdev->deviceID[pdev->mirrorRecon] & 1);
1435
1436 if ( pdev->lastsectorlba[pdev->mirrorRecon] < testsize )
1437 {
1438 DEB (printk ("\npci2220i: sub 2 %ld %ld", pdev->lastsectorlba[pdev->mirrorRecon], testsize));
1439 break;
1440 }
1441
1442 // test LBA and multiper sector transfer compatibility
1443 if (!pid->SupportLBA || (pid->NumSectorsPerInt < SECTORSXFER) || !pid->Valid_64_70 )
1444 {
1445 DEB (printk ("\npci2220i: sub 3"));
1446 break;
1447 }
1448
1449 // test PIO/bus matering mode compatibility
1450 if ( (pid->MinPIOCycleWithoutFlow > 240) && !pid->SupportIORDYDisable && !padapter->timingPIO )
1451 {
1452 DEB (printk ("\npci2220i: sub 4"));
1453 break;
1454 }
1455
1456 if ( pid->MinPIOCycleWithoutFlow <= 120 ) // setup timing mode of drive
1457 minmode = 5;
1458 else
1459 {
1460 if ( pid->MinPIOCylceWithFlow <= 150 )
1461 minmode = 4;
1462 else
1463 {
1464 if ( pid->MinPIOCylceWithFlow <= 180 )
1465 minmode = 3;
1466 else
1467 {
1468 if ( pid->MinPIOCylceWithFlow <= 240 )
1469 minmode = 2;
1470 else
1471 {
1472 DEB (printk ("\npci2220i: sub 5"));
1473 break;
1474 }
1475 }
1476 }
1477 }
1478
1479 if ( padapter->timingMode > minmode ) // set minimum timing mode
1480 padapter->timingMode = minmode;
1481 if ( padapter->timingMode >= 2 )
1482 padapter->timingAddress = ModeArray[padapter->timingMode - 2];
1483 else
1484 padapter->timingPIO = TRUE;
1485
1486 padapter->reconOn = TRUE;
1487 break;
1488 }
1489
1490 if ( !pdev->reconOn )
1491 {
1492 padapter->survivor = pdev->mirrorRecon ^ 1;
1493 padapter->reconPhase = RECON_PHASE_FAILOVER;
1494 DEB (printk ("\npci2220i: FAILURE 7"));
1495 InitFailover (padapter, pdev);
1496 goto reconTimerExpiry;
1497 }
1498
1499 pdev->raid = TRUE;
1500
1501 if ( WriteSignature (padapter, pdev, pdev->spigot, pdev->mirrorRecon ^ 1) )
1502 goto reconTimerExpiry;
1503 padapter->reconPhase = RECON_PHASE_MARKING;
1504 goto reconTimerExpiry;
1505 }
1506
1507 //**********************************
1508 // reconstruct copy starts here
1509 //**********************************
1510 if ( pdev->reconCount++ > 2000 )
1511 {
1512 pdev->reconCount = 0;
1513 if ( WriteSignature (padapter, pdev, pdev->spigots[pdev->mirrorRecon], pdev->mirrorRecon) )
1514 {
1515 padapter->survivor = pdev->mirrorRecon ^ 1;
1516 padapter->reconPhase = RECON_PHASE_FAILOVER;
1517 DEB (printk ("\npci2220i: FAILURE 8"));
1518 InitFailover (padapter, pdev);
1519 goto reconTimerExpiry;
1520 }
1521 padapter->reconPhase = RECON_PHASE_UPDATE;
1522 goto reconTimerExpiry;
1523 }
1524
1525 zl = pdev->DiskMirror[pdev->mirrorRecon].reconstructPoint;
1526 padapter->reconSize = pdev->DiskMirror[pdev->mirrorRecon ^ 1].reconstructPoint - zl;
1527 if ( padapter->reconSize > MAX_BUS_MASTER_BLOCKS )
1528 padapter->reconSize = MAX_BUS_MASTER_BLOCKS;
1529
1530 if ( padapter->reconSize )
1531 {
1532 SelectSpigot (padapter, pdev->spigots[0] | pdev->spigots[1]); // select the spigots
1533 outb_p (pdev->byte6 | ((UCHAR *)(&zl))[3], padapter->regLba24); // select the drive
1534 SelectSpigot (padapter, pdev->spigot);
1535 if ( WaitReady (padapter) )
1536 goto reconTimerExpiry;
1537
1538 SelectSpigot (padapter, pdev->spigots[pdev->mirrorRecon]);
1539 if ( WaitReady (padapter) )
1540 {
1541 padapter->survivor = pdev->mirrorRecon ^ 1;
1542 padapter->reconPhase = RECON_PHASE_FAILOVER;
1543 DEB (printk ("\npci2220i: FAILURE 9"));
1544 InitFailover (padapter, pdev);
1545 goto reconTimerExpiry;
1546 }
1547
1548 SelectSpigot (padapter, pdev->spigots[0] | pdev->spigots[1]);
1549 outb_p (padapter->reconSize & 0xFF, padapter->regSectCount);
1550 outb_p (((UCHAR *)(&zl))[0], padapter->regLba0);
1551 outb_p (((UCHAR *)(&zl))[1], padapter->regLba8);
1552 outb_p (((UCHAR *)(&zl))[2], padapter->regLba16);
1553 padapter->expectingIRQ = TRUE;
1554 padapter->reconPhase = RECON_PHASE_READY;
1555 SelectSpigot (padapter, pdev->spigots[pdev->mirrorRecon]);
1556 WriteCommand (padapter, WRITE_CMD);
1557 StartTimer (padapter);
1558 SelectSpigot (padapter, pdev->spigot);
1559 WriteCommand (padapter, READ_CMD);
1560 goto reconTimerExpiry;
1561 }
1562
1563 pdev->DiskMirror[pdev->mirrorRecon].status = UCBF_MIRRORED | UCBF_MATCHED;
1564 pdev->DiskMirror[pdev->mirrorRecon ^ 1].status = UCBF_MIRRORED | UCBF_MATCHED;
1565 if ( WriteSignature (padapter, pdev, pdev->spigot, pdev->mirrorRecon ^ 1) )
1566 goto reconTimerExpiry;
1567 padapter->reconPhase = RECON_PHASE_LAST;
1568
1569reconTimerExpiry:;
1570 /*
1571 * Release the I/O spinlock and restore the original flags
1572 * which will enable interrupts if and only if they were
1573 * enabled on entry.
1574 */
1575 spin_unlock_irqrestore(host->host_lock, flags);
1576 }
1577/****************************************************************
1578 * Name: Irq_Handler :LOCAL
1579 *
1580 * Description: Interrupt handler.
1581 *
1582 * Parameters: irq - Hardware IRQ number.
1583 * dev_id -
1584 * regs -
1585 *
1586 * Returns: TRUE if drive is not ready in time.
1587 *
1588 ****************************************************************/
1589static irqreturn_t Irq_Handler (int irq, void *dev_id, struct pt_regs *regs)
1590 {
1591 struct Scsi_Host *shost = NULL; // Pointer to host data block
1592 PADAPTER2220I padapter; // Pointer to adapter control structure
1593 POUR_DEVICE pdev;
1594 Scsi_Cmnd *SCpnt;
1595 UCHAR status;
1596 UCHAR status1;
1597 ATAPI_STATUS statusa;
1598 ATAPI_REASON reasona;
1599 ATAPI_ERROR errora;
1600 int z;
1601 ULONG zl;
1602 unsigned long flags;
1603 int handled = 0;
1604
1605// DEB (printk ("\npci2220i received interrupt\n"));
1606
1607 for ( z = 0; z < NumAdapters; z++ ) // scan for interrupt to process
1608 {
1609 if ( PsiHost[z]->irq == (UCHAR)(irq & 0xFF) )
1610 {
1611 if ( inw_p (HOSTDATA(PsiHost[z])->regIrqControl) & 0x8000 )
1612 {
1613 shost = PsiHost[z];
1614 break;
1615 }
1616 }
1617 }
1618
1619 if ( !shost )
1620 {
1621 DEB (printk ("\npci2220i: not my interrupt"));
1622 goto out;
1623 }
1624
1625 handled = 1;
1626 spin_lock_irqsave(shost->host_lock, flags);
1627 padapter = HOSTDATA(shost);
1628 pdev = padapter->pdev;
1629 SCpnt = padapter->SCpnt;
1630 outb_p (0x08, padapter->regDmaCmdStat); // cancel interrupt from DMA engine
1631
1632 if ( padapter->atapi && SCpnt )
1633 {
1634 *(char *)&statusa = inb_p (padapter->regStatCmd); // read the device status
1635 *(char *)&reasona = inb_p (padapter->regSectCount); // read the device interrupt reason
1636
1637 if ( !statusa.bsy )
1638 {
1639 if ( statusa.drq ) // test for transfer phase
1640 {
1641 if ( !reasona.cod ) // test for data phase
1642 {
1643 z = (ULONG)inb_p (padapter->regLba8) | (ULONG)(inb_p (padapter->regLba16) << 8);
1644 if ( padapter->reqSense )
1645 insw (padapter->regData, SCpnt->sense_buffer, z / 2);
1646 else
1647 AtapiBusMaster (padapter, reasona.io, z);
1648 goto irq_return;
1649 }
1650 if ( reasona.cod && !reasona.io ) // test for command packet phase
1651 {
1652 if ( padapter->reqSense )
1653 AtapiRequestSense (padapter, pdev, SCpnt, TRUE);
1654 else
1655 AtapiSendCdb (padapter, pdev, padapter->atapiCdb);
1656 goto irq_return;
1657 }
1658 }
1659 else
1660 {
1661 if ( reasona.io && statusa.drdy ) // test for status phase
1662 {
1663 Atapi2Scsi (padapter, SCpnt);
1664 if ( statusa.check )
1665 {
1666 *(UCHAR *)&errora = inb_p (padapter->regError); // read the device error
1667 if ( errora.senseKey )
1668 {
1669 if ( padapter->reqSense || AtapiRequestSense (padapter, pdev, SCpnt, FALSE) )
1670 OpDone (padapter, DID_ERROR << 16);
1671 }
1672 else
1673 {
1674 if ( errora.ili || errora.abort )
1675 OpDone (padapter, DID_ERROR << 16);
1676 else
1677 OpDone (padapter, DID_OK << 16);
1678 }
1679 }
1680 else
1681 if ( padapter->reqSense )
1682 {
1683 DEB (printk ("PCI2242I: Sense codes - %X %X %X ", ((UCHAR *)SCpnt->sense_buffer)[0], ((UCHAR *)SCpnt->sense_buffer)[12], ((UCHAR *)SCpnt->sense_buffer)[13]));
1684 OpDone (padapter, (DRIVER_SENSE << 24) | (DID_OK << 16) | 2);
1685 }
1686 else
1687 OpDone (padapter, DID_OK << 16);
1688 }
1689 }
1690 }
1691 goto irq_return;
1692 }
1693
1694 if ( !padapter->expectingIRQ || !(SCpnt || padapter->reconPhase) )
1695 {
1696 DEB(printk ("\npci2220i Unsolicited interrupt\n"));
1697 STOP_HERE ();
1698 goto irq_return;
1699 }
1700 padapter->expectingIRQ = 0;
1701
1702 if ( padapter->failinprog )
1703 {
1704 DEB (printk ("\npci2220i interrupt failover complete"));
1705 padapter->failinprog = FALSE;
1706 status = inb_p (padapter->regStatCmd); // read the device status
1707 if ( status & (IDE_STATUS_ERROR | IDE_STATUS_WRITE_FAULT) )
1708 {
1709 DEB (printk ("\npci2220i: interrupt failover error from drive %X", status));
1710 padapter->cmd = 0;
1711 }
1712 else
1713 {
1714 DEB (printk ("\npci2220i: restarting failed opertation."));
1715 pdev->spigot = (padapter->survivor) ? pdev->spigots[1] : pdev->spigots[0];
1716 del_timer (&padapter->timer);
1717 if ( padapter->reconPhase )
1718 OpDone (padapter, DID_OK << 16);
1719 else
1720 Pci2220i_QueueCommand (SCpnt, SCpnt->scsi_done);
1721 goto irq_return;
1722 }
1723 }
1724
1725 if ( padapter->reconPhase )
1726 {
1727 switch ( padapter->reconPhase )
1728 {
1729 case RECON_PHASE_MARKING:
1730 case RECON_PHASE_LAST:
1731 status = inb_p (padapter->regStatCmd); // read the device status
1732 del_timer (&padapter->timer);
1733 if ( padapter->reconPhase == RECON_PHASE_LAST )
1734 {
1735 if ( status & (IDE_STATUS_ERROR | IDE_STATUS_WRITE_FAULT) )
1736 {
1737 padapter->survivor = ( pdev->spigot == pdev->spigots[0] ) ? 1 : 0;
1738 DEB (printk ("\npci2220i: FAILURE 10"));
1739 if ( InitFailover (padapter, pdev) )
1740 OpDone (padapter, DecodeError (padapter, status));
1741 goto irq_return;
1742 }
1743 if ( WriteSignature (padapter, pdev, pdev->spigots[pdev->mirrorRecon], pdev->mirrorRecon) )
1744 {
1745 padapter->survivor = ( pdev->spigot == pdev->spigots[0] ) ? 0 : 1;
1746 DEB (printk ("\npci2220i: FAILURE 11"));
1747 if ( InitFailover (padapter, pdev) )
1748 OpDone (padapter, DecodeError (padapter, status));
1749 goto irq_return;
1750 }
1751 padapter->reconPhase = RECON_PHASE_END;
1752 goto irq_return;
1753 }
1754 OpDone (padapter, DID_OK << 16);
1755 goto irq_return;
1756
1757 case RECON_PHASE_READY:
1758 status = inb_p (padapter->regStatCmd); // read the device status
1759 if ( status & (IDE_STATUS_ERROR | IDE_STATUS_WRITE_FAULT) )
1760 {
1761 del_timer (&padapter->timer);
1762 OpDone (padapter, DecodeError (padapter, status));
1763 goto irq_return;
1764 }
1765 SelectSpigot (padapter, pdev->spigots[pdev->mirrorRecon]);
1766 if ( WaitDrq (padapter) )
1767 {
1768 del_timer (&padapter->timer);
1769 padapter->survivor = ( pdev->spigot == pdev->spigots[0] ) ? 0 : 1;
1770 DEB (printk ("\npci2220i: FAILURE 12"));
1771 if ( InitFailover (padapter, pdev) )
1772 OpDone (padapter, DecodeError (padapter, status));
1773 goto irq_return;
1774 }
1775 SelectSpigot (padapter, pdev->spigot | SEL_COPY | padapter->bigD);
1776 padapter->reconPhase = RECON_PHASE_COPY;
1777 padapter->expectingIRQ = TRUE;
1778 if ( padapter->timingPIO )
1779 {
1780 insw (padapter->regData, padapter->kBuffer, padapter->reconSize * (BYTES_PER_SECTOR / 2));
1781 }
1782 else
1783 {
1784 if ( (padapter->timingMode > 3) )
1785 {
1786 if ( padapter->bigD )
1787 outl (BIGD_DATA_MODE3, padapter->regDmaAddrLoc);
1788 else
1789 outl (DALE_DATA_MODE3, padapter->regDmaAddrLoc);
1790 }
1791 else
1792 outl (padapter->timingAddress, padapter->regDmaAddrLoc);
1793 outl (padapter->kBufferDma, padapter->regDmaAddrPci);
1794 outl (padapter->reconSize * BYTES_PER_SECTOR, padapter->regDmaCount);
1795 outb_p (8, padapter->regDmaDesc); // read operation
1796 if ( padapter->bigD )
1797 outb_p (8, padapter->regDmaMode); // no interrupt
1798 else
1799 outb_p (1, padapter->regDmaMode); // no interrupt
1800 outb_p (0x03, padapter->regDmaCmdStat); // kick the DMA engine in gear
1801 }
1802 goto irq_return;
1803
1804 case RECON_PHASE_COPY:
1805 pdev->DiskMirror[pdev->mirrorRecon].reconstructPoint += padapter->reconSize;
1806
1807 case RECON_PHASE_UPDATE:
1808 SelectSpigot (padapter, pdev->spigots[pdev->mirrorRecon] | SEL_IRQ_OFF);
1809 status = inb_p (padapter->regStatCmd); // read the device status
1810 del_timer (&padapter->timer);
1811 if ( status & (IDE_STATUS_ERROR | IDE_STATUS_WRITE_FAULT) )
1812 {
1813 padapter->survivor = ( pdev->spigot == pdev->spigots[0] ) ? 0 : 1;
1814 DEB (printk ("\npci2220i: FAILURE 13"));
1815 DEB (printk ("\n status register = %X error = %X", status, inb_p (padapter->regError)));
1816 if ( InitFailover (padapter, pdev) )
1817 OpDone (padapter, DecodeError (padapter, status));
1818 goto irq_return;
1819 }
1820 OpDone (padapter, DID_OK << 16);
1821 goto irq_return;
1822
1823 case RECON_PHASE_END:
1824 status = inb_p (padapter->regStatCmd); // read the device status
1825 del_timer (&padapter->timer);
1826 if ( status & (IDE_STATUS_ERROR | IDE_STATUS_WRITE_FAULT) )
1827 {
1828 padapter->survivor = ( pdev->spigot == pdev->spigots[0] ) ? 0 : 1;
1829 DEB (printk ("\npci2220i: FAILURE 14"));
1830 if ( InitFailover (padapter, pdev) )
1831 OpDone (padapter, DecodeError (padapter, status));
1832 goto irq_return;
1833 }
1834 pdev->reconOn = 0;
1835 if ( padapter->bigD )
1836 {
1837 for ( z = 0; z < padapter->numberOfDrives; z++ )
1838 {
1839 if ( padapter->device[z].DiskMirror[0].status & UCBF_SURVIVOR )
1840 {
1841 Alarm (padapter, padapter->device[z].deviceID[0] ^ 2);
1842 MuteAlarm (padapter);
1843 }
1844 if ( padapter->device[z].DiskMirror[1].status & UCBF_SURVIVOR )
1845 {
1846 Alarm (padapter, padapter->device[z].deviceID[1] ^ 2);
1847 MuteAlarm (padapter);
1848 }
1849 }
1850 }
1851 OpDone (padapter, DID_OK << 16);
1852 goto irq_return;
1853
1854 default:
1855 goto irq_return;
1856 }
1857 }
1858
1859 switch ( padapter->cmd ) // decide how to handle the interrupt
1860 {
1861 case READ_CMD:
1862 if ( padapter->sectorCount )
1863 {
1864 status = inb_p (padapter->regStatCmd); // read the device status
1865 if ( status & (IDE_STATUS_ERROR | IDE_STATUS_WRITE_FAULT) )
1866 {
1867 if ( pdev->raid )
1868 {
1869 padapter->survivor = ( pdev->spigot == pdev->spigots[0] ) ? 1 : 0;
1870 del_timer (&padapter->timer);
1871 DEB (printk ("\npci2220i: FAILURE 15"));
1872 if ( !InitFailover (padapter, pdev) )
1873 goto irq_return;
1874 }
1875 break;
1876 }
1877 if ( padapter->timingPIO )
1878 {
1879 insw (padapter->regData, padapter->kBuffer, padapter->readCount / 2);
1880 padapter->sectorCount -= padapter->readCount / BYTES_PER_SECTOR;
1881 WalkScatGath (padapter, TRUE, padapter->readCount);
1882 if ( !padapter->sectorCount )
1883 {
1884 status = 0;
1885 break;
1886 }
1887 }
1888 else
1889 {
1890 if ( padapter->readCount )
1891 WalkScatGath (padapter, TRUE, padapter->readCount);
1892 BusMaster (padapter, 1, 1);
1893 }
1894 padapter->expectingIRQ = TRUE;
1895 goto irq_return;
1896 }
1897 if ( padapter->readCount && !padapter->timingPIO )
1898 WalkScatGath (padapter, TRUE, padapter->readCount);
1899 status = 0;
1900 break;
1901
1902 case WRITE_CMD:
1903 if ( pdev->raid )
1904 {
1905 SelectSpigot (padapter, pdev->spigots[0] | SEL_IRQ_OFF);
1906 status = inb_p (padapter->regStatCmd); // read the device status
1907 SelectSpigot (padapter, pdev->spigots[1] | SEL_IRQ_OFF);
1908 status1 = inb_p (padapter->regStatCmd); // read the device status
1909 }
1910 else
1911 SelectSpigot (padapter, pdev->spigot | SEL_IRQ_OFF);
1912 status = inb_p (padapter->regStatCmd); // read the device status
1913 status1 = 0;
1914
1915 if ( status & (IDE_STATUS_ERROR | IDE_STATUS_WRITE_FAULT) )
1916 {
1917 if ( pdev->raid && !(status1 & (IDE_STATUS_ERROR | IDE_STATUS_WRITE_FAULT)) )
1918 {
1919 padapter->survivor = 1;
1920 del_timer (&padapter->timer);
1921 SelectSpigot (padapter, pdev->spigot | SEL_IRQ_OFF);
1922 DEB (printk ("\npci2220i: FAILURE 16 status = %X error = %X", status, inb_p (padapter->regError)));
1923 if ( !InitFailover (padapter, pdev) )
1924 goto irq_return;
1925 }
1926 break;
1927 }
1928 if ( pdev->raid )
1929 {
1930 if ( status1 & (IDE_STATUS_ERROR | IDE_STATUS_WRITE_FAULT) )
1931 {
1932 padapter->survivor = 0;
1933 del_timer (&padapter->timer);
1934 DEB (printk ("\npci2220i: FAILURE 17 status = %X error = %X", status1, inb_p (padapter->regError)));
1935 if ( !InitFailover (padapter, pdev) )
1936 goto irq_return;
1937 status = status1;
1938 break;
1939 }
1940 if ( padapter->sectorCount )
1941 {
1942 status = WriteDataBoth (padapter, pdev);
1943 if ( status )
1944 {
1945 padapter->survivor = status >> 1;
1946 del_timer (&padapter->timer);
1947 DEB (printk ("\npci2220i: FAILURE 18"));
1948 if ( !InitFailover (padapter, pdev) )
1949 goto irq_return;
1950 SelectSpigot (padapter, pdev->spigots[status] | SEL_IRQ_OFF);
1951 status = inb_p (padapter->regStatCmd); // read the device status
1952 break;
1953 }
1954 padapter->expectingIRQ = TRUE;
1955 goto irq_return;
1956 }
1957 status = 0;
1958 break;
1959 }
1960 if ( padapter->sectorCount )
1961 {
1962 SelectSpigot (padapter, pdev->spigot | padapter->bigD);
1963 status = WriteData (padapter);
1964 if ( status )
1965 break;
1966 padapter->expectingIRQ = TRUE;
1967 goto irq_return;
1968 }
1969 status = 0;
1970 break;
1971
1972 case IDE_COMMAND_IDENTIFY:
1973 {
1974 PINQUIRYDATA pinquiryData = SCpnt->request_buffer;
1975 PIDENTIFY_DATA pid = (PIDENTIFY_DATA)padapter->kBuffer;
1976
1977 status = inb_p (padapter->regStatCmd);
1978 if ( status & IDE_STATUS_DRQ )
1979 {
1980 insw (padapter->regData, pid, sizeof (IDENTIFY_DATA) >> 1);
1981
1982 memset (pinquiryData, 0, SCpnt->request_bufflen); // Zero INQUIRY data structure.
1983 pinquiryData->DeviceType = 0;
1984 pinquiryData->Versions = 2;
1985 pinquiryData->AdditionalLength = 35 - 4;
1986
1987 // Fill in vendor identification fields.
1988 for ( z = 0; z < 20; z += 2 )
1989 {
1990 pinquiryData->VendorId[z] = ((UCHAR *)pid->ModelNumber)[z + 1];
1991 pinquiryData->VendorId[z + 1] = ((UCHAR *)pid->ModelNumber)[z];
1992 }
1993
1994 // Initialize unused portion of product id.
1995 for ( z = 0; z < 4; z++ )
1996 pinquiryData->ProductId[12 + z] = ' ';
1997
1998 // Move firmware revision from IDENTIFY data to
1999 // product revision in INQUIRY data.
2000 for ( z = 0; z < 4; z += 2 )
2001 {
2002 pinquiryData->ProductRevisionLevel[z] = ((UCHAR *)pid->FirmwareRevision)[z + 1];
2003 pinquiryData->ProductRevisionLevel[z + 1] = ((UCHAR *)pid->FirmwareRevision)[z];
2004 }
2005 if ( pdev == padapter->device )
2006 *((USHORT *)(&pinquiryData->VendorSpecific)) = DEVICE_DALE_1;
2007
2008 status = 0;
2009 }
2010 break;
2011 }
2012
2013 default:
2014 status = 0;
2015 break;
2016 }
2017
2018 del_timer (&padapter->timer);
2019 if ( status )
2020 {
2021 DEB (printk ("\npci2220i Interrupt handler return error"));
2022 zl = DecodeError (padapter, status);
2023 }
2024 else
2025 zl = DID_OK << 16;
2026
2027 OpDone (padapter, zl);
2028irq_return:
2029 spin_unlock_irqrestore(shost->host_lock, flags);
2030out:
2031 return IRQ_RETVAL(handled);
2032}
2033
2034/****************************************************************
2035 * Name: Pci2220i_QueueCommand
2036 *
2037 * Description: Process a queued command from the SCSI manager.
2038 *
2039 * Parameters: SCpnt - Pointer to SCSI command structure.
2040 * done - Pointer to done function to call.
2041 *
2042 * Returns: Status code.
2043 *
2044 ****************************************************************/
2045int Pci2220i_QueueCommand (Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
2046 {
2047 UCHAR *cdb = (UCHAR *)SCpnt->cmnd; // Pointer to SCSI CDB
2048 PADAPTER2220I padapter = HOSTDATA(SCpnt->device->host); // Pointer to adapter control structure
2049 POUR_DEVICE pdev = &padapter->device[SCpnt->device->id];// Pointer to device information
2050 UCHAR rc; // command return code
2051 int z;
2052 PDEVICE_RAID1 pdr;
2053
2054 SCpnt->scsi_done = done;
2055 padapter->SCpnt = SCpnt; // Save this command data
2056 padapter->readCount = 0;
2057
2058 if ( SCpnt->use_sg )
2059 {
2060 padapter->currentSgBuffer = ((struct scatterlist *)SCpnt->request_buffer)[0].address;
2061 padapter->currentSgCount = ((struct scatterlist *)SCpnt->request_buffer)[0].length;
2062 }
2063 else
2064 {
2065 padapter->currentSgBuffer = SCpnt->request_buffer;
2066 padapter->currentSgCount = SCpnt->request_bufflen;
2067 }
2068 padapter->nextSg = 1;
2069
2070 if ( !done )
2071 {
2072 printk("pci2220i_queuecommand: %02X: done can't be NULL\n", *cdb);
2073 return 0;
2074 }
2075
2076 if ( padapter->atapi )
2077 {
2078 UCHAR zlo, zhi;
2079
2080 DEB (printk ("\nPCI2242I: ID %d, LUN %d opcode %X ", SCpnt->device->id, SCpnt->device->lun, *cdb));
2081 padapter->pdev = pdev;
2082 if ( !pdev->byte6 || SCpnt->device->lun )
2083 {
2084 OpDone (padapter, DID_BAD_TARGET << 16);
2085 return 0;
2086 }
2087
2088 padapter->atapiSpecial = FALSE;
2089 padapter->reqSense = FALSE;
2090 memset (padapter->atapiCdb, 0, 16);
2091 SelectSpigot (padapter, pdev->spigot); // select the spigot
2092 AtapiDevice (padapter, pdev->byte6); // select the drive
2093 if ( AtapiWaitReady (padapter, 100) )
2094 {
2095 OpDone (padapter, DID_NO_CONNECT << 16);
2096 return 0;
2097 }
2098
2099 switch ( cdb[0] )
2100 {
2101 case SCSIOP_MODE_SENSE:
2102 case SCSIOP_MODE_SELECT:
2103 Scsi2Atapi (padapter, SCpnt);
2104 z = SCpnt->request_bufflen + 4;
2105 break;
2106 case SCSIOP_READ6:
2107 case SCSIOP_WRITE6:
2108 Scsi2Atapi (padapter, SCpnt);
2109 z = SCpnt->request_bufflen;
2110 break;
2111 default:
2112 memcpy (padapter->atapiCdb, cdb, SCpnt->cmd_len);
2113 z = SCpnt->request_bufflen;
2114 break;
2115 }
2116 if ( z > ATAPI_TRANSFER )
2117 z = ATAPI_TRANSFER;
2118 zlo = (UCHAR)(z & 0xFF);
2119 zhi = (UCHAR)(z >> 8);
2120
2121 AtapiCountLo (padapter, zlo);
2122 AtapiCountHi (padapter, zhi);
2123 outb_p (0, padapter->regError);
2124 WriteCommand (padapter, IDE_COMMAND_ATAPI_PACKET);
2125 if ( pdev->cmdDrqInt )
2126 return 0;
2127
2128 if ( AtapiWaitDrq (padapter, 500) )
2129 {
2130 OpDone (padapter, DID_ERROR << 16);
2131 return 0;
2132 }
2133 AtapiSendCdb (padapter, pdev, padapter->atapiCdb);
2134 return 0;
2135 }
2136
2137 if ( padapter->reconPhase )
2138 return 0;
2139 if ( padapter->reconTimer.data )
2140 {
2141 del_timer (&padapter->reconTimer);
2142 padapter->reconTimer.data = 0;
2143 }
2144
2145 if ( (SCpnt->device->id >= padapter->numberOfDrives) || SCpnt->device->lun )
2146 {
2147 OpDone (padapter, DID_BAD_TARGET << 16);
2148 return 0;
2149 }
2150
2151 switch ( *cdb )
2152 {
2153 case SCSIOP_INQUIRY: // inquiry CDB
2154 {
2155 if ( cdb[2] == SC_MY_RAID )
2156 {
2157 switch ( cdb[3] )
2158 {
2159 case MY_SCSI_REBUILD:
2160 for ( z = 0; z < padapter->numberOfDrives; z++ )
2161 {
2162 pdev = &padapter->device[z];
2163 if ( ((pdev->DiskMirror[0].status & UCBF_SURVIVOR) && (pdev->DiskMirror[1].status & UCBF_MIRRORED)) ||
2164 ((pdev->DiskMirror[1].status & UCBF_SURVIVOR) && (pdev->DiskMirror[0].status & UCBF_MIRRORED)) )
2165 {
2166 padapter->reconOn = pdev->reconOn = pdev->reconIsStarting = TRUE;
2167 }
2168 }
2169 OpDone (padapter, DID_OK << 16);
2170 break;
2171 case MY_SCSI_ALARMMUTE:
2172 MuteAlarm (padapter);
2173 OpDone (padapter, DID_OK << 16);
2174 break;
2175 case MY_SCSI_DEMOFAIL:
2176 padapter->demoFail = TRUE;
2177 OpDone (padapter, DID_OK << 16);
2178 break;
2179 default:
2180 z = cdb[5]; // get index
2181 pdr = (PDEVICE_RAID1)SCpnt->request_buffer;
2182 if ( padapter->raidData[z] )
2183 {
2184 memcpy (&pdr->DiskRaid1, padapter->raidData[z], sizeof (DISK_MIRROR));
2185 if ( padapter->raidData[z]->reconstructPoint > padapter->raidData[z ^ 2]->reconstructPoint )
2186 pdr->TotalSectors = padapter->raidData[z]->reconstructPoint;
2187 else
2188 pdr->TotalSectors = padapter->raidData[z ^ 2]->reconstructPoint;
2189 }
2190 else
2191 memset (pdr, 0, sizeof (DEVICE_RAID1));
2192 OpDone (padapter, DID_OK << 16);
2193 break;
2194 }
2195 return 0;
2196 }
2197 padapter->cmd = IDE_COMMAND_IDENTIFY;
2198 break;
2199 }
2200
2201 case SCSIOP_TEST_UNIT_READY: // test unit ready CDB
2202 OpDone (padapter, DID_OK << 16);
2203 return 0;
2204 case SCSIOP_READ_CAPACITY: // read capctiy CDB
2205 {
2206 PREAD_CAPACITY_DATA pdata = (PREAD_CAPACITY_DATA)SCpnt->request_buffer;
2207
2208 pdata->blksiz = 0x20000;
2209 XANY2SCSI ((UCHAR *)&pdata->blks, pdev->blocks);
2210 OpDone (padapter, DID_OK << 16);
2211 return 0;
2212 }
2213 case SCSIOP_VERIFY: // verify CDB
2214 padapter->startSector = XSCSI2LONG (&cdb[2]);
2215 padapter->sectorCount = (UCHAR)((USHORT)cdb[8] | ((USHORT)cdb[7] << 8));
2216 padapter->cmd = IDE_COMMAND_VERIFY;
2217 break;
2218 case SCSIOP_READ: // read10 CDB
2219 padapter->startSector = XSCSI2LONG (&cdb[2]);
2220 padapter->sectorCount = (USHORT)cdb[8] | ((USHORT)cdb[7] << 8);
2221 padapter->cmd = READ_CMD;
2222 break;
2223 case SCSIOP_READ6: // read6 CDB
2224 padapter->startSector = SCSI2LONG (&cdb[1]);
2225 padapter->sectorCount = cdb[4];
2226 padapter->cmd = READ_CMD;
2227 break;
2228 case SCSIOP_WRITE: // write10 CDB
2229 padapter->startSector = XSCSI2LONG (&cdb[2]);
2230 padapter->sectorCount = (USHORT)cdb[8] | ((USHORT)cdb[7] << 8);
2231 padapter->cmd = WRITE_CMD;
2232 break;
2233 case SCSIOP_WRITE6: // write6 CDB
2234 padapter->startSector = SCSI2LONG (&cdb[1]);
2235 padapter->sectorCount = cdb[4];
2236 padapter->cmd = WRITE_CMD;
2237 break;
2238 default:
2239 DEB (printk ("pci2220i_queuecommand: Unsupported command %02X\n", *cdb));
2240 OpDone (padapter, DID_ERROR << 16);
2241 return 0;
2242 }
2243
2244 if ( padapter->reconPhase )
2245 return 0;
2246
2247 padapter->pdev = pdev;
2248
2249 while ( padapter->demoFail )
2250 {
2251 pdev = padapter->pdev = &padapter->device[0];
2252 padapter->demoFail = FALSE;
2253 if ( !pdev->raid ||
2254 (pdev->DiskMirror[0].status & UCBF_SURVIVOR) ||
2255 (pdev->DiskMirror[1].status & UCBF_SURVIVOR) )
2256 {
2257 break;
2258 }
2259 if ( pdev->DiskMirror[0].status & UCBF_REBUILD )
2260 padapter->survivor = 1;
2261 else
2262 padapter->survivor = 0;
2263 DEB (printk ("\npci2220i: FAILURE 19"));
2264 if ( InitFailover (padapter, pdev) )
2265 break;
2266 return 0;
2267 }
2268
2269 StartTimer (padapter);
2270 if ( pdev->raid && (padapter->cmd == WRITE_CMD) )
2271 {
2272 rc = IdeCmdBoth (padapter, pdev);
2273 if ( !rc )
2274 rc = WriteDataBoth (padapter, pdev);
2275 if ( rc )
2276 {
2277 del_timer (&padapter->timer);
2278 padapter->expectingIRQ = 0;
2279 padapter->survivor = rc >> 1;
2280 DEB (printk ("\npci2220i: FAILURE 20"));
2281 if ( InitFailover (padapter, pdev) )
2282 {
2283 OpDone (padapter, DID_ERROR << 16);
2284 return 0;
2285 }
2286 }
2287 }
2288 else
2289 {
2290 rc = IdeCmd (padapter, pdev);
2291 if ( (padapter->cmd == WRITE_CMD) && !rc )
2292 rc = WriteData (padapter);
2293 if ( rc )
2294 {
2295 del_timer (&padapter->timer);
2296 padapter->expectingIRQ = 0;
2297 if ( pdev->raid )
2298 {
2299 padapter->survivor = (pdev->spigot ^ 3) >> 1;
2300 DEB (printk ("\npci2220i: FAILURE 21"));
2301 if ( !InitFailover (padapter, pdev) )
2302 return 0;
2303 }
2304 OpDone (padapter, DID_ERROR << 16);
2305 return 0;
2306 }
2307 }
2308 return 0;
2309 }
2310/****************************************************************
2311 * Name: ReadFlash
2312 *
2313 * Description: Read information from controller Flash memory.
2314 *
2315 * Parameters: padapter - Pointer to host interface data structure.
2316 * pdata - Pointer to data structures.
2317 * base - base address in Flash.
2318 * length - lenght of data space in bytes.
2319 *
2320 * Returns: Nothing.
2321 *
2322 ****************************************************************/
2323static VOID ReadFlash (PADAPTER2220I padapter, VOID *pdata, ULONG base, ULONG length)
2324 {
2325 ULONG oldremap;
2326 UCHAR olddesc;
2327 ULONG z;
2328 UCHAR *pd = (UCHAR *)pdata;
2329
2330 oldremap = inl (padapter->regRemap); // save values to restore later
2331 olddesc = inb_p (padapter->regDesc);
2332
2333 outl (base | 1, padapter->regRemap); // remap to Flash space as specified
2334 outb_p (0x40, padapter->regDesc); // describe remap region as 8 bit
2335 for ( z = 0; z < length; z++) // get "length" data count
2336 *pd++ = inb_p (padapter->regBase + z); // read in the data
2337
2338 outl (oldremap, padapter->regRemap); // restore remap register values
2339 outb_p (olddesc, padapter->regDesc);
2340 }
2341/****************************************************************
2342 * Name: GetRegs
2343 *
2344 * Description: Initialize the regester information.
2345 *
2346 * Parameters: pshost - Pointer to SCSI host data structure.
2347 * bigd - PCI-2240I identifier
2348 * pcidev - Pointer to device data structure.
2349 *
2350 * Returns: TRUE if failure to install.
2351 *
2352 ****************************************************************/
2353static USHORT GetRegs (struct Scsi_Host *pshost, BOOL bigd, struct pci_dev *pcidev)
2354 {
2355 PADAPTER2220I padapter;
2356 int setirq;
2357 int z;
2358 USHORT zr, zl;
2359 UCHAR *consistent;
2360 dma_addr_t consistentDma;
2361
2362 padapter = HOSTDATA(pshost);
2363 memset (padapter, 0, sizeof (ADAPTER2220I));
2364 memset (&DaleSetup, 0, sizeof (DaleSetup));
2365 memset (DiskMirror, 0, sizeof (DiskMirror));
2366
2367 zr = pci_resource_start (pcidev, 1);
2368 zl = pci_resource_start (pcidev, 2);
2369
2370 padapter->basePort = zr;
2371 padapter->regRemap = zr + RTR_LOCAL_REMAP; // 32 bit local space remap
2372 padapter->regDesc = zr + RTR_REGIONS; // 32 bit local region descriptor
2373 padapter->regRange = zr + RTR_LOCAL_RANGE; // 32 bit local range
2374 padapter->regIrqControl = zr + RTR_INT_CONTROL_STATUS; // 16 bit interrupt control and status
2375 padapter->regScratchPad = zr + RTR_MAILBOX; // 16 byte scratchpad I/O base address
2376
2377 padapter->regBase = zl;
2378 padapter->regData = zl + REG_DATA; // data register I/O address
2379 padapter->regError = zl + REG_ERROR; // error register I/O address
2380 padapter->regSectCount = zl + REG_SECTOR_COUNT; // sector count register I/O address
2381 padapter->regLba0 = zl + REG_LBA_0; // least significant byte of LBA
2382 padapter->regLba8 = zl + REG_LBA_8; // next least significant byte of LBA
2383 padapter->regLba16 = zl + REG_LBA_16; // next most significan byte of LBA
2384 padapter->regLba24 = zl + REG_LBA_24; // head and most 4 significant bits of LBA
2385 padapter->regStatCmd = zl + REG_STAT_CMD; // status on read and command on write register
2386 padapter->regStatSel = zl + REG_STAT_SEL; // board status on read and spigot select on write register
2387 padapter->regFail = zl + REG_FAIL;
2388 padapter->regAltStat = zl + REG_ALT_STAT;
2389 padapter->pcidev = pcidev;
2390
2391 if ( bigd )
2392 {
2393 padapter->regDmaDesc = zr + RTR_DMA0_DESC_PTR; // address of the DMA discriptor register for direction of transfer
2394 padapter->regDmaCmdStat = zr + RTR_DMA_COMMAND_STATUS; // Byte #0 of DMA command status register
2395 padapter->regDmaAddrPci = zr + RTR_DMA0_PCI_ADDR; // 32 bit register for PCI address of DMA
2396 padapter->regDmaAddrLoc = zr + RTR_DMA0_LOCAL_ADDR; // 32 bit register for local bus address of DMA
2397 padapter->regDmaCount = zr + RTR_DMA0_COUNT; // 32 bit register for DMA transfer count
2398 padapter->regDmaMode = zr + RTR_DMA0_MODE + 1; // 32 bit register for DMA mode control
2399 padapter->bigD = SEL_NEW_SPEED_1; // set spigot speed control bit
2400 }
2401 else
2402 {
2403 padapter->regDmaDesc = zl + RTL_DMA1_DESC_PTR; // address of the DMA discriptor register for direction of transfer
2404 padapter->regDmaCmdStat = zl + RTL_DMA_COMMAND_STATUS + 1; // Byte #1 of DMA command status register
2405 padapter->regDmaAddrPci = zl + RTL_DMA1_PCI_ADDR; // 32 bit register for PCI address of DMA
2406 padapter->regDmaAddrLoc = zl + RTL_DMA1_LOCAL_ADDR; // 32 bit register for local bus address of DMA
2407 padapter->regDmaCount = zl + RTL_DMA1_COUNT; // 32 bit register for DMA transfer count
2408 padapter->regDmaMode = zl + RTL_DMA1_MODE + 1; // 32 bit register for DMA mode control
2409 }
2410
2411 padapter->numberOfDrives = inb_p (padapter->regScratchPad + BIGD_NUM_DRIVES);
2412 if ( !bigd && !padapter->numberOfDrives ) // if no devices on this board
2413 return TRUE;
2414
2415 pshost->irq = pcidev->irq;
2416 setirq = 1;
2417 for ( z = 0; z < Installed; z++ ) // scan for shared interrupts
2418 {
2419 if ( PsiHost[z]->irq == pshost->irq ) // if shared then, don't posses
2420 setirq = 0;
2421 }
2422 if ( setirq ) // if not shared, posses
2423 {
2424 if ( request_irq (pshost->irq, Irq_Handler, SA_SHIRQ, "pci2220i", padapter) < 0 )
2425 {
2426 if ( request_irq (pshost->irq, Irq_Handler, SA_INTERRUPT | SA_SHIRQ, "pci2220i", padapter) < 0 )
2427 {
2428 printk ("Unable to allocate IRQ for PCI-2220I controller.\n");
2429 return TRUE;
2430 }
2431 }
2432 padapter->irqOwned = pshost->irq; // set IRQ as owned
2433 }
2434
2435 if ( padapter->numberOfDrives )
2436 consistent = pci_alloc_consistent (pcidev, SECTORSXFER * BYTES_PER_SECTOR, &consistentDma);
2437 else
2438 consistent = pci_alloc_consistent (pcidev, ATAPI_TRANSFER, &consistentDma);
2439 if ( !consistent )
2440 {
2441 printk ("Unable to allocate DMA buffer for PCI-2220I controller.\n");
2442 free_irq (pshost->irq, padapter);
2443 return TRUE;
2444 }
2445 padapter->kBuffer = consistent;
2446 padapter->kBufferDma = consistentDma;
2447
2448 PsiHost[Installed] = pshost; // save SCSI_HOST pointer
2449 pshost->io_port = padapter->basePort;
2450 pshost->n_io_port = 0xFF;
2451 pshost->unique_id = padapter->regBase;
2452
2453 outb_p (0x01, padapter->regRange); // fix our range register because other drivers want to tromp on it
2454
2455 padapter->timingMode = inb_p (padapter->regScratchPad + DALE_TIMING_MODE);
2456 if ( padapter->timingMode >= 2 )
2457 {
2458 if ( bigd )
2459 padapter->timingAddress = ModeArray2[padapter->timingMode - 2];
2460 else
2461 padapter->timingAddress = ModeArray[padapter->timingMode - 2];
2462 }
2463 else
2464 padapter->timingPIO = TRUE;
2465
2466 ReadFlash (padapter, &DaleSetup, DALE_FLASH_SETUP, sizeof (SETUP));
2467 ReadFlash (padapter, &DiskMirror, DALE_FLASH_RAID, sizeof (DiskMirror));
2468
2469 return FALSE;
2470 }
2471/****************************************************************
2472 * Name: SetupFinish
2473 *
2474 * Description: Complete the driver initialization process for a card
2475 *
2476 * Parameters: padapter - Pointer to SCSI host data structure.
2477 * str - Pointer to board type string.
2478 *
2479 * Returns: Nothing.
2480 *
2481 ****************************************************************/
2482VOID SetupFinish (PADAPTER2220I padapter, char *str, int irq)
2483 {
2484 init_timer (&padapter->timer);
2485 padapter->timer.function = TimerExpiry;
2486 padapter->timer.data = (unsigned long)padapter;
2487 init_timer (&padapter->reconTimer);
2488 padapter->reconTimer.function = ReconTimerExpiry;
2489 padapter->reconTimer.data = (unsigned long)padapter;
2490 printk("\nPCI-%sI EIDE CONTROLLER: at I/O = %lX/%lX IRQ = %d\n", str, padapter->basePort, padapter->regBase, irq);
2491 printk("Version %s, Compiled %s %s\n\n", PCI2220I_VERSION, __DATE__, __TIME__);
2492 }
2493/****************************************************************
2494 * Name: Pci2220i_Detect
2495 *
2496 * Description: Detect and initialize our boards.
2497 *
2498 * Parameters: tpnt - Pointer to SCSI host template structure.
2499 *
2500 * Returns: Number of adapters installed.
2501 *
2502 ****************************************************************/
2503int Pci2220i_Detect (Scsi_Host_Template *tpnt)
2504 {
2505 struct Scsi_Host *pshost;
2506 PADAPTER2220I padapter;
2507 POUR_DEVICE pdev;
2508 int unit;
2509 int z;
2510 USHORT raidon;
2511 UCHAR spigot1, spigot2;
2512 UCHAR device;
2513 struct pci_dev *pcidev = NULL;
2514
2515 while ( (pcidev = pci_find_device (VENDOR_PSI, DEVICE_DALE_1, pcidev)) != NULL )
2516 {
2517 if (pci_enable_device(pcidev))
2518 continue;
2519 pshost = scsi_register (tpnt, sizeof(ADAPTER2220I));
2520 if(pshost==NULL)
2521 continue;
2522
2523 padapter = HOSTDATA(pshost);
2524
2525 if ( GetRegs (pshost, FALSE, pcidev) )
2526 goto unregister;
2527
2528 scsi_set_device(pshost, &pcidev->dev);
2529 pshost->max_id = padapter->numberOfDrives;
2530 for ( z = 0; z < padapter->numberOfDrives; z++ )
2531 {
2532 unit = inb_p (padapter->regScratchPad + DALE_CHANNEL_DEVICE_0 + z) & 0x0F;
2533 pdev = &padapter->device[z];
2534 pdev->byte6 = (UCHAR)(((unit & 1) << 4) | 0xE0);
2535 pdev->spigot = (UCHAR)(1 << (unit >> 1));
2536 pdev->sectors = DaleSetup.setupDevice[unit].sectors;
2537 pdev->heads = DaleSetup.setupDevice[unit].heads;
2538 pdev->cylinders = DaleSetup.setupDevice[unit].cylinders;
2539 pdev->blocks = DaleSetup.setupDevice[unit].blocks;
2540
2541 if ( !z )
2542 {
2543 DiskMirror[0].status = inb_p (padapter->regScratchPad + DALE_RAID_0_STATUS);
2544 DiskMirror[1].status = inb_p (padapter->regScratchPad + DALE_RAID_1_STATUS);
2545 if ( (DiskMirror[0].signature == SIGNATURE) && (DiskMirror[1].signature == SIGNATURE) &&
2546 (DiskMirror[0].pairIdentifier == (DiskMirror[1].pairIdentifier ^ 1)) )
2547 {
2548 raidon = TRUE;
2549 if ( unit > (unit ^ 2) )
2550 unit = unit ^ 2;
2551 }
2552 else
2553 raidon = FALSE;
2554
2555 memcpy (pdev->DiskMirror, DiskMirror, sizeof (DiskMirror));
2556 padapter->raidData[0] = &pdev->DiskMirror[0];
2557 padapter->raidData[2] = &pdev->DiskMirror[1];
2558
2559 spigot1 = spigot2 = FALSE;
2560 pdev->spigots[0] = 1;
2561 pdev->spigots[1] = 2;
2562 pdev->lastsectorlba[0] = InlineIdentify (padapter, 1, 0);
2563 pdev->lastsectorlba[1] = InlineIdentify (padapter, 2, 0);
2564
2565 if ( !(pdev->DiskMirror[1].status & UCBF_SURVIVOR) && pdev->lastsectorlba[0] )
2566 spigot1 = TRUE;
2567 if ( !(pdev->DiskMirror[0].status & UCBF_SURVIVOR) && pdev->lastsectorlba[1] )
2568 spigot2 = TRUE;
2569 if ( pdev->DiskMirror[0].status & DiskMirror[1].status & UCBF_SURVIVOR )
2570 spigot1 = TRUE;
2571
2572 if ( spigot1 && (pdev->DiskMirror[0].status & UCBF_REBUILD) )
2573 InlineReadSignature (padapter, pdev, 0);
2574 if ( spigot2 && (pdev->DiskMirror[1].status & UCBF_REBUILD) )
2575 InlineReadSignature (padapter, pdev, 1);
2576
2577 if ( spigot1 && spigot2 && raidon )
2578 {
2579 pdev->raid = 1;
2580 if ( pdev->DiskMirror[0].status & UCBF_REBUILD )
2581 pdev->spigot = 2;
2582 else
2583 pdev->spigot = 1;
2584 if ( (pdev->DiskMirror[0].status & UCBF_REBUILD) || (pdev->DiskMirror[1].status & UCBF_REBUILD) )
2585 padapter->reconOn = pdev->reconOn = pdev->reconIsStarting = TRUE;
2586 }
2587 else
2588 {
2589 if ( spigot1 )
2590 {
2591 if ( pdev->DiskMirror[0].status & UCBF_REBUILD )
2592 goto unregister;
2593 pdev->DiskMirror[0].status = UCBF_MIRRORED | UCBF_SURVIVOR;
2594 pdev->spigot = 1;
2595 }
2596 else
2597 {
2598 if ( pdev->DiskMirror[1].status & UCBF_REBUILD )
2599 goto unregister;
2600 pdev->DiskMirror[1].status = UCBF_MIRRORED | UCBF_SURVIVOR;
2601 pdev->spigot = 2;
2602 }
2603 if ( DaleSetup.rebootRebuild && raidon )
2604 padapter->reconOn = pdev->reconOn = pdev->reconIsStarting = TRUE;
2605 }
2606
2607 if ( raidon )
2608 break;
2609 }
2610 }
2611
2612 SetupFinish (padapter, "2220", pshost->irq);
2613
2614 if ( ++Installed < MAXADAPTER )
2615 continue;
2616 break;
2617unregister:;
2618 scsi_unregister (pshost);
2619 }
2620
2621 while ( (pcidev = pci_find_device (VENDOR_PSI, DEVICE_BIGD_1, pcidev)) != NULL )
2622 {
2623 pshost = scsi_register (tpnt, sizeof(ADAPTER2220I));
2624 padapter = HOSTDATA(pshost);
2625
2626 if ( GetRegs (pshost, TRUE, pcidev) )
2627 goto unregister1;
2628
2629 for ( z = 0; z < BIGD_MAXDRIVES; z++ )
2630 DiskMirror[z].status = inb_p (padapter->regScratchPad + BIGD_RAID_0_STATUS + z);
2631
2632 scsi_set_pci_device(pshost, pcidev);
2633 pshost->max_id = padapter->numberOfDrives;
2634 padapter->failRegister = inb_p (padapter->regScratchPad + BIGD_ALARM_IMAGE);
2635 for ( z = 0; z < padapter->numberOfDrives; z++ )
2636 {
2637 unit = inb_p (padapter->regScratchPad + BIGD_DEVICE_0 + z);
2638 pdev = &padapter->device[z];
2639 pdev->byte6 = (UCHAR)(((unit & 1) << 4) | 0xE0);
2640 pdev->spigot = (UCHAR)(1 << (unit >> 1));
2641 pdev->sectors = DaleSetup.setupDevice[unit].sectors;
2642 pdev->heads = DaleSetup.setupDevice[unit].heads;
2643 pdev->cylinders = DaleSetup.setupDevice[unit].cylinders;
2644 pdev->blocks = DaleSetup.setupDevice[unit].blocks;
2645
2646 if ( (DiskMirror[unit].signature == SIGNATURE) && (DiskMirror[unit ^ 2].signature == SIGNATURE) &&
2647 (DiskMirror[unit].pairIdentifier == (DiskMirror[unit ^ 2].pairIdentifier ^ 1)) )
2648 {
2649 raidon = TRUE;
2650 if ( unit > (unit ^ 2) )
2651 unit = unit ^ 2;
2652 }
2653 else
2654 raidon = FALSE;
2655
2656 spigot1 = spigot2 = FALSE;
2657 memcpy (&pdev->DiskMirror[0], &DiskMirror[unit], sizeof (DISK_MIRROR));
2658 memcpy (&pdev->DiskMirror[1], &DiskMirror[unit ^ 2], sizeof (DISK_MIRROR));
2659 padapter->raidData[unit] = &pdev->DiskMirror[0];
2660 padapter->raidData[unit ^ 2] = &pdev->DiskMirror[1];
2661 pdev->spigots[0] = 1 << (unit >> 1);
2662 pdev->spigots[1] = 1 << ((unit ^ 2) >> 1);
2663 pdev->deviceID[0] = unit;
2664 pdev->deviceID[1] = unit ^ 2;
2665 pdev->lastsectorlba[0] = InlineIdentify (padapter, pdev->spigots[0], unit & 1);
2666 pdev->lastsectorlba[1] = InlineIdentify (padapter, pdev->spigots[1], unit & 1);
2667
2668 if ( !(pdev->DiskMirror[1].status & UCBF_SURVIVOR) && pdev->lastsectorlba[0] )
2669 spigot1 = TRUE;
2670 if ( !(pdev->DiskMirror[0].status & UCBF_SURVIVOR) && pdev->lastsectorlba[1] )
2671 spigot2 = TRUE;
2672 if ( pdev->DiskMirror[0].status & pdev->DiskMirror[1].status & UCBF_SURVIVOR )
2673 spigot1 = TRUE;
2674
2675 if ( spigot1 && (pdev->DiskMirror[0].status & UCBF_REBUILD) )
2676 InlineReadSignature (padapter, pdev, 0);
2677 if ( spigot2 && (pdev->DiskMirror[1].status & UCBF_REBUILD) )
2678 InlineReadSignature (padapter, pdev, 1);
2679
2680 if ( spigot1 && spigot2 && raidon )
2681 {
2682 pdev->raid = 1;
2683 if ( pdev->DiskMirror[0].status & UCBF_REBUILD )
2684 pdev->spigot = pdev->spigots[1];
2685 else
2686 pdev->spigot = pdev->spigots[0];
2687 if ( (pdev->DiskMirror[0].status & UCBF_REBUILD) || (pdev->DiskMirror[1].status & UCBF_REBUILD) )
2688 padapter->reconOn = pdev->reconOn = pdev->reconIsStarting = TRUE;
2689 }
2690 else
2691 {
2692 if ( spigot1 )
2693 {
2694 if ( pdev->DiskMirror[0].status & UCBF_REBUILD )
2695 goto unregister1;
2696 pdev->DiskMirror[0].status = UCBF_MIRRORED | UCBF_SURVIVOR;
2697 pdev->spigot = pdev->spigots[0];
2698 }
2699 else
2700 {
2701 if ( pdev->DiskMirror[1].status & UCBF_REBUILD )
2702 goto unregister;
2703 pdev->DiskMirror[1].status = UCBF_MIRRORED | UCBF_SURVIVOR;
2704 pdev->spigot = pdev->spigots[1];
2705 }
2706 if ( DaleSetup.rebootRebuild && raidon )
2707 padapter->reconOn = pdev->reconOn = pdev->reconIsStarting = TRUE;
2708 }
2709 }
2710
2711 if ( !padapter->numberOfDrives ) // If no ATA devices then scan ATAPI
2712 {
2713 unit = 0;
2714 for ( spigot1 = 0; spigot1 < 4; spigot1++ )
2715 {
2716 for ( device = 0; device < 2; device++ )
2717 {
2718 DEB (printk ("\nPCI2242I: scanning for ID %d ", (spigot1 * 2) + device));
2719 pdev = &(padapter->device[(spigot1 * 2) + device]);
2720 pdev->byte6 = 0x0A | (device << 4);
2721 pdev->spigot = 1 << spigot1;
2722 if ( !AtapiReset (padapter, pdev) )
2723 {
2724 DEB (printk (" Device found "));
2725 if ( !AtapiIdentify (padapter, pdev) )
2726 {
2727 DEB (printk (" Device verified"));
2728 unit++;
2729 continue;
2730 }
2731 }
2732 pdev->spigot = pdev->byte6 = 0;
2733 }
2734 }
2735
2736 if ( unit )
2737 {
2738 padapter->atapi = TRUE;
2739 padapter->timingAddress = DALE_DATA_MODE3;
2740 outw_p (0x0900, padapter->regIrqControl); // Turn our interrupts on
2741 outw_p (0x0C41, padapter->regDmaMode - 1); // setup for 16 bits, ready enabled, done IRQ enabled, no incriment
2742 outb_p (0xFF, padapter->regFail); // all fail lights and alarm off
2743 pshost->max_id = 8;
2744 }
2745 }
2746 SetupFinish (padapter, "2240", pshost->irq);
2747
2748 if ( ++Installed < MAXADAPTER )
2749 continue;
2750 break;
2751unregister1:;
2752 scsi_unregister (pshost);
2753 }
2754
2755 NumAdapters = Installed;
2756 return Installed;
2757 }
2758/****************************************************************
2759 * Name: Pci2220i_Abort
2760 *
2761 * Description: Process the Abort command from the SCSI manager.
2762 *
2763 * Parameters: SCpnt - Pointer to SCSI command structure.
2764 *
2765 * Returns: Allways snooze.
2766 *
2767 ****************************************************************/
2768int Pci2220i_Abort (Scsi_Cmnd *SCpnt)
2769 {
2770 PADAPTER2220I padapter = HOSTDATA(SCpnt->device->host); // Pointer to adapter control structure
2771 POUR_DEVICE pdev = &padapter->device[SCpnt->device->id];// Pointer to device information
2772
2773 if ( !padapter->SCpnt )
2774 return SCSI_ABORT_NOT_RUNNING;
2775
2776 if ( padapter->atapi )
2777 {
2778 if ( AtapiReset (padapter, pdev) )
2779 return SCSI_ABORT_ERROR;
2780 OpDone (padapter, DID_ABORT << 16);
2781 return SCSI_ABORT_SUCCESS;
2782 }
2783 return SCSI_ABORT_SNOOZE;
2784 }
2785/****************************************************************
2786 * Name: Pci2220i_Reset
2787 *
2788 * Description: Process the Reset command from the SCSI manager.
2789 *
2790 * Parameters: SCpnt - Pointer to SCSI command structure.
2791 * flags - Flags about the reset command
2792 *
2793 * Returns: No active command at this time, so this means
2794 * that each time we got some kind of response the
2795 * last time through. Tell the mid-level code to
2796 * request sense information in order to decide what
2797 * to do next.
2798 *
2799 ****************************************************************/
2800int Pci2220i_Reset (Scsi_Cmnd *SCpnt, unsigned int reset_flags)
2801 {
2802 PADAPTER2220I padapter = HOSTDATA(SCpnt->device->host); // Pointer to adapter control structure
2803 POUR_DEVICE pdev = &padapter->device[SCpnt->device->id];// Pointer to device information
2804
2805 if ( padapter->atapi )
2806 {
2807 if ( AtapiReset (padapter, pdev) )
2808 return SCSI_RESET_ERROR;
2809 return SCSI_RESET_SUCCESS;
2810 }
2811 return SCSI_RESET_PUNT;
2812 }
2813/****************************************************************
2814 * Name: Pci2220i_Release
2815 *
2816 * Description: Release resources allocated for a single each adapter.
2817 *
2818 * Parameters: pshost - Pointer to SCSI command structure.
2819 *
2820 * Returns: zero.
2821 *
2822 ****************************************************************/
2823int Pci2220i_Release (struct Scsi_Host *pshost)
2824 {
2825 PADAPTER2220I padapter = HOSTDATA (pshost);
2826 USHORT z;
2827
2828 if ( padapter->reconOn )
2829 {
2830 padapter->reconOn = FALSE; // shut down the hot reconstruct
2831 if ( padapter->reconPhase )
2832 mdelay (300);
2833 if ( padapter->reconTimer.data ) // is the timer running?
2834 {
2835 del_timer (&padapter->reconTimer);
2836 padapter->reconTimer.data = 0;
2837 }
2838 }
2839
2840 // save RAID status on the board
2841 if ( padapter->bigD )
2842 {
2843 outb_p (padapter->failRegister, padapter->regScratchPad + BIGD_ALARM_IMAGE);
2844 for ( z = 0; z < BIGD_MAXDRIVES; z++ )
2845 {
2846 if ( padapter->raidData )
2847 outb_p (padapter->raidData[z]->status, padapter->regScratchPad + BIGD_RAID_0_STATUS + z);
2848 else
2849 outb_p (0, padapter->regScratchPad + BIGD_RAID_0_STATUS);
2850 }
2851 }
2852 else
2853 {
2854 outb_p (padapter->device[0].DiskMirror[0].status, padapter->regScratchPad + DALE_RAID_0_STATUS);
2855 outb_p (padapter->device[0].DiskMirror[1].status, padapter->regScratchPad + DALE_RAID_1_STATUS);
2856 }
2857
2858 if ( padapter->irqOwned )
2859 free_irq (pshost->irq, padapter);
2860 release_region (pshost->io_port, pshost->n_io_port);
2861 if ( padapter->numberOfDrives )
2862 pci_free_consistent (padapter->pcidev, SECTORSXFER * BYTES_PER_SECTOR, padapter->kBuffer, padapter->kBufferDma);
2863 else
2864 pci_free_consistent (padapter->pcidev, ATAPI_TRANSFER, padapter->kBuffer, padapter->kBufferDma);
2865 scsi_unregister(pshost);
2866 return 0;
2867 }
2868
2869/****************************************************************
2870 * Name: Pci2220i_BiosParam
2871 *
2872 * Description: Process the biosparam request from the SCSI manager to
2873 * return C/H/S data.
2874 *
2875 * Parameters: disk - Pointer to SCSI disk structure.
2876 * dev - Major/minor number from kernel.
2877 * geom - Pointer to integer array to place geometry data.
2878 *
2879 * Returns: zero.
2880 *
2881 ****************************************************************/
2882int Pci2220i_BiosParam (struct scsi_device *sdev, struct block_device *dev,
2883 sector_t capacity, int geom[])
2884 {
2885 POUR_DEVICE pdev;
2886
2887 if ( !(HOSTDATA(sdev->host))->atapi )
2888 {
2889 pdev = &(HOSTDATA(sdev->host)->device[sdev->id]);
2890
2891 geom[0] = pdev->heads;
2892 geom[1] = pdev->sectors;
2893 geom[2] = pdev->cylinders;
2894 }
2895 return 0;
2896 }
2897
2898MODULE_LICENSE("Dual BSD/GPL");
2899
2900static Scsi_Host_Template driver_template = {
2901 .proc_name = "pci2220i",
2902 .name = "PCI-2220I/PCI-2240I",
2903 .detect = Pci2220i_Detect,
2904 .release = Pci2220i_Release,
2905 .queuecommand = Pci2220i_QueueCommand,
2906 .abort = Pci2220i_Abort,
2907 .reset = Pci2220i_Reset,
2908 .bios_param = Pci2220i_BiosParam,
2909 .can_queue = 1,
2910 .this_id = -1,
2911 .sg_tablesize = SG_ALL,
2912 .cmd_per_lun = 1,
2913 .use_clustering = DISABLE_CLUSTERING,
2914};
2915#include "scsi_module.c"
diff --git a/drivers/scsi/pci2220i.h b/drivers/scsi/pci2220i.h
deleted file mode 100644
index 6926056c2aee..000000000000
--- a/drivers/scsi/pci2220i.h
+++ /dev/null
@@ -1,39 +0,0 @@
1/****************************************************************************
2 * Perceptive Solutions, Inc. PCI-2220I device driver for Linux.
3 *
4 * pci2220i.h - Linux Host Driver for PCI-2220i EIDE Adapters
5 *
6 * Copyright (c) 1997-1999 Perceptive Solutions, Inc.
7 * All Rights Reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that redistributions of source
11 * code retain the above copyright notice and this comment without
12 * modification.
13 *
14 * Technical updates and product information at:
15 * http://www.psidisk.com
16 *
17 * Please send questions, comments, bug reports to:
18 * tech@psidisk.com Technical Support
19 *
20 ****************************************************************************/
21#ifndef _PCI2220I_H
22#define _PCI2220I_H
23
24#ifndef LINUX_VERSION_CODE
25#include <linux/version.h>
26#endif
27#define LINUXVERSION(v,p,s) (((v)<<16) + ((p)<<8) + (s))
28
29// function prototypes
30int Pci2220i_Detect (Scsi_Host_Template *tpnt);
31int Pci2220i_Command (Scsi_Cmnd *SCpnt);
32int Pci2220i_QueueCommand (Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *));
33int Pci2220i_Abort (Scsi_Cmnd *SCpnt);
34int Pci2220i_Reset (Scsi_Cmnd *SCpnt, unsigned int flags);
35int Pci2220i_Release (struct Scsi_Host *pshost);
36int Pci2220i_BiosParam (struct scsi_device *sdev,
37 struct block_device *dev,
38 sector_t capacity, int geom[]);
39#endif
diff --git a/drivers/scsi/psi_dale.h b/drivers/scsi/psi_dale.h
deleted file mode 100644
index d672e3b01982..000000000000
--- a/drivers/scsi/psi_dale.h
+++ /dev/null
@@ -1,564 +0,0 @@
1/****************************************************************************
2 * Perceptive Solutions, Inc. PCI-2220I device driver for Linux.
3 *
4 * psi_dalei.h - Linux Host Driver for PCI-2220i EIDE Adapters
5 *
6 * Copyright (c) 1997-1999 Perceptive Solutions, Inc.
7 * All Rights Reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that redistributions of source
11 * code retain the above copyright notice and this comment without
12 * modification.
13 *
14 * Technical updates and product information at:
15 * http://www.psidisk.com
16 *
17 * Please send questions, comments, bug reports to:
18 * tech@psidisk.com Technical Support
19 *
20 ****************************************************************************/
21
22/************************************************/
23/* Some defines that we like */
24/************************************************/
25#define CHAR char
26#define UCHAR unsigned char
27#define SHORT short
28#define USHORT unsigned short
29#define BOOL unsigned short
30#define LONG long
31#define ULONG unsigned long
32#define VOID void
33
34/************************************************/
35/* Dale PCI setup */
36/************************************************/
37#define VENDOR_PSI 0x1256
38#define DEVICE_DALE_1 0x4401 /* 'D1' */
39#define DEVICE_BIGD_1 0x4201 /* 'B1' */
40#define DEVICE_BIGD_2 0x4202 /* 'B2' */
41
42/************************************************/
43/* Misc konstants */
44/************************************************/
45#define DALE_MAXDRIVES 4
46#define BIGD_MAXDRIVES 8
47#define SECTORSXFER 8
48#define ATAPI_TRANSFER 8192
49#define BYTES_PER_SECTOR 512
50#define DEFAULT_TIMING_MODE 5
51
52/************************************************/
53/* EEPROM locations */
54/************************************************/
55#define DALE_FLASH_PAGE_SIZE 128 // number of bytes per page
56#define DALE_FLASH_SIZE 65536L
57
58#define DALE_FLASH_BIOS 0x00080000L // BIOS base address
59#define DALE_FLASH_SETUP 0x00088000L // SETUP PROGRAM base address offset from BIOS
60#define DALE_FLASH_RAID 0x00088400L // RAID signature storage
61#define DALE_FLASH_FACTORY 0x00089000L // FACTORY data base address offset from BIOS
62
63#define DALE_FLASH_BIOS_SIZE 32768U // size of FLASH BIOS REGION
64
65/************************************************/
66/* DALE Register address offsets */
67/************************************************/
68#define REG_DATA 0x80
69#define REG_ERROR 0x84
70#define REG_SECTOR_COUNT 0x88
71#define REG_LBA_0 0x8C
72#define REG_LBA_8 0x90
73#define REG_LBA_16 0x94
74#define REG_LBA_24 0x98
75#define REG_STAT_CMD 0x9C
76#define REG_STAT_SEL 0xA0
77#define REG_FAIL 0xB0
78#define REG_ALT_STAT 0xB8
79#define REG_DRIVE_ADRS 0xBC
80
81#define DALE_DATA_SLOW 0x00040000L
82#define DALE_DATA_MODE2 0x00040000L
83#define DALE_DATA_MODE3 0x00050000L
84#define DALE_DATA_MODE4 0x00060000L
85#define DALE_DATA_MODE5 0x00070000L
86
87#define BIGD_DATA_SLOW 0x00000000L
88#define BIGD_DATA_MODE0 0x00000000L
89#define BIGD_DATA_MODE2 0x00000000L
90#define BIGD_DATA_MODE3 0x00000008L
91#define BIGD_DATA_MODE4 0x00000010L
92#define BIGD_DATA_MODE5 0x00000020L
93
94#define RTR_LOCAL_RANGE 0x000
95#define RTR_LOCAL_REMAP 0x004
96#define RTR_EXP_RANGE 0x010
97#define RTR_EXP_REMAP 0x014
98#define RTR_REGIONS 0x018
99#define RTR_DM_MASK 0x01C
100#define RTR_DM_LOCAL_BASE 0x020
101#define RTR_DM_IO_BASE 0x024
102#define RTR_DM_PCI_REMAP 0x028
103#define RTR_DM_IO_CONFIG 0x02C
104#define RTR_MAILBOX 0x040
105#define RTR_LOCAL_DOORBELL 0x060
106#define RTR_PCI_DOORBELL 0x064
107#define RTR_INT_CONTROL_STATUS 0x068
108#define RTR_EEPROM_CONTROL_STATUS 0x06C
109
110#define RTR_DMA0_MODE 0x0080
111#define RTR_DMA0_PCI_ADDR 0x0084
112#define RTR_DMA0_LOCAL_ADDR 0x0088
113#define RTR_DMA0_COUNT 0x008C
114#define RTR_DMA0_DESC_PTR 0x0090
115#define RTR_DMA1_MODE 0x0094
116#define RTR_DMA1_PCI_ADDR 0x0098
117#define RTR_DMA1_LOCAL_ADDR 0x009C
118#define RTR_DMA1_COUNT 0x00A0
119#define RTR_DMA1_DESC_PTR 0x00A4
120#define RTR_DMA_COMMAND_STATUS 0x00A8
121#define RTR_DMA_ARB0 0x00AC
122#define RTR_DMA_ARB1 0x00B0
123
124#define RTL_DMA0_MODE 0x00
125#define RTL_DMA0_PCI_ADDR 0x04
126#define RTL_DMA0_LOCAL_ADDR 0x08
127#define RTL_DMA0_COUNT 0x0C
128#define RTL_DMA0_DESC_PTR 0x10
129#define RTL_DMA1_MODE 0x14
130#define RTL_DMA1_PCI_ADDR 0x18
131#define RTL_DMA1_LOCAL_ADDR 0x1C
132#define RTL_DMA1_COUNT 0x20
133#define RTL_DMA1_DESC_PTR 0x24
134#define RTL_DMA_COMMAND_STATUS 0x28
135#define RTL_DMA_ARB0 0x2C
136#define RTL_DMA_ARB1 0x30
137
138/************************************************/
139/* Dale Scratchpad locations */
140/************************************************/
141#define DALE_CHANNEL_DEVICE_0 0 // device channel locations
142#define DALE_CHANNEL_DEVICE_1 1
143#define DALE_CHANNEL_DEVICE_2 2
144#define DALE_CHANNEL_DEVICE_3 3
145
146#define DALE_SCRATCH_DEVICE_0 4 // device type codes
147#define DALE_SCRATCH_DEVICE_1 5
148#define DALE_SCRATCH_DEVICE_2 6
149#define DALE_SCRATCH_DEVICE_3 7
150
151#define DALE_RAID_0_STATUS 8
152#define DALE_RAID_1_STATUS 9
153
154#define DALE_TIMING_MODE 12 // bus master timing mode (2, 3, 4, 5)
155#define DALE_NUM_DRIVES 13 // number of addressable drives on this board
156#define DALE_RAID_ON 14 // RAID status On
157#define DALE_LAST_ERROR 15 // Last error code from BIOS
158
159/************************************************/
160/* BigD Scratchpad locations */
161/************************************************/
162#define BIGD_DEVICE_0 0 // device channel locations
163#define BIGD_DEVICE_1 1
164#define BIGD_DEVICE_2 2
165#define BIGD_DEVICE_3 3
166
167#define BIGD_DEVICE_4 4 // device type codes
168#define BIGD_DEVICE_5 5
169#define BIGD_DEVICE_6 6
170#define BIGD_DEVICE_7 7
171
172#define BIGD_ALARM_IMAGE 11 // ~image of alarm fail register
173#define BIGD_TIMING_MODE 12 // bus master timing mode (2, 3, 4, 5)
174#define BIGD_NUM_DRIVES 13 // number of addressable drives on this board
175#define BIGD_RAID_ON 14 // RAID status is on for the whole board
176#define BIGD_LAST_ERROR 15 // Last error code from BIOS
177
178#define BIGD_RAID_0_STATUS 16
179#define BIGD_RAID_1_STATUS 17
180#define BIGD_RAID_2_STATUS 18
181#define BIGD_RAID_3_STATUS 19
182#define BIGD_RAID_4_STATUS 20
183#define BIGD_RAID_5_STATUS 21
184#define BIGD_RAID_6_STATUS 22
185#define BIGD_RAID_7_STATUS 23
186
187/************************************************/
188/* Dale cable select bits */
189/************************************************/
190#define SEL_NONE 0x00
191#define SEL_1 0x01
192#define SEL_2 0x02
193#define SEL_3 0x04
194#define SEL_4 0x08
195#define SEL_NEW_SPEED_1 0x20
196#define SEL_COPY 0x40
197#define SEL_IRQ_OFF 0x80
198
199/************************************************/
200/* Device/Geometry controls */
201/************************************************/
202#define GEOMETRY_NONE 0x0 // No device
203#define GEOMETRY_SET 0x1 // Geometry set
204#define GEOMETRY_LBA 0x2 // Geometry set in default LBA mode
205#define GEOMETRY_PHOENIX 0x3 // Geometry set in Pheonix BIOS compatibility mode
206
207#define DEVICE_NONE 0x0 // No device present
208#define DEVICE_INACTIVE 0x1 // device present but not registered active
209#define DEVICE_ATAPI 0x2 // ATAPI device (CD_ROM, Tape, Etc...)
210#define DEVICE_DASD_NONLBA 0x3 // Non LBA incompatible device
211#define DEVICE_DASD_LBA 0x4 // LBA compatible device
212
213/************************************************/
214/* BigD fail register bits */
215/************************************************/
216#define FAIL_NONE 0x00
217#define FAIL_0 0x01
218#define FAIL_1 0x02
219#define FAIL_2 0x04
220#define FAIL_MULTIPLE 0x08
221#define FAIL_GOOD 0x20
222#define FAIL_AUDIBLE 0x40
223#define FAIL_ANY 0x80
224
225/************************************************/
226/* Setup Structure Definitions */
227/************************************************/
228typedef struct // device setup parameters
229 {
230 UCHAR geometryControl; // geometry control flags
231 UCHAR device; // device code
232 USHORT sectors; // number of sectors per track
233 USHORT heads; // number of heads
234 USHORT cylinders; // number of cylinders for this device
235 ULONG blocks; // number of blocks on device
236 ULONG realCapacity; // number of real blocks on this device for drive changed testing
237 } SETUP_DEVICE, *PSETUP_DEVICE;
238
239typedef struct // master setup structure
240 {
241 USHORT startupDelay;
242 BOOL promptBIOS;
243 BOOL fastFormat;
244 BOOL shareInterrupt;
245 BOOL rebootRebuild;
246 USHORT timingMode;
247 USHORT spare5;
248 USHORT spare6;
249 SETUP_DEVICE setupDevice[BIGD_MAXDRIVES];
250 } SETUP, *PSETUP;
251
252/************************************************/
253/* RAID Structure Definitions */
254/************************************************/
255typedef struct
256 {
257 UCHAR signature; // 0x55 our mirror signature
258 UCHAR status; // current status bits
259 UCHAR pairIdentifier; // unique identifier for pair
260 ULONG reconstructPoint; // recontruction point for hot reconstruct
261 } DISK_MIRROR;
262
263typedef struct DEVICE_RAID1
264 {
265 long TotalSectors;
266 DISK_MIRROR DiskRaid1;
267 } DEVICE_RAID1, *PDEVICE_RAID1;
268
269#define DISK_MIRROR_POSITION 0x01A8
270#define SIGNATURE 0x55
271
272#define MASK_SERIAL_NUMBER 0x0FFE // mask for serial number matching
273#define MASK_SERIAL_UNIT 0x0001 // mask for unit portion of serial number
274
275// Status bits
276#define UCBF_MIRRORED 0x0010 // drive has a pair
277#define UCBF_MATCHED 0x0020 // drive pair is matched
278#define UCBF_SURVIVOR 0x0040 // this unit is a survivor of a pair
279#define UCBF_REBUILD 0x0080 // rebuild in progress on this device
280
281// SCSI controls for RAID
282#define SC_MY_RAID 0xBF // our special CDB command byte for Win95... interface
283#define MY_SCSI_QUERY1 0x32 // byte 1 subcommand to query driver for RAID 1 informatation
284#define MY_SCSI_REBUILD 0x40 // byte 1 subcommand to reconstruct a mirrored pair
285#define MY_SCSI_DEMOFAIL 0x54 // byte 1 subcommand for RAID failure demonstration
286#define MY_SCSI_ALARMMUTE 0x60 // byte 1 subcommand to mute any alarm currently on
287
288/************************************************/
289/* Timeout konstants */
290/************************************************/
291#define TIMEOUT_READY 100 // 100 mSec
292#define TIMEOUT_DRQ 300 // 300 mSec
293#define TIMEOUT_DATA (3 * HZ) // 3 seconds
294
295/************************************************/
296/* Misc. macros */
297/************************************************/
298#define ANY2SCSI(up, p) \
299((UCHAR *)up)[0] = (((ULONG)(p)) >> 8); \
300((UCHAR *)up)[1] = ((ULONG)(p));
301
302#define SCSI2LONG(up) \
303( (((long)*(((UCHAR *)up))) << 16) \
304+ (((long)(((UCHAR *)up)[1])) << 8) \
305+ ((long)(((UCHAR *)up)[2])) )
306
307#define XANY2SCSI(up, p) \
308((UCHAR *)up)[0] = ((long)(p)) >> 24; \
309((UCHAR *)up)[1] = ((long)(p)) >> 16; \
310((UCHAR *)up)[2] = ((long)(p)) >> 8; \
311((UCHAR *)up)[3] = ((long)(p));
312
313#define XSCSI2LONG(up) \
314( (((long)(((UCHAR *)up)[0])) << 24) \
315+ (((long)(((UCHAR *)up)[1])) << 16) \
316+ (((long)(((UCHAR *)up)[2])) << 8) \
317+ ((long)(((UCHAR *)up)[3])) )
318
319#define SelectSpigot(padapter,spigot) outb_p (spigot, padapter->regStatSel)
320#define WriteCommand(padapter,cmd) outb_p (cmd, padapter->regStatCmd)
321#define AtapiDevice(padapter,b) outb_p (b, padapter->regLba24);
322#define AtapiCountLo(padapter,b) outb_p (b, padapter->regLba8)
323#define AtapiCountHi(padapter,b) outb_p (b, padapter->regLba16)
324
325/************************************************/
326/* SCSI CDB operation codes */
327/************************************************/
328#define SCSIOP_TEST_UNIT_READY 0x00
329#define SCSIOP_REZERO_UNIT 0x01
330#define SCSIOP_REWIND 0x01
331#define SCSIOP_REQUEST_BLOCK_ADDR 0x02
332#define SCSIOP_REQUEST_SENSE 0x03
333#define SCSIOP_FORMAT_UNIT 0x04
334#define SCSIOP_READ_BLOCK_LIMITS 0x05
335#define SCSIOP_REASSIGN_BLOCKS 0x07
336#define SCSIOP_READ6 0x08
337#define SCSIOP_RECEIVE 0x08
338#define SCSIOP_WRITE6 0x0A
339#define SCSIOP_PRINT 0x0A
340#define SCSIOP_SEND 0x0A
341#define SCSIOP_SEEK6 0x0B
342#define SCSIOP_TRACK_SELECT 0x0B
343#define SCSIOP_SLEW_PRINT 0x0B
344#define SCSIOP_SEEK_BLOCK 0x0C
345#define SCSIOP_PARTITION 0x0D
346#define SCSIOP_READ_REVERSE 0x0F
347#define SCSIOP_WRITE_FILEMARKS 0x10
348#define SCSIOP_FLUSH_BUFFER 0x10
349#define SCSIOP_SPACE 0x11
350#define SCSIOP_INQUIRY 0x12
351#define SCSIOP_VERIFY6 0x13
352#define SCSIOP_RECOVER_BUF_DATA 0x14
353#define SCSIOP_MODE_SELECT 0x15
354#define SCSIOP_RESERVE_UNIT 0x16
355#define SCSIOP_RELEASE_UNIT 0x17
356#define SCSIOP_COPY 0x18
357#define SCSIOP_ERASE 0x19
358#define SCSIOP_MODE_SENSE 0x1A
359#define SCSIOP_START_STOP_UNIT 0x1B
360#define SCSIOP_STOP_PRINT 0x1B
361#define SCSIOP_LOAD_UNLOAD 0x1B
362#define SCSIOP_RECEIVE_DIAGNOSTIC 0x1C
363#define SCSIOP_SEND_DIAGNOSTIC 0x1D
364#define SCSIOP_MEDIUM_REMOVAL 0x1E
365#define SCSIOP_READ_CAPACITY 0x25
366#define SCSIOP_READ 0x28
367#define SCSIOP_WRITE 0x2A
368#define SCSIOP_SEEK 0x2B
369#define SCSIOP_LOCATE 0x2B
370#define SCSIOP_WRITE_VERIFY 0x2E
371#define SCSIOP_VERIFY 0x2F
372#define SCSIOP_SEARCH_DATA_HIGH 0x30
373#define SCSIOP_SEARCH_DATA_EQUAL 0x31
374#define SCSIOP_SEARCH_DATA_LOW 0x32
375#define SCSIOP_SET_LIMITS 0x33
376#define SCSIOP_READ_POSITION 0x34
377#define SCSIOP_SYNCHRONIZE_CACHE 0x35
378#define SCSIOP_COMPARE 0x39
379#define SCSIOP_COPY_COMPARE 0x3A
380#define SCSIOP_WRITE_DATA_BUFF 0x3B
381#define SCSIOP_READ_DATA_BUFF 0x3C
382#define SCSIOP_CHANGE_DEFINITION 0x40
383#define SCSIOP_READ_SUB_CHANNEL 0x42
384#define SCSIOP_READ_TOC 0x43
385#define SCSIOP_READ_HEADER 0x44
386#define SCSIOP_PLAY_AUDIO 0x45
387#define SCSIOP_PLAY_AUDIO_MSF 0x47
388#define SCSIOP_PLAY_TRACK_INDEX 0x48
389#define SCSIOP_PLAY_TRACK_RELATIVE 0x49
390#define SCSIOP_PAUSE_RESUME 0x4B
391#define SCSIOP_LOG_SELECT 0x4C
392#define SCSIOP_LOG_SENSE 0x4D
393#define SCSIOP_MODE_SELECT10 0x55
394#define SCSIOP_MODE_SENSE10 0x5A
395#define SCSIOP_LOAD_UNLOAD_SLOT 0xA6
396#define SCSIOP_MECHANISM_STATUS 0xBD
397#define SCSIOP_READ_CD 0xBE
398
399// IDE command definitions
400#define IDE_COMMAND_ATAPI_RESET 0x08
401#define IDE_COMMAND_READ 0x20
402#define IDE_COMMAND_WRITE 0x30
403#define IDE_COMMAND_RECALIBRATE 0x10
404#define IDE_COMMAND_SEEK 0x70
405#define IDE_COMMAND_SET_PARAMETERS 0x91
406#define IDE_COMMAND_VERIFY 0x40
407#define IDE_COMMAND_ATAPI_PACKET 0xA0
408#define IDE_COMMAND_ATAPI_IDENTIFY 0xA1
409#define IDE_CMD_READ_MULTIPLE 0xC4
410#define IDE_CMD_WRITE_MULTIPLE 0xC5
411#define IDE_CMD_SET_MULTIPLE 0xC6
412#define IDE_COMMAND_IDENTIFY 0xEC
413
414// IDE status definitions
415#define IDE_STATUS_ERROR 0x01
416#define IDE_STATUS_INDEX 0x02
417#define IDE_STATUS_CORRECTED_ERROR 0x04
418#define IDE_STATUS_DRQ 0x08
419#define IDE_STATUS_DSC 0x10
420#define IDE_STATUS_WRITE_FAULT 0x20
421#define IDE_STATUS_DRDY 0x40
422#define IDE_STATUS_BUSY 0x80
423
424typedef struct _ATAPI_STATUS
425 {
426 CHAR check :1;
427 CHAR reserved1 :1;
428 CHAR corr :1;
429 CHAR drq :1;
430 CHAR dsc :1;
431 CHAR reserved2 :1;
432 CHAR drdy :1;
433 CHAR bsy :1;
434 } ATAPI_STATUS;
435
436typedef struct _ATAPI_REASON
437 {
438 CHAR cod :1;
439 CHAR io :1;
440 CHAR reserved1 :6;
441 } ATAPI_REASON;
442
443typedef struct _ATAPI_ERROR
444 {
445 CHAR ili :1;
446 CHAR eom :1;
447 CHAR abort :1;
448 CHAR mcr :1;
449 CHAR senseKey :4;
450 } ATAPI_ERROR;
451
452// IDE error definitions
453#define IDE_ERROR_AMNF 0x01
454#define IDE_ERROR_TKONF 0x02
455#define IDE_ERROR_ABRT 0x04
456#define IDE_ERROR_MCR 0x08
457#define IDE_ERROR_IDFN 0x10
458#define IDE_ERROR_MC 0x20
459#define IDE_ERROR_UNC 0x40
460#define IDE_ERROR_BBK 0x80
461
462// SCSI read capacity structure
463typedef struct _READ_CAPACITY_DATA
464 {
465 ULONG blks; /* total blocks (converted to little endian) */
466 ULONG blksiz; /* size of each (converted to little endian) */
467 } READ_CAPACITY_DATA, *PREAD_CAPACITY_DATA;
468
469// SCSI inquiry data
470typedef struct _INQUIRYDATA
471 {
472 UCHAR DeviceType :5;
473 UCHAR DeviceTypeQualifier :3;
474 UCHAR DeviceTypeModifier :7;
475 UCHAR RemovableMedia :1;
476 UCHAR Versions;
477 UCHAR ResponseDataFormat;
478 UCHAR AdditionalLength;
479 UCHAR Reserved[2];
480 UCHAR SoftReset :1;
481 UCHAR CommandQueue :1;
482 UCHAR Reserved2 :1;
483 UCHAR LinkedCommands :1;
484 UCHAR Synchronous :1;
485 UCHAR Wide16Bit :1;
486 UCHAR Wide32Bit :1;
487 UCHAR RelativeAddressing :1;
488 UCHAR VendorId[8];
489 UCHAR ProductId[16];
490 UCHAR ProductRevisionLevel[4];
491 UCHAR VendorSpecific[20];
492 UCHAR Reserved3[40];
493 } INQUIRYDATA, *PINQUIRYDATA;
494
495// IDE IDENTIFY data
496#pragma pack (1)
497typedef struct _IDENTIFY_DATA
498 {
499 USHORT GeneralConfiguration; // 0
500 USHORT NumberOfCylinders; // 1
501 USHORT Reserved1; // 2
502 USHORT NumberOfHeads; // 3
503 USHORT UnformattedBytesPerTrack; // 4
504 USHORT UnformattedBytesPerSector; // 5
505 USHORT SectorsPerTrack; // 6
506 USHORT NumBytesISG; // 7 Byte Len - inter-sector gap
507 USHORT NumBytesSync; // 8 - sync field
508 USHORT NumWordsVUS; // 9 Len - Vendor Unique Info
509 USHORT SerialNumber[10]; // 10
510 USHORT BufferType; // 20
511 USHORT BufferSectorSize; // 21
512 USHORT NumberOfEccBytes; // 22
513 USHORT FirmwareRevision[4]; // 23
514 USHORT ModelNumber[20]; // 27
515 USHORT NumSectorsPerInt :8; // 47 Multiple Mode - Sec/Blk
516 USHORT Reserved2 :8; // 47
517 USHORT DoubleWordMode; // 48 flag for double word mode capable
518 USHORT VendorUnique1 :8; // 49
519 USHORT SupportDMA :1; // 49 DMA supported
520 USHORT SupportLBA :1; // 49 LBA supported
521 USHORT SupportIORDYDisable :1; // 49 IORDY can be disabled
522 USHORT SupportIORDY :1; // 49 IORDY supported
523 USHORT ReservedPsuedoDMA :1; // 49 reserved for pseudo DMA mode support
524 USHORT Reserved3 :3; // 49
525 USHORT Reserved4; // 50
526 USHORT Reserved5 :8; // 51 Transfer Cycle Timing - PIO
527 USHORT PIOCycleTime :8; // 51 Transfer Cycle Timing - PIO
528 USHORT Reserved6 :8; // 52 - DMA
529 USHORT DMACycleTime :8; // 52 - DMA
530 USHORT Valid_54_58 :1; // 53 words 54 - 58 are valid
531 USHORT Valid_64_70 :1; // 53 words 64 - 70 are valid
532 USHORT Reserved7 :14; // 53
533 USHORT LogNumCyl; // 54 Current Translation - Num Cyl
534 USHORT LogNumHeads; // 55 Num Heads
535 USHORT LogSectorsPerTrack; // 56 Sec/Trk
536 ULONG LogTotalSectors; // 57 Total Sec
537 USHORT CurrentNumSecPerInt :8; // 59 current setting for number of sectors per interrupt
538 USHORT ValidNumSecPerInt :1; // 59 Current setting is valid for number of sectors per interrupt
539 USHORT Reserved8 :7; // 59
540 ULONG LBATotalSectors; // 60 LBA Mode - Sectors
541 USHORT DMASWordFlags; // 62
542 USHORT DMAMWordFlags; // 63
543 USHORT AdvancedPIOSupport :8; // 64 Flow control PIO transfer modes supported
544 USHORT Reserved9 :8; // 64
545 USHORT MinMultiDMACycle; // 65 minimum multiword DMA transfer cycle time per word
546 USHORT RecomendDMACycle; // 66 Manufacturer's recommende multiword DMA transfer cycle time
547 USHORT MinPIOCycleWithoutFlow; // 67 Minimum PIO transfer cycle time without flow control
548 USHORT MinPIOCylceWithFlow; // 68 Minimum PIO transfer cycle time with IORDY flow control
549 USHORT ReservedSpace[256-69]; // 69
550 } IDENTIFY_DATA, *PIDENTIFY_DATA;
551
552// ATAPI configuration bits
553typedef struct _ATAPI_GENERAL_0
554 {
555 USHORT CmdPacketSize :2; // Command packet size
556 USHORT Reserved1 :3;
557 USHORT CmdDrqType :2;
558 USHORT Removable :1;
559 USHORT DeviceType :5;
560 USHORT Reserved2 :1;
561 USHORT ProtocolType :2;
562 } ATAPI_GENERAL_0;
563
564#pragma pack ()
diff --git a/drivers/scsi/psi_roy.h b/drivers/scsi/psi_roy.h
deleted file mode 100644
index c55b9c04c32a..000000000000
--- a/drivers/scsi/psi_roy.h
+++ /dev/null
@@ -1,331 +0,0 @@
1/****************************************************************************
2 * Perceptive Solutions, Inc. PCI-2000 device driver for Linux.
3 *
4 * psi_roy.h - Linux Host Driver for PCI-2000 IntelliCache SCSI Adapters
5 *
6 * Copyright (c) 1997-1999 Perceptive Solutions, Inc.
7 * All Rights Reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that redistributions of source
11 * code retain the above copyright notice and this comment without
12 * modification.
13 *
14 * Technical updates and product information at:
15 * http://www.psidisk.com
16 *
17 * Please send questions, comments, bug reports to:
18 * tech@psidisk.com Technical Support
19 *
20 ****************************************************************************/
21
22#ifndef ROY_HOST
23#define ROY_HOST
24
25/************************************************/
26/* PCI setup */
27/************************************************/
28#define VENDOR_PSI 0x1256
29#define DEVICE_ROY_1 0x5201 /* 'R1' */
30
31/************************************************/
32/* controller constants */
33/************************************************/
34#define MAXADAPTER 4 // Increase this and the sizes of the arrays below, if you need more.
35#define MAX_BUS 2
36#define MAX_UNITS 16
37#define TIMEOUT_COMMAND 400 // number of milliSecondos for command busy timeout
38
39/************************************************/
40/* I/O address offsets */
41/************************************************/
42#define RTR_MAILBOX 0x040
43#define RTR_LOCAL_DOORBELL 0x060
44#define RTR_PCI_DOORBELL 0x064
45
46/************************************************/
47/* */
48/* Host command codes */
49/* */
50/************************************************/
51#define CMD_READ_CHS 0x01 /* read sectors as specified (CHS mode) */
52#define CMD_READ 0x02 /* read sectors as specified (RBA mode) */
53#define CMD_READ_SG 0x03 /* read sectors using scatter/gather list */
54#define CMD_WRITE_CHS 0x04 /* write sectors as specified (CHS mode) */
55#define CMD_WRITE 0x05 /* write sectors as specified (RBA mode) */
56#define CMD_WRITE_SG 0x06 /* write sectors using scatter/gather list (LBA mode) */
57#define CMD_READ_CHS_SG 0x07 /* read sectors using scatter/gather list (CHS mode) */
58#define CMD_WRITE_CHS_SG 0x08 /* write sectors using scatter/gather list (CHS mode) */
59#define CMD_VERIFY_CHS 0x09 /* verify data on sectors as specified (CHS mode) */
60#define CMD_VERIFY 0x0A /* verify data on sectors as specified (RBA mode) */
61#define CMD_DASD_CDB 0x0B /* process CDB for a DASD device */
62#define CMD_DASD_CDB_SG 0x0C /* process CDB for a DASD device with scatter/gather */
63
64#define CMD_READ_ABS 0x10 /* read absolute disk */
65#define CMD_WRITE_ABS 0x11 /* write absolute disk */
66#define CMD_VERIFY_ABS 0x12 /* verify absolute disk */
67#define CMD_TEST_READY 0x13 /* test unit ready and return status code */
68#define CMD_LOCK_DOOR 0x14 /* lock device door */
69#define CMD_UNLOCK_DOOR 0x15 /* unlock device door */
70#define CMD_EJECT_MEDIA 0x16 /* eject the media */
71#define CMD_UPDATE_CAP 0x17 /* update capacity information */
72#define CMD_TEST_PRIV 0x18 /* test and setup private format media */
73
74
75#define CMD_SCSI_THRU 0x30 /* SCSI pass through CDB */
76#define CMD_SCSI_THRU_SG 0x31 /* SCSI pass through CDB with scatter/gather */
77#define CMD_SCSI_REQ_SENSE 0x32 /* SCSI pass through request sense after check condition */
78
79#define CMD_DASD_RAID_RQ 0x35 /* request DASD RAID drive data */
80#define CMD_DASD_RAID_RQ0 0x31 /* byte 1 subcommand to query for RAID 0 informatation */
81#define CMD_DASD_RAID_RQ1 0x32 /* byte 1 subcommand to query for RAID 1 informatation */
82#define CMD_DASD_RAID_RQ5 0x33 /* byte 1 subcommand to query for RAID 5 informatation */
83
84#define CMD_DASD_SCSI_INQ 0x36 /* do DASD inquire and return in SCSI format */
85#define CMD_DASD_CAP 0x37 /* read DASD capacity */
86#define CMD_DASD_INQ 0x38 /* do DASD inquire for type data and return SCSI/EIDE inquiry */
87#define CMD_SCSI_INQ 0x39 /* do SCSI inquire */
88#define CMD_READ_SETUP 0x3A /* Get setup structures from controller */
89#define CMD_WRITE_SETUP 0x3B /* Put setup structures in controller and burn in flash */
90#define CMD_READ_CONFIG 0x3C /* Get the entire configuration and setup structures */
91#define CMD_WRITE_CONFIG 0x3D /* Put the entire configuration and setup structures in flash */
92
93#define CMD_TEXT_DEVICE 0x3E /* obtain device text */
94#define CMD_TEXT_SIGNON 0x3F /* get sign on banner */
95
96#define CMD_QUEUE 0x40 /* any command below this generates a queue tag interrupt to host*/
97
98#define CMD_PREFETCH 0x40 /* prefetch sectors as specified */
99#define CMD_TEST_WRITE 0x41 /* Test a device for write protect */
100#define CMD_LAST_STATUS 0x42 /* get last command status and error data*/
101#define CMD_ABORT 0x43 /* abort command as specified */
102#define CMD_ERROR 0x44 /* fetch error code from a tagged op */
103#define CMD_DONE 0x45 /* done with operation */
104#define CMD_DIAGNOSTICS 0x46 /* execute controller diagnostics and wait for results */
105#define CMD_FEATURE_MODE 0x47 /* feature mode control word */
106#define CMD_DASD_INQUIRE 0x48 /* inquire as to DASD SCSI device (32 possible) */
107#define CMD_FEATURE_QUERY 0x49 /* query the feature control word */
108#define CMD_DASD_EJECT 0x4A /* Eject removable media for DASD type */
109#define CMD_DASD_LOCK 0x4B /* Lock removable media for DASD type */
110#define CMD_DASD_TYPE 0x4C /* obtain DASD device type */
111#define CMD_NUM_DEV 0x4D /* obtain the number of devices connected to the controller */
112#define CMD_GET_PARMS 0x4E /* obtain device parameters */
113#define CMD_SPECIFY 0x4F /* specify operating system for scatter/gather operations */
114
115#define CMD_RAID_GET_DEV 0x50 /* read RAID device geometry */
116#define CMD_RAID_READ 0x51 /* read RAID 1 parameter block */
117#define CMD_RAID_WRITE 0x52 /* write RAID 1 parameter block */
118#define CMD_RAID_LITEUP 0x53 /* Light up the drive light for identification */
119#define CMD_RAID_REBUILD 0x54 /* issue a RAID 1 pair rebuild */
120#define CMD_RAID_MUTE 0x55 /* mute RAID failure alarm */
121#define CMD_RAID_FAIL 0x56 /* induce a RAID failure */
122#define CMD_RAID_STATUS 0x57 /* get status of RAID pair */
123#define CMD_RAID_STOP 0x58 /* stop any reconstruct in progress */
124#define CMD_RAID_START 0x59 /* start reconstruct */
125#define CMD_RAID0_READ 0x5A /* read RAID 0 parameter block */
126#define CMD_RAID0_WRITE 0x5B /* write RAID 0 parameter block */
127#define CMD_RAID5_READ 0x5C /* read RAID 5 parameter block */
128#define CMD_RAID5_WRITE 0x5D /* write RAID 5 parameter block */
129
130#define CMD_ERASE_TABLES 0x5F /* erase partition table and RAID signatutures */
131
132#define CMD_SCSI_GET 0x60 /* get SCSI pass through devices */
133#define CMD_SCSI_TIMEOUT 0x61 /* set SCSI pass through timeout */
134#define CMD_SCSI_ERROR 0x62 /* get SCSI pass through request sense length and residual data count */
135#define CMD_GET_SPARMS 0x63 /* get SCSI bus and user parms */
136#define CMD_SCSI_ABORT 0x64 /* abort by setting time-out to zero */
137
138#define CMD_CHIRP_CHIRP 0x77 /* make a chirp chirp sound */
139#define CMD_GET_LAST_DONE 0x78 /* get tag of last done in progress */
140#define CMD_GET_FEATURES 0x79 /* get feature code and ESN */
141#define CMD_CLEAR_CACHE 0x7A /* Clear cache on specified device */
142#define CMD_BIOS_TEST 0x7B /* Test whether or not to load BIOS */
143#define CMD_WAIT_FLUSH 0x7C /* wait for cache flushed and invalidate read cache */
144#define CMD_RESET_BUS 0x7D /* reset the SCSI bus */
145#define CMD_STARTUP_QRY 0x7E /* startup in progress query */
146#define CMD_RESET 0x7F /* reset the controller */
147
148#define CMD_RESTART_RESET 0x80 /* reload and restart the controller at any reset issued */
149#define CMD_SOFT_RESET 0x81 /* do a soft reset NOW! */
150
151/************************************************/
152/* */
153/* Host return errors */
154/* */
155/************************************************/
156#define ERR08_TAGGED 0x80 /* doorbell error ored with tag */
157
158#define ERR16_NONE 0x0000 /* no errors */
159#define ERR16_SC_COND_MET 0x0004 /* SCSI status - Condition Met */
160#define ERR16_CMD 0x0101 /* command error */
161#define ERR16_SC_CHECK_COND 0x0002 /* SCSI status - Check Condition */
162#define ERR16_CMD_NOT 0x0201 /* command not supported */
163#define ERR16_NO_DEVICE 0x0301 /* invalid device selection */
164#define ERR16_SECTOR 0x0202 /* bad sector */
165#define ERR16_PROTECT 0x0303 /* write protected */
166#define ERR16_NOSECTOR 0x0404 /* sector not found */
167#define ERR16_MEDIA 0x0C0C /* invalid media */
168#define ERR16_CONTROL 0x2020 /* controller error */
169#define ERR16_CONTROL_DMA 0x2120 /* controller DMA engine error */
170#define ERR16_NO_ALARM 0x2220 /* alarm is not active */
171#define ERR16_OP_BUSY 0x2320 /* operation busy */
172#define ERR16_SEEK 0x4040 /* seek failure */
173#define ERR16_DEVICE_FAIL 0x4140 /* device has failed */
174#define ERR16_TIMEOUT 0x8080 /* timeout error */
175#define ERR16_DEV_NOT_READY 0xAAAA /* drive not ready */
176#define ERR16_UNDEFINED 0xBBBB /* undefined error */
177#define ERR16_WRITE_FAULT 0xCCCC /* write fault */
178#define ERR16_INVALID_DEV 0x4001 /* invalid device access */
179#define ERR16_DEVICE_BUSY 0x4002 /* device is busy */
180#define ERR16_MEMORY 0x4003 /* device pass thru requires too much memory */
181#define ERR16_NO_FEATURE 0x40FA /* feature no implemented */
182#define ERR16_NOTAG 0x40FD /* no tag space available */
183#define ERR16_NOT_READY 0x40FE /* controller not ready error */
184#define ERR16_SETUP_FLASH 0x5050 /* error when writing setup to flash memory */
185#define ERR16_SETUP_SIZE 0x5051 /* setup block size error */
186#define ERR16_SENSE 0xFFFF /* sense opereration failed */
187#define ERR16_SC_BUSY 0x0008 /* SCSI status - Busy */
188#define ERR16_SC_RES_CONFL 0x0018 /* SCSI status - Reservation Conflict */
189#define ERR16_SC_CMD_TERM 0x0022 /* SCSI status - Command Terminated */
190#define ERR16_SC_OTHER 0x00FF /* SCSI status - not recognized (any value masked) */
191#define ERR16_MEDIA_CHANGED 0x8001 /* devices media has been changed */
192
193#define ERR32_NONE 0x00000000 /* no errors */
194#define ERR32_SC_COND_MET 0x00000004 /* SCSI status - Condition Met */
195#define ERR32_CMD 0x00010101 /* command error */
196#define ERR32_SC_CHECK_COND 0x00020002 /* SCSI status - Check Condition */
197#define ERR32_CMD_NOT 0x00030201 /* command not supported */
198#define ERR32_NO_DEVICE 0x00040301 /* invalid device selection */
199#define ERR32_SECTOR 0x00050202 /* bad sector */
200#define ERR32_PROTECT 0x00060303 /* write protected */
201#define ERR32_NOSECTOR 0x00070404 /* sector not found */
202#define ERR32_MEDIA 0x00080C0C /* invalid media */
203#define ERR32_CONTROL 0x00092020 /* controller error */
204#define ERR32_CONTROL_DMA 0x000A2120 /* Controller DMA error */
205#define ERR32_NO_ALARM 0x000B2220 /* alarm is not active */
206#define ERR32_OP_BUSY 0x000C2320 /* operation busy */
207#define ERR32_SEEK 0x000D4040 /* seek failure */
208#define ERR32_DEVICE_FAIL 0x000E4140 /* device has failed */
209#define ERR32_TIMEOUT 0x000F8080 /* timeout error */
210#define ERR32_DEV_NOT_READY 0x0010AAAA /* drive not ready */
211#define ERR32_UNDEFINED 0x0011BBBB /* undefined error */
212#define ERR32_WRITE_FAULT 0x0012CCCC /* write fault */
213#define ERR32_INVALID_DEV 0x00134001 /* invalid device access */
214#define ERR32_DEVICE_BUSY 0x00144002 /* device is busy */
215#define ERR32_MEMORY 0x00154003 /* device pass thru requires too much memory */
216#define ERR32_NO_FEATURE 0x001640FA /* feature no implemented */
217#define ERR32_NOTAG 0x001740FD /* no tag space available */
218#define ERR32_NOT_READY 0x001840FE /* controller not ready error */
219#define ERR32_SETUP_FLASH 0x00195050 /* error when writing setup to flash memory */
220#define ERR32_SETUP_SIZE 0x001A5051 /* setup block size error */
221#define ERR32_SENSE 0x001BFFFF /* sense opereration failed */
222#define ERR32_SC_BUSY 0x001C0008 /* SCSI status - Busy */
223#define ERR32_SC_RES_CONFL 0x001D0018 /* SCSI status - Reservation Conflict */
224#define ERR32_SC_CMD_TERM 0x001E0022 /* SCSI status - Command Terminated */
225#define ERR32_SC_OTHER 0x001F00FF /* SCSI status - not recognized (any value masked) */
226#define ERR32_MEDIA_CHANGED 0x00208001 /* devices media has been changed */
227
228/************************************************/
229/* */
230/* Host Operating System specification codes */
231/* */
232/************************************************/
233#define SPEC_INTERRUPT 0x80 /* specification requires host interrupt */
234#define SPEC_BACKWARD_SG 0x40 /* specification requires scatter/gather items reversed */
235#define SPEC_DOS_BLOCK 0x01 /* DOS DASD blocking on pass through */
236#define SPEC_OS2_V3 0x02 /* OS/2 Warp */
237#define SPCE_SCO_3242 0x04 /* SCO 3.4.2.2 */
238#define SPEC_QNX_4X 0x05 /* QNX 4.XX */
239#define SPEC_NOVELL_NWPA 0x08 /* Novell NWPA scatter/gather support */
240
241/************************************************/
242/* */
243/* Inquire structures */
244/* */
245/************************************************/
246typedef struct _CNT_SCSI_INQ
247 {
248 UCHAR devt; /* 00: device type */
249 UCHAR devtm; /* 01: device type modifier */
250 UCHAR svers; /* 02: SCSI version */
251 UCHAR rfmt; /* 03: response data format */
252 UCHAR adlen; /* 04: additional length of data */
253 UCHAR res1; /* 05: */
254 UCHAR res2; /* 06: */
255 UCHAR fncs; /* 07: functional capabilities */
256 UCHAR vid[8]; /* 08: vendor ID */
257 UCHAR pid[16]; /* 10: product ID */
258 UCHAR rev[4]; /* 20: product revision */
259 } CNT_SCSI_INQ;
260
261typedef struct _CNT_IDE_INQ
262 {
263 USHORT GeneralConfiguration; /* 00 */
264 USHORT NumberOfCylinders; /* 02 */
265 USHORT Reserved1; /* 04 */
266 USHORT NumberOfHeads; /* 06 */
267 USHORT UnformattedBytesPerTrack; /* 08 */
268 USHORT UnformattedBytesPerSector; /* 0A */
269 USHORT SectorsPerTrack; /* 0C */
270 USHORT VendorUnique1[3]; /* 0E */
271 USHORT SerialNumber[10]; /* 14 */
272 USHORT BufferType; /* 28 */
273 USHORT BufferSectorSize; /* 2A */
274 USHORT NumberOfEccBytes; /* 2C */
275 USHORT FirmwareRevision[4]; /* 2E */
276 USHORT ModelNumber[20]; /* 36 */
277 UCHAR MaximumBlockTransfer; /* 5E */
278 UCHAR VendorUnique2; /* 5F */
279 USHORT DoubleWordIo; /* 60 */
280 USHORT Capabilities; /* 62 */
281 USHORT Reserved2; /* 64 */
282 UCHAR VendorUnique3; /* 66 */
283 UCHAR PioCycleTimingMode; /* 67 */
284 UCHAR VendorUnique4; /* 68 */
285 UCHAR DmaCycleTimingMode; /* 69 */
286 USHORT TranslationFieldsValid; /* 6A */
287 USHORT NumberOfCurrentCylinders; /* 6C */
288 USHORT NumberOfCurrentHeads; /* 6E */
289 USHORT CurrentSectorsPerTrack; /* 70 */
290 ULONG CurrentSectorCapacity; /* 72 */
291 } CNT_IDE_INQ;
292
293typedef struct _DASD_INQUIRE
294 {
295 ULONG type; /* 0 = SCSI, 1 = IDE */
296 union
297 {
298 CNT_SCSI_INQ scsi; /* SCSI inquire data */
299 CNT_IDE_INQ ide; /* IDE inquire data */
300 } inq;
301 } DASD_INQUIRE;
302
303/************************************************/
304/* */
305/* Device Codes */
306/* */
307/************************************************/
308#define DEVC_DASD 0x00 /* Direct-access Storage Device */
309#define DEVC_SEQACESS 0x01 /* Sequential-access device */
310#define DEVC_PRINTER 0x02 /* Printer device */
311#define DEVC_PROCESSOR 0x03 /* Processor device */
312#define DEVC_WRITEONCE 0x04 /* Write-once device */
313#define DEVC_CDROM 0x05 /* CD-ROM device */
314#define DEVC_SCANNER 0x06 /* Scanner device */
315#define DEVC_OPTICAL 0x07 /* Optical memory device */
316#define DEVC_MEDCHGR 0x08 /* Medium changer device */
317#define DEVC_DASD_REMOVABLE 0x80 /* Direct-access storage device, Removable */
318#define DEVC_NONE 0xFF /* no device */
319
320// SCSI controls for RAID
321#define SC_MY_RAID 0xBF // our special CDB command byte for Win95... interface
322#define MY_SCSI_QUERY0 0x31 // byte 1 subcommand to query driver for RAID 0 informatation
323#define MY_SCSI_QUERY1 0x32 // byte 1 subcommand to query driver for RAID 1 informatation
324#define MY_SCSI_QUERY5 0x33 // byte 1 subcommand to query driver for RAID 5 informatation
325#define MY_SCSI_REBUILD 0x40 // byte 1 subcommand to reconstruct a mirrored pair
326#define MY_SCSI_DEMOFAIL 0x54 // byte 1 subcommand for RAID failure demonstration
327#define MY_SCSI_ALARMMUTE 0x60 // byte 1 subcommand to mute any alarm currently on
328
329
330#endif
331