1 /****************************************************************************
2 * Perceptive Solutions, Inc. PCI-2220I device driver for Linux.
4 * pci2220i.c - Linux Host Driver for PCI-2220I EIDE RAID Adapters
6 * Copyright (c) 1997-1999 Perceptive Solutions, Inc.
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
14 * Technical updates and product information at:
15 * http://www.psidisk.com
17 * Please send questions, comments, bug reports to:
18 * tech@psidisk.com Technical Support
21 * Revisions 1.10 Mar-26-1999
22 * - Updated driver for RAID and hot reconstruct support.
24 * Revisions 1.11 Mar-26-1999
25 * - Fixed spinlock and PCI configuration.
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
32 * Revision 2.10 March-27-2000
33 * - Added support for dynamic DMA
35 ****************************************************************************/
37 #error Convert me to understand page+offset based scatterlists
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>
58 #include <asm/system.h>
62 #include <scsi/scsi_host.h>
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
74 #define STOP_HERE() {int st;for(st=0;st<100;st++){st=1;}}
80 #define MAXADAPTER 4 // Increase this and the sizes of the arrays below, if you need more.
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
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
;
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
];
145 UCHAR
*currentSgBuffer
;
146 ULONG currentSgCount
;
150 POUR_DEVICE pdev
; // current device opearating on
151 USHORT devInReconIndex
;
153 USHORT reconOn
; // Hot reconstruct is to be done.
154 USHORT reconPhase
; // Hot reconstruct operation is in progress.
156 USHORT demoFail
; // flag for RAID failure demonstration
159 struct timer_list reconTimer
;
160 struct timer_list timer
;
162 dma_addr_t kBufferDma
;
166 } ADAPTER2220I
, *PADAPTER2220I
;
168 #define HOSTDATA(host) ((PADAPTER2220I)&host->hostdata)
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
178 static struct Scsi_Host
*PsiHost
[MAXADAPTER
] = {NULL
,}; // One for each adapter
179 static int NumAdapters
= 0;
180 static int Installed
= 0;
181 static SETUP DaleSetup
;
182 static DISK_MIRROR DiskMirror
[BIGD_MAXDRIVES
];
183 static ULONG ModeArray
[] = {DALE_DATA_MODE2
, DALE_DATA_MODE3
, DALE_DATA_MODE4
, DALE_DATA_MODE5
};
184 static ULONG ModeArray2
[] = {BIGD_DATA_MODE2
, BIGD_DATA_MODE3
, BIGD_DATA_MODE4
, BIGD_DATA_MODE5
};
186 static void ReconTimerExpiry (unsigned long data
);
188 /*******************************************************************************************************
191 * Description: Sound the for the given device
193 * Parameters: padapter - Pointer adapter data structure.
194 * device - Device number.
198 ******************************************************************************************************/
199 static void Alarm (PADAPTER2220I padapter
, UCHAR device
)
203 if ( padapter
->bigD
)
205 zc
= device
| (FAIL_ANY
| FAIL_AUDIBLE
);
206 if ( padapter
->failRegister
& FAIL_ANY
)
209 padapter
->failRegister
= zc
;
210 outb_p (~zc
, padapter
->regFail
);
213 outb_p (0x3C | (1 << device
), padapter
->regFail
); // sound alarm and set fail light
215 /****************************************************************
216 * Name: MuteAlarm :LOCAL
218 * Description: Mute the audible alarm.
220 * Parameters: padapter - Pointer adapter data structure.
222 * Returns: TRUE if drive does not assert DRQ in time.
224 ****************************************************************/
225 static void MuteAlarm (PADAPTER2220I padapter
)
229 if ( padapter
->bigD
)
231 padapter
->failRegister
&= ~FAIL_AUDIBLE
;
232 outb_p (~padapter
->failRegister
, padapter
->regFail
);
236 old
= (inb_p (padapter
->regStatSel
) >> 3) | (inb_p (padapter
->regStatSel
) & 0x83);
237 outb_p (old
| 0x40, padapter
->regFail
);
240 /****************************************************************
241 * Name: WaitReady :LOCAL
243 * Description: Wait for device ready.
245 * Parameters: padapter - Pointer adapter data structure.
247 * Returns: TRUE if drive does not assert DRQ in time.
249 ****************************************************************/
250 static int WaitReady (PADAPTER2220I padapter
)
255 for ( z
= 0; z
< (TIMEOUT_READY
* 4); z
++ )
257 status
= inb_p (padapter
->regStatCmd
);
258 if ( (status
& (IDE_STATUS_DRDY
| IDE_STATUS_BUSY
)) == IDE_STATUS_DRDY
)
264 /****************************************************************
265 * Name: WaitReadyReset :LOCAL
267 * Description: Wait for device ready.
269 * Parameters: padapter - Pointer adapter data structure.
271 * Returns: TRUE if drive does not assert DRQ in time.
273 ****************************************************************/
274 static int WaitReadyReset (PADAPTER2220I padapter
)
279 for ( z
= 0; z
< (125 * 16); z
++ ) // wait up to 1/4 second
281 status
= inb_p (padapter
->regStatCmd
);
282 if ( (status
& (IDE_STATUS_DRDY
| IDE_STATUS_BUSY
)) == IDE_STATUS_DRDY
)
284 DEB (printk ("\nPCI2220I: Reset took %ld mSec to be ready", z
/ 8));
289 DEB (printk ("\nPCI2220I: Reset took more than 2 Seconds to come ready, Disk Failure"));
292 /****************************************************************
293 * Name: WaitDrq :LOCAL
295 * Description: Wait for device ready for data transfer.
297 * Parameters: padapter - Pointer adapter data structure.
299 * Returns: TRUE if drive does not assert DRQ in time.
301 ****************************************************************/
302 static int WaitDrq (PADAPTER2220I padapter
)
307 for ( z
= 0; z
< (TIMEOUT_DRQ
* 4); z
++ )
309 status
= inb_p (padapter
->regStatCmd
);
310 if ( status
& IDE_STATUS_DRQ
)
316 /****************************************************************
317 * Name: AtapiWaitReady :LOCAL
319 * Description: Wait for device busy and DRQ to be cleared.
321 * Parameters: padapter - Pointer adapter data structure.
322 * msec - Number of milliseconds to wait.
324 * Returns: TRUE if drive does not clear busy in time.
326 ****************************************************************/
327 static int AtapiWaitReady (PADAPTER2220I padapter
, int msec
)
331 for ( z
= 0; z
< (msec
* 16); z
++ )
333 if ( !(inb_p (padapter
->regStatCmd
) & (IDE_STATUS_BUSY
| IDE_STATUS_DRQ
)) )
339 /****************************************************************
340 * Name: AtapiWaitDrq :LOCAL
342 * Description: Wait for device ready for data transfer.
344 * Parameters: padapter - Pointer adapter data structure.
345 * msec - Number of milliseconds to wait.
347 * Returns: TRUE if drive does not assert DRQ in time.
349 ****************************************************************/
350 static int AtapiWaitDrq (PADAPTER2220I padapter
, int msec
)
354 for ( z
= 0; z
< (msec
* 16); z
++ )
356 if ( inb_p (padapter
->regStatCmd
) & IDE_STATUS_DRQ
)
362 /****************************************************************
363 * Name: HardReset :LOCAL
365 * Description: Wait for device ready for data transfer.
367 * Parameters: padapter - Pointer adapter data structure.
368 * pdev - Pointer to device.
369 * spigot - Spigot number.
371 * Returns: TRUE if drive does not assert DRQ in time.
373 ****************************************************************/
374 static int HardReset (PADAPTER2220I padapter
, POUR_DEVICE pdev
, UCHAR spigot
)
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
);
380 outb_p (0x0E, padapter
->regAltStat
); // reset the suvivor
381 udelay (100); // wait a little
382 outb_p (0x08, padapter
->regAltStat
); // clear the reset
385 outb_p (0xA0, padapter
->regLba24
); // select the master drive
386 if ( WaitReadyReset (padapter
) )
388 DEB (printk ("\npci2220i: master not ready after reset"));
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
)
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
) )
399 DEB (printk ("\npci2220i: slave not ready after set multiple"));
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
) )
409 DEB (printk ("\npci2220i: master not ready after set multiple"));
414 /****************************************************************
415 * Name: AtapiReset :LOCAL
417 * Description: Wait for device ready for data transfer.
419 * Parameters: padapter - Pointer adapter data structure.
420 * pdev - Pointer to device.
422 * Returns: TRUE if drive does not come ready.
424 ****************************************************************/
425 static int AtapiReset (PADAPTER2220I padapter
, POUR_DEVICE pdev
)
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
);
433 if ( AtapiWaitReady (padapter
, 1000) )
435 if ( inb_p (padapter
->regStatCmd
) || (inb_p (padapter
->regLba8
) != 0x14) || (inb_p (padapter
->regLba16
) != 0xEB) )
439 /****************************************************************
440 * Name: WalkScatGath :LOCAL
442 * Description: Transfer data to/from scatter/gather buffers.
444 * Parameters: padapter - Pointer adapter data structure.
445 * datain - TRUE if data read.
446 * length - Number of bytes to transfer.
450 ****************************************************************/
451 static void WalkScatGath (PADAPTER2220I padapter
, UCHAR datain
, ULONG length
)
454 UCHAR
*buffer
= padapter
->kBuffer
;
458 count
= ( length
> padapter
->currentSgCount
) ? padapter
->currentSgCount
: length
;
461 memcpy (padapter
->currentSgBuffer
, buffer
, count
);
463 memcpy (buffer
, padapter
->currentSgBuffer
, count
);
465 padapter
->currentSgCount
-= count
;
466 if ( !padapter
->currentSgCount
)
468 if ( padapter
->nextSg
< padapter
->SCpnt
->use_sg
)
470 padapter
->currentSgBuffer
= ((struct scatterlist
*)padapter
->SCpnt
->request_buffer
)[padapter
->nextSg
].address
;
471 padapter
->currentSgCount
= ((struct scatterlist
*)padapter
->SCpnt
->request_buffer
)[padapter
->nextSg
].length
;
476 padapter
->currentSgBuffer
+= count
;
482 /****************************************************************
483 * Name: BusMaster :LOCAL
485 * Description: Do a bus master I/O.
487 * Parameters: padapter - Pointer adapter data structure.
488 * datain - TRUE if data read.
489 * irq - TRUE if bus master interrupt expected.
493 ****************************************************************/
494 static void BusMaster (PADAPTER2220I padapter
, UCHAR datain
, UCHAR irq
)
498 zl
= ( padapter
->sectorCount
> MAX_BUS_MASTER_BLOCKS
) ? MAX_BUS_MASTER_BLOCKS
: padapter
->sectorCount
;
499 padapter
->sectorCount
-= zl
;
500 zl
*= (ULONG
)BYTES_PER_SECTOR
;
504 padapter
->readCount
= zl
;
505 outb_p (8, padapter
->regDmaDesc
); // read operation
506 if ( padapter
->bigD
)
508 if ( irq
&& !padapter
->sectorCount
)
509 outb_p (0x0C, padapter
->regDmaMode
); // interrupt on
511 outb_p (0x08, padapter
->regDmaMode
); // no interrupt
515 if ( irq
&& !padapter
->sectorCount
)
516 outb_p (0x05, padapter
->regDmaMode
); // interrupt on
518 outb_p (0x01, padapter
->regDmaMode
); // no interrupt
523 outb_p (0x00, padapter
->regDmaDesc
); // write operation
524 if ( padapter
->bigD
)
525 outb_p (0x08, padapter
->regDmaMode
); // no interrupt
527 outb_p (0x01, padapter
->regDmaMode
); // no interrupt
528 WalkScatGath (padapter
, FALSE
, zl
);
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
536 /****************************************************************
537 * Name: AtapiBusMaster :LOCAL
539 * Description: Do a bus master I/O.
541 * Parameters: padapter - Pointer adapter data structure.
542 * datain - TRUE if data read.
543 * length - Number of bytes to transfer.
547 ****************************************************************/
548 static void AtapiBusMaster (PADAPTER2220I padapter
, UCHAR datain
, ULONG length
)
550 outl (padapter
->timingAddress
, padapter
->regDmaAddrLoc
);
551 outl (padapter
->kBufferDma
, padapter
->regDmaAddrPci
);
552 outl (length
, padapter
->regDmaCount
);
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
;
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
);
568 outb_p (0x03, padapter
->regDmaCmdStat
); // kick the DMA engine in gear
570 /****************************************************************
571 * Name: WriteData :LOCAL
573 * Description: Write data to device.
575 * Parameters: padapter - Pointer adapter data structure.
577 * Returns: TRUE if drive does not assert DRQ in time.
579 ****************************************************************/
580 static int WriteData (PADAPTER2220I padapter
)
584 if ( !WaitDrq (padapter
) )
586 if ( padapter
->timingPIO
)
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
;
594 BusMaster (padapter
, 0, 0);
597 padapter
->cmd
= 0; // null out the command byte
600 /****************************************************************
601 * Name: WriteDataBoth :LOCAL
603 * Description: Write data to device.
605 * Parameters: padapter - Pointer to adapter structure.
606 * pdev - Pointer to device structure
608 * Returns: Index + 1 of drive not failed or zero for OK.
610 ****************************************************************/
611 static int WriteDataBoth (PADAPTER2220I padapter
, POUR_DEVICE pdev
)
614 UCHAR status0
, status1
;
616 SelectSpigot (padapter
, pdev
->spigots
[0]);
617 status0
= WaitDrq (padapter
);
620 SelectSpigot (padapter
, pdev
->spigots
[1]);
621 status1
= WaitDrq (padapter
);
624 SelectSpigot (padapter
, pdev
->spigots
[0] | pdev
->spigots
[1] | padapter
->bigD
);
625 if ( padapter
->timingPIO
)
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
;
633 BusMaster (padapter
, 0, 0);
637 padapter
->cmd
= 0; // null out the command byte
642 /****************************************************************
643 * Name: IdeCmd :LOCAL
645 * Description: Process an IDE command.
647 * Parameters: padapter - Pointer adapter data structure.
648 * pdev - Pointer to device.
650 * Returns: Zero if no error or status register contents on error.
652 ****************************************************************/
653 static UCHAR
IdeCmd (PADAPTER2220I padapter
, POUR_DEVICE pdev
)
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
);
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
);
671 padapter
->cmd
= 0; // null out the command byte
674 /****************************************************************
675 * Name: IdeCmdBoth :LOCAL
677 * Description: Process an IDE command to both drivers.
679 * Parameters: padapter - Pointer adapter data structure.
680 * pdev - Pointer to device structure
682 * Returns: Index + 1 of drive not failed or zero for OK.
684 ****************************************************************/
685 static UCHAR
IdeCmdBoth (PADAPTER2220I padapter
, POUR_DEVICE pdev
)
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
);
696 SelectSpigot (padapter
, pdev
->spigots
[1]);
697 status1
= WaitReady (padapter
);
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
);
710 padapter
->cmd
= 0; // null out the command byte
715 /****************************************************************
716 * Name: OpDone :LOCAL
718 * Description: Complete an operatoin done sequence.
720 * Parameters: padapter - Pointer to host data block.
721 * spigot - Spigot select code.
722 * device - Device byte code.
726 ****************************************************************/
727 static void OpDone (PADAPTER2220I padapter
, ULONG result
)
729 Scsi_Cmnd
*SCpnt
= padapter
->SCpnt
;
731 if ( padapter
->reconPhase
)
733 padapter
->reconPhase
= 0;
734 if ( padapter
->SCpnt
)
736 Pci2220i_QueueCommand (SCpnt
, SCpnt
->scsi_done
);
740 if ( padapter
->reconOn
)
742 ReconTimerExpiry ((unsigned long)padapter
);
749 padapter
->SCpnt
= NULL
;
750 padapter
->pdev
= NULL
;
751 SCpnt
->result
= result
;
752 SCpnt
->scsi_done (SCpnt
);
753 if ( padapter
->reconOn
&& !padapter
->reconTimer
.data
)
755 padapter
->reconTimer
.expires
= jiffies
+ (HZ
/ 4); // start in 1/4 second
756 padapter
->reconTimer
.data
= (unsigned long)padapter
;
757 add_timer (&padapter
->reconTimer
);
761 /****************************************************************
762 * Name: InlineIdentify :LOCAL
764 * Description: Do an intline inquiry on a drive.
766 * Parameters: padapter - Pointer to host data block.
767 * spigot - Spigot select code.
768 * device - Device byte code.
770 * Returns: Last addressable sector or zero if none.
772 ****************************************************************/
773 static ULONG
InlineIdentify (PADAPTER2220I padapter
, UCHAR spigot
, UCHAR device
)
775 PIDENTIFY_DATA pid
= (PIDENTIFY_DATA
)padapter
->kBuffer
;
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
) )
781 WriteCommand (padapter
, IDE_COMMAND_IDENTIFY
);
782 if ( WaitDrq (padapter
) )
784 insw (padapter
->regData
, padapter
->kBuffer
, sizeof (IDENTIFY_DATA
) >> 1);
785 return (pid
->LBATotalSectors
- 1);
787 /****************************************************************
788 * Name: AtapiIdentify :LOCAL
790 * Description: Do an intline inquiry on a drive.
792 * Parameters: padapter - Pointer to host data block.
793 * pdev - Pointer to device table.
795 * Returns: TRUE on error.
797 ****************************************************************/
798 static ULONG
AtapiIdentify (PADAPTER2220I padapter
, POUR_DEVICE pdev
)
804 AtapiDevice (padapter
, pdev
->byte6
);
805 WriteCommand (padapter
, IDE_COMMAND_ATAPI_IDENTIFY
);
806 if ( AtapiWaitDrq (padapter
, 3000) )
809 *(USHORT
*)&ag0
= inw_p (padapter
->regData
);
810 for ( z
= 0; z
< 255; z
++ )
811 zs
= inw_p (padapter
->regData
);
813 if ( ag0
.ProtocolType
== 2 )
815 if ( ag0
.CmdDrqType
== 1 )
816 pdev
->cmdDrqInt
= TRUE
;
817 switch ( ag0
.CmdPacketSize
)
833 /****************************************************************
836 * Description: Convert ATAPI data to SCSI data.
838 * Parameters: padapter - Pointer adapter data structure.
839 * SCpnt - Pointer to SCSI command structure.
843 ****************************************************************/
844 void Atapi2Scsi (PADAPTER2220I padapter
, Scsi_Cmnd
*SCpnt
)
846 UCHAR
*buff
= padapter
->currentSgBuffer
;
848 switch ( SCpnt
->cmnd
[0] )
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);
858 padapter
->kBuffer
[2] = 2;
859 memcpy (buff
, padapter
->kBuffer
, padapter
->currentSgCount
);
862 if ( padapter
->readCount
)
863 WalkScatGath (padapter
, TRUE
, padapter
->readCount
);
867 /****************************************************************
870 * Description: Convert SCSI packet command to Atapi packet command.
872 * Parameters: padapter - Pointer adapter data structure.
873 * SCpnt - Pointer to SCSI command structure.
877 ****************************************************************/
878 static void Scsi2Atapi (PADAPTER2220I padapter
, Scsi_Cmnd
*SCpnt
)
880 UCHAR
*cdb
= SCpnt
->cmnd
;
881 UCHAR
*buff
= padapter
->currentSgBuffer
;
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];
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];
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;
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;
921 /****************************************************************
924 * Description: Send the CDB packet to the device.
926 * Parameters: padapter - Pointer adapter data structure.
927 * pdev - Pointer to device.
928 * cdb - Pointer to 16 byte SCSI cdb.
932 ****************************************************************/
933 static void AtapiSendCdb (PADAPTER2220I padapter
, POUR_DEVICE pdev
, CHAR
*cdb
)
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
);
938 /****************************************************************
939 * Name: AtapiRequestSense
941 * Description: Send the CDB packet to the device.
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.
948 * Returns: TRUE on error.
950 ****************************************************************/
951 static int AtapiRequestSense (PADAPTER2220I padapter
, POUR_DEVICE pdev
, Scsi_Cmnd
*SCpnt
, UCHAR pass
)
953 UCHAR cdb
[16] = {SCSIOP_REQUEST_SENSE
,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0};
955 DEB (printk ("\nPCI2242I: AUTO REQUEST SENSE"));
956 cdb
[4] = (UCHAR
)(sizeof (SCpnt
->sense_buffer
));
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
)
967 if ( AtapiWaitDrq (padapter
, 500) )
970 AtapiSendCdb (padapter
, pdev
, cdb
);
973 /****************************************************************
974 * Name: InlineReadSignature :LOCAL
976 * Description: Do an inline read RAID sigature.
978 * Parameters: padapter - Pointer adapter data structure.
979 * pdev - Pointer to device.
980 * index - index of data to read.
982 * Returns: Zero if no error or status register contents on error.
984 ****************************************************************/
985 static UCHAR
InlineReadSignature (PADAPTER2220I padapter
, POUR_DEVICE pdev
, int index
)
988 ULONG zl
= pdev
->lastsectorlba
[index
];
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
);
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
);
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
);
1013 /****************************************************************
1014 * Name: DecodeError :LOCAL
1016 * Description: Decode and process device errors.
1018 * Parameters: padapter - Pointer to adapter data.
1019 * status - Status register code.
1021 * Returns: The driver status code.
1023 ****************************************************************/
1024 static ULONG
DecodeError (PADAPTER2220I padapter
, UCHAR status
)
1028 padapter
->expectingIRQ
= 0;
1029 if ( status
& IDE_STATUS_WRITE_FAULT
)
1031 return DID_PARITY
<< 16;
1033 if ( status
& IDE_STATUS_BUSY
)
1034 return DID_BUS_BUSY
<< 16;
1036 error
= inb_p (padapter
->regError
);
1037 DEB(printk ("\npci2220i error register: %x", error
));
1040 case IDE_ERROR_AMNF
:
1041 case IDE_ERROR_TKONF
:
1042 case IDE_ERROR_ABRT
:
1043 case IDE_ERROR_IDFN
:
1047 return DID_ERROR
<< 16;
1049 return DID_ERROR
<< 16;
1051 /****************************************************************
1052 * Name: StartTimer :LOCAL
1054 * Description: Start the timer.
1056 * Parameters: ipadapter - Pointer adapter data structure.
1060 ****************************************************************/
1061 static void StartTimer (PADAPTER2220I padapter
)
1063 padapter
->timer
.expires
= jiffies
+ TIMEOUT_DATA
;
1064 add_timer (&padapter
->timer
);
1066 /****************************************************************
1067 * Name: WriteSignature :LOCAL
1069 * Description: Start the timer.
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.
1076 * Returns: TRUE on any error.
1078 ****************************************************************/
1079 static int WriteSignature (PADAPTER2220I padapter
, POUR_DEVICE pdev
, UCHAR spigot
, int index
)
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
);
1091 WriteCommand (padapter
, IDE_COMMAND_WRITE
);
1092 if ( WaitDrq (padapter
) )
1094 StartTimer (padapter
);
1095 padapter
->expectingIRQ
= TRUE
;
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);
1102 /*******************************************************************************************************
1103 * Name: InitFailover
1105 * Description: This is the beginning of the failover routine
1107 * Parameters: SCpnt - Pointer to SCSI command structure.
1108 * padapter - Pointer adapter data structure.
1109 * pdev - Pointer to our device.
1111 * Returns: TRUE on error.
1113 ******************************************************************************************************/
1114 static int InitFailover (PADAPTER2220I padapter
, POUR_DEVICE pdev
)
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
];
1123 if ( pdev
->DiskMirror
[padapter
->survivor
].status
& UCBF_REBUILD
)
1125 DEB (printk ("\n failed, is survivor"));
1129 if ( HardReset (padapter
, pdev
, spigot
) )
1131 DEB (printk ("\n failed, reset"));
1135 Alarm (padapter
, pdev
->deviceID
[padapter
->survivor
^ 1]);
1136 pdev
->DiskMirror
[padapter
->survivor
].status
= UCBF_MIRRORED
| UCBF_SURVIVOR
; //clear present status
1138 if ( WriteSignature (padapter
, pdev
, spigot
, padapter
->survivor
) )
1140 DEB (printk ("\n failed, write signature"));
1143 padapter
->failinprog
= TRUE
;
1146 /****************************************************************
1147 * Name: TimerExpiry :LOCAL
1149 * Description: Timer expiry routine.
1151 * Parameters: data - Pointer adapter data structure.
1155 ****************************************************************/
1156 static void TimerExpiry (unsigned long data
)
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
;
1163 unsigned long flags
;
1166 * Disable interrupts, if they aren't already disabled and acquire
1169 spin_lock_irqsave (host
->host_lock
, flags
);
1170 DEB (printk ("\nPCI2220I: Timeout expired "));
1172 if ( padapter
->failinprog
)
1174 DEB (printk ("in failover process"));
1175 OpDone (padapter
, DecodeError (padapter
, inb_p (padapter
->regStatCmd
)));
1176 goto timerExpiryDone
;
1179 while ( padapter
->reconPhase
)
1181 DEB (printk ("in recon phase %X", padapter
->reconPhase
));
1182 switch ( padapter
->reconPhase
)
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
;
1192 case RECON_PHASE_READY
:
1193 OpDone (padapter
, DID_ERROR
<< 16);
1194 goto timerExpiryDone
;
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
;
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
;
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
;
1219 goto timerExpiryDone
;
1223 while ( padapter
->cmd
)
1225 outb_p (0x08, padapter
->regDmaCmdStat
); // cancel interrupt from DMA engine
1228 if ( padapter
->cmd
== WRITE_CMD
)
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
)
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
);
1239 temp
= IDE_STATUS_BUSY
;
1241 temp1
= ( pdev
->spigot
& (SEL_1
| SEL_2
) ) ? SEL_2
: SEL_4
;
1242 if ( inb (padapter
->regStatSel
) & temp1
)
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
);
1249 temp1
= IDE_STATUS_BUSY
;
1251 if ( (temp
& IDE_STATUS_BUSY
) || (temp1
& IDE_STATUS_BUSY
) )
1253 DEB (printk ("\npci2220i: Status A: %X B: %X", temp
& 0xFF, temp1
& 0xFF));
1254 if ( (temp
& IDE_STATUS_BUSY
) && (temp1
& IDE_STATUS_BUSY
) )
1261 if ( temp
& IDE_STATUS_BUSY
)
1262 padapter
->survivor
= 1;
1264 padapter
->survivor
= 0;
1265 if ( InitFailover (padapter
, pdev
) )
1267 status
= inb_p (padapter
->regStatCmd
);
1270 goto timerExpiryDone
;
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
) )
1281 status
= inb_p (padapter
->regStatCmd
);
1284 goto timerExpiryDone
;
1289 DEB (printk ("in I/O operation"));
1290 status
= inb_p (padapter
->regStatCmd
);
1295 OpDone (padapter
, DecodeError (padapter
, status
));
1299 * Release the I/O spinlock and restore the original flags
1300 * which will enable interrupts if and only if they were
1303 spin_unlock_irqrestore (host
->host_lock
, flags
);
1305 /****************************************************************
1306 * Name: SetReconstruct :LOCAL
1308 * Description: Set the reconstruct up.
1310 * Parameters: pdev - Pointer to device structure.
1311 * index - Mirror index number.
1313 * Returns: Number of sectors on new disk required.
1315 ****************************************************************/
1316 static LONG
SetReconstruct (POUR_DEVICE pdev
, int index
)
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
;
1324 /****************************************************************
1325 * Name: ReconTimerExpiry :LOCAL
1327 * Description: Reconstruct timer expiry routine.
1329 * Parameters: data - Pointer adapter data structure.
1333 ****************************************************************/
1334 static void ReconTimerExpiry (unsigned long data
)
1336 PADAPTER2220I padapter
= (PADAPTER2220I
)data
;
1337 struct Scsi_Host
*host
= padapter
->SCpnt
->device
->host
;
1345 unsigned long flags
;
1348 * Disable interrupts, if they aren't already disabled and acquire
1351 spin_lock_irqsave(host
->host_lock
, flags
);
1353 if ( padapter
->SCpnt
)
1354 goto reconTimerExpiry
;
1356 padapter
->reconTimer
.data
= 0;
1357 for ( z
= padapter
->devInReconIndex
+ 1; z
< BIGD_MAXDRIVES
; z
++ )
1359 if ( padapter
->device
[z
].reconOn
)
1362 if ( z
< BIGD_MAXDRIVES
)
1363 pdev
= &padapter
->device
[z
];
1366 for ( z
= 0; z
< BIGD_MAXDRIVES
; z
++ )
1368 if ( padapter
->device
[z
].reconOn
)
1371 if ( z
< BIGD_MAXDRIVES
)
1372 pdev
= &padapter
->device
[z
];
1375 padapter
->reconOn
= FALSE
;
1376 goto reconTimerExpiry
;
1380 padapter
->devInReconIndex
= z
;
1381 pid
= (PIDENTIFY_DATA
)padapter
->kBuffer
;
1382 padapter
->pdev
= pdev
;
1383 if ( pdev
->reconIsStarting
)
1385 pdev
->reconIsStarting
= FALSE
;
1386 pdev
->reconOn
= FALSE
;
1388 while ( (pdev
->DiskMirror
[0].signature
== SIGNATURE
) && (pdev
->DiskMirror
[1].signature
== SIGNATURE
) &&
1389 (pdev
->DiskMirror
[0].pairIdentifier
== (pdev
->DiskMirror
[1].pairIdentifier
^ 1)) )
1391 if ( (pdev
->DiskMirror
[0].status
& UCBF_MATCHED
) && (pdev
->DiskMirror
[1].status
& UCBF_MATCHED
) )
1394 if ( pdev
->DiskMirror
[0].status
& UCBF_SURVIVOR
) // is first drive survivor?
1395 testsize
= SetReconstruct (pdev
, 0);
1397 if ( pdev
->DiskMirror
[1].status
& UCBF_SURVIVOR
) // is second drive survivor?
1398 testsize
= SetReconstruct (pdev
, 1);
1400 if ( (pdev
->DiskMirror
[0].status
& UCBF_REBUILD
) || (pdev
->DiskMirror
[1].status
& UCBF_REBUILD
) )
1402 if ( pdev
->DiskMirror
[0].status
& UCBF_REBUILD
)
1403 pdev
->mirrorRecon
= 0;
1405 pdev
->mirrorRecon
= 1;
1406 pdev
->reconOn
= TRUE
;
1411 if ( !pdev
->reconOn
)
1412 goto reconTimerExpiry
;
1414 if ( padapter
->bigD
)
1416 padapter
->failRegister
= 0;
1417 outb_p (~padapter
->failRegister
, padapter
->regFail
);
1421 zc
= ((inb_p (padapter
->regStatSel
) >> 3) | inb_p (padapter
->regStatSel
)) & 0x83; // mute the alarm
1422 outb_p (0xFF, padapter
->regFail
);
1427 DEB (printk ("\npci2220i: hard reset issue"));
1428 if ( HardReset (padapter
, pdev
, pdev
->spigots
[pdev
->mirrorRecon
]) )
1430 DEB (printk ("\npci2220i: sub 1"));
1434 pdev
->lastsectorlba
[pdev
->mirrorRecon
] = InlineIdentify (padapter
, pdev
->spigots
[pdev
->mirrorRecon
], pdev
->deviceID
[pdev
->mirrorRecon
] & 1);
1436 if ( pdev
->lastsectorlba
[pdev
->mirrorRecon
] < testsize
)
1438 DEB (printk ("\npci2220i: sub 2 %ld %ld", pdev
->lastsectorlba
[pdev
->mirrorRecon
], testsize
));
1442 // test LBA and multiper sector transfer compatibility
1443 if (!pid
->SupportLBA
|| (pid
->NumSectorsPerInt
< SECTORSXFER
) || !pid
->Valid_64_70
)
1445 DEB (printk ("\npci2220i: sub 3"));
1449 // test PIO/bus matering mode compatibility
1450 if ( (pid
->MinPIOCycleWithoutFlow
> 240) && !pid
->SupportIORDYDisable
&& !padapter
->timingPIO
)
1452 DEB (printk ("\npci2220i: sub 4"));
1456 if ( pid
->MinPIOCycleWithoutFlow
<= 120 ) // setup timing mode of drive
1460 if ( pid
->MinPIOCylceWithFlow
<= 150 )
1464 if ( pid
->MinPIOCylceWithFlow
<= 180 )
1468 if ( pid
->MinPIOCylceWithFlow
<= 240 )
1472 DEB (printk ("\npci2220i: sub 5"));
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];
1484 padapter
->timingPIO
= TRUE
;
1486 padapter
->reconOn
= TRUE
;
1490 if ( !pdev
->reconOn
)
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
;
1501 if ( WriteSignature (padapter
, pdev
, pdev
->spigot
, pdev
->mirrorRecon
^ 1) )
1502 goto reconTimerExpiry
;
1503 padapter
->reconPhase
= RECON_PHASE_MARKING
;
1504 goto reconTimerExpiry
;
1507 //**********************************
1508 // reconstruct copy starts here
1509 //**********************************
1510 if ( pdev
->reconCount
++ > 2000 )
1512 pdev
->reconCount
= 0;
1513 if ( WriteSignature (padapter
, pdev
, pdev
->spigots
[pdev
->mirrorRecon
], pdev
->mirrorRecon
) )
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
;
1521 padapter
->reconPhase
= RECON_PHASE_UPDATE
;
1522 goto reconTimerExpiry
;
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
;
1530 if ( padapter
->reconSize
)
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
;
1538 SelectSpigot (padapter
, pdev
->spigots
[pdev
->mirrorRecon
]);
1539 if ( WaitReady (padapter
) )
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
;
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
;
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
;
1571 * Release the I/O spinlock and restore the original flags
1572 * which will enable interrupts if and only if they were
1575 spin_unlock_irqrestore(host
->host_lock
, flags
);
1577 /****************************************************************
1578 * Name: Irq_Handler :LOCAL
1580 * Description: Interrupt handler.
1582 * Parameters: irq - Hardware IRQ number.
1586 * Returns: TRUE if drive is not ready in time.
1588 ****************************************************************/
1589 static irqreturn_t
Irq_Handler (int irq
, void *dev_id
, struct pt_regs
*regs
)
1591 struct Scsi_Host
*shost
= NULL
; // Pointer to host data block
1592 PADAPTER2220I padapter
; // Pointer to adapter control structure
1597 ATAPI_STATUS statusa
;
1598 ATAPI_REASON reasona
;
1602 unsigned long flags
;
1605 // DEB (printk ("\npci2220i received interrupt\n"));
1607 for ( z
= 0; z
< NumAdapters
; z
++ ) // scan for interrupt to process
1609 if ( PsiHost
[z
]->irq
== (UCHAR
)(irq
& 0xFF) )
1611 if ( inw_p (HOSTDATA(PsiHost
[z
])->regIrqControl
) & 0x8000 )
1621 DEB (printk ("\npci2220i: not my interrupt"));
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
1632 if ( padapter
->atapi
&& SCpnt
)
1634 *(char *)&statusa
= inb_p (padapter
->regStatCmd
); // read the device status
1635 *(char *)&reasona
= inb_p (padapter
->regSectCount
); // read the device interrupt reason
1639 if ( statusa
.drq
) // test for transfer phase
1641 if ( !reasona
.cod
) // test for data phase
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);
1647 AtapiBusMaster (padapter
, reasona
.io
, z
);
1650 if ( reasona
.cod
&& !reasona
.io
) // test for command packet phase
1652 if ( padapter
->reqSense
)
1653 AtapiRequestSense (padapter
, pdev
, SCpnt
, TRUE
);
1655 AtapiSendCdb (padapter
, pdev
, padapter
->atapiCdb
);
1661 if ( reasona
.io
&& statusa
.drdy
) // test for status phase
1663 Atapi2Scsi (padapter
, SCpnt
);
1664 if ( statusa
.check
)
1666 *(UCHAR
*)&errora
= inb_p (padapter
->regError
); // read the device error
1667 if ( errora
.senseKey
)
1669 if ( padapter
->reqSense
|| AtapiRequestSense (padapter
, pdev
, SCpnt
, FALSE
) )
1670 OpDone (padapter
, DID_ERROR
<< 16);
1674 if ( errora
.ili
|| errora
.abort
)
1675 OpDone (padapter
, DID_ERROR
<< 16);
1677 OpDone (padapter
, DID_OK
<< 16);
1681 if ( padapter
->reqSense
)
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);
1687 OpDone (padapter
, DID_OK
<< 16);
1694 if ( !padapter
->expectingIRQ
|| !(SCpnt
|| padapter
->reconPhase
) )
1696 DEB(printk ("\npci2220i Unsolicited interrupt\n"));
1700 padapter
->expectingIRQ
= 0;
1702 if ( padapter
->failinprog
)
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
) )
1709 DEB (printk ("\npci2220i: interrupt failover error from drive %X", status
));
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);
1720 Pci2220i_QueueCommand (SCpnt
, SCpnt
->scsi_done
);
1725 if ( padapter
->reconPhase
)
1727 switch ( padapter
->reconPhase
)
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
)
1735 if ( status
& (IDE_STATUS_ERROR
| IDE_STATUS_WRITE_FAULT
) )
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
));
1743 if ( WriteSignature (padapter
, pdev
, pdev
->spigots
[pdev
->mirrorRecon
], pdev
->mirrorRecon
) )
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
));
1751 padapter
->reconPhase
= RECON_PHASE_END
;
1754 OpDone (padapter
, DID_OK
<< 16);
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
) )
1761 del_timer (&padapter
->timer
);
1762 OpDone (padapter
, DecodeError (padapter
, status
));
1765 SelectSpigot (padapter
, pdev
->spigots
[pdev
->mirrorRecon
]);
1766 if ( WaitDrq (padapter
) )
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
));
1775 SelectSpigot (padapter
, pdev
->spigot
| SEL_COPY
| padapter
->bigD
);
1776 padapter
->reconPhase
= RECON_PHASE_COPY
;
1777 padapter
->expectingIRQ
= TRUE
;
1778 if ( padapter
->timingPIO
)
1780 insw (padapter
->regData
, padapter
->kBuffer
, padapter
->reconSize
* (BYTES_PER_SECTOR
/ 2));
1784 if ( (padapter
->timingMode
> 3) )
1786 if ( padapter
->bigD
)
1787 outl (BIGD_DATA_MODE3
, padapter
->regDmaAddrLoc
);
1789 outl (DALE_DATA_MODE3
, padapter
->regDmaAddrLoc
);
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
1799 outb_p (1, padapter
->regDmaMode
); // no interrupt
1800 outb_p (0x03, padapter
->regDmaCmdStat
); // kick the DMA engine in gear
1804 case RECON_PHASE_COPY
:
1805 pdev
->DiskMirror
[pdev
->mirrorRecon
].reconstructPoint
+= padapter
->reconSize
;
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
) )
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
));
1820 OpDone (padapter
, DID_OK
<< 16);
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
) )
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
));
1835 if ( padapter
->bigD
)
1837 for ( z
= 0; z
< padapter
->numberOfDrives
; z
++ )
1839 if ( padapter
->device
[z
].DiskMirror
[0].status
& UCBF_SURVIVOR
)
1841 Alarm (padapter
, padapter
->device
[z
].deviceID
[0] ^ 2);
1842 MuteAlarm (padapter
);
1844 if ( padapter
->device
[z
].DiskMirror
[1].status
& UCBF_SURVIVOR
)
1846 Alarm (padapter
, padapter
->device
[z
].deviceID
[1] ^ 2);
1847 MuteAlarm (padapter
);
1851 OpDone (padapter
, DID_OK
<< 16);
1859 switch ( padapter
->cmd
) // decide how to handle the interrupt
1862 if ( padapter
->sectorCount
)
1864 status
= inb_p (padapter
->regStatCmd
); // read the device status
1865 if ( status
& (IDE_STATUS_ERROR
| IDE_STATUS_WRITE_FAULT
) )
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
) )
1877 if ( padapter
->timingPIO
)
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
)
1890 if ( padapter
->readCount
)
1891 WalkScatGath (padapter
, TRUE
, padapter
->readCount
);
1892 BusMaster (padapter
, 1, 1);
1894 padapter
->expectingIRQ
= TRUE
;
1897 if ( padapter
->readCount
&& !padapter
->timingPIO
)
1898 WalkScatGath (padapter
, TRUE
, padapter
->readCount
);
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
1911 SelectSpigot (padapter
, pdev
->spigot
| SEL_IRQ_OFF
);
1912 status
= inb_p (padapter
->regStatCmd
); // read the device status
1915 if ( status
& (IDE_STATUS_ERROR
| IDE_STATUS_WRITE_FAULT
) )
1917 if ( pdev
->raid
&& !(status1
& (IDE_STATUS_ERROR
| IDE_STATUS_WRITE_FAULT
)) )
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
) )
1930 if ( status1
& (IDE_STATUS_ERROR
| IDE_STATUS_WRITE_FAULT
) )
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
) )
1940 if ( padapter
->sectorCount
)
1942 status
= WriteDataBoth (padapter
, pdev
);
1945 padapter
->survivor
= status
>> 1;
1946 del_timer (&padapter
->timer
);
1947 DEB (printk ("\npci2220i: FAILURE 18"));
1948 if ( !InitFailover (padapter
, pdev
) )
1950 SelectSpigot (padapter
, pdev
->spigots
[status
] | SEL_IRQ_OFF
);
1951 status
= inb_p (padapter
->regStatCmd
); // read the device status
1954 padapter
->expectingIRQ
= TRUE
;
1960 if ( padapter
->sectorCount
)
1962 SelectSpigot (padapter
, pdev
->spigot
| padapter
->bigD
);
1963 status
= WriteData (padapter
);
1966 padapter
->expectingIRQ
= TRUE
;
1972 case IDE_COMMAND_IDENTIFY
:
1974 PINQUIRYDATA pinquiryData
= SCpnt
->request_buffer
;
1975 PIDENTIFY_DATA pid
= (PIDENTIFY_DATA
)padapter
->kBuffer
;
1977 status
= inb_p (padapter
->regStatCmd
);
1978 if ( status
& IDE_STATUS_DRQ
)
1980 insw (padapter
->regData
, pid
, sizeof (IDENTIFY_DATA
) >> 1);
1982 memset (pinquiryData
, 0, SCpnt
->request_bufflen
); // Zero INQUIRY data structure.
1983 pinquiryData
->DeviceType
= 0;
1984 pinquiryData
->Versions
= 2;
1985 pinquiryData
->AdditionalLength
= 35 - 4;
1987 // Fill in vendor identification fields.
1988 for ( z
= 0; z
< 20; z
+= 2 )
1990 pinquiryData
->VendorId
[z
] = ((UCHAR
*)pid
->ModelNumber
)[z
+ 1];
1991 pinquiryData
->VendorId
[z
+ 1] = ((UCHAR
*)pid
->ModelNumber
)[z
];
1994 // Initialize unused portion of product id.
1995 for ( z
= 0; z
< 4; z
++ )
1996 pinquiryData
->ProductId
[12 + z
] = ' ';
1998 // Move firmware revision from IDENTIFY data to
1999 // product revision in INQUIRY data.
2000 for ( z
= 0; z
< 4; z
+= 2 )
2002 pinquiryData
->ProductRevisionLevel
[z
] = ((UCHAR
*)pid
->FirmwareRevision
)[z
+ 1];
2003 pinquiryData
->ProductRevisionLevel
[z
+ 1] = ((UCHAR
*)pid
->FirmwareRevision
)[z
];
2005 if ( pdev
== padapter
->device
)
2006 *((USHORT
*)(&pinquiryData
->VendorSpecific
)) = DEVICE_DALE_1
;
2018 del_timer (&padapter
->timer
);
2021 DEB (printk ("\npci2220i Interrupt handler return error"));
2022 zl
= DecodeError (padapter
, status
);
2027 OpDone (padapter
, zl
);
2029 spin_unlock_irqrestore(shost
->host_lock
, flags
);
2031 return IRQ_RETVAL(handled
);
2034 /****************************************************************
2035 * Name: Pci2220i_QueueCommand
2037 * Description: Process a queued command from the SCSI manager.
2039 * Parameters: SCpnt - Pointer to SCSI command structure.
2040 * done - Pointer to done function to call.
2042 * Returns: Status code.
2044 ****************************************************************/
2045 int Pci2220i_QueueCommand (Scsi_Cmnd
*SCpnt
, void (*done
)(Scsi_Cmnd
*))
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
2054 SCpnt
->scsi_done
= done
;
2055 padapter
->SCpnt
= SCpnt
; // Save this command data
2056 padapter
->readCount
= 0;
2058 if ( SCpnt
->use_sg
)
2060 padapter
->currentSgBuffer
= ((struct scatterlist
*)SCpnt
->request_buffer
)[0].address
;
2061 padapter
->currentSgCount
= ((struct scatterlist
*)SCpnt
->request_buffer
)[0].length
;
2065 padapter
->currentSgBuffer
= SCpnt
->request_buffer
;
2066 padapter
->currentSgCount
= SCpnt
->request_bufflen
;
2068 padapter
->nextSg
= 1;
2072 printk("pci2220i_queuecommand: %02X: done can't be NULL\n", *cdb
);
2076 if ( padapter
->atapi
)
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
)
2084 OpDone (padapter
, DID_BAD_TARGET
<< 16);
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) )
2095 OpDone (padapter
, DID_NO_CONNECT
<< 16);
2101 case SCSIOP_MODE_SENSE
:
2102 case SCSIOP_MODE_SELECT
:
2103 Scsi2Atapi (padapter
, SCpnt
);
2104 z
= SCpnt
->request_bufflen
+ 4;
2108 Scsi2Atapi (padapter
, SCpnt
);
2109 z
= SCpnt
->request_bufflen
;
2112 memcpy (padapter
->atapiCdb
, cdb
, SCpnt
->cmd_len
);
2113 z
= SCpnt
->request_bufflen
;
2116 if ( z
> ATAPI_TRANSFER
)
2118 zlo
= (UCHAR
)(z
& 0xFF);
2119 zhi
= (UCHAR
)(z
>> 8);
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
)
2128 if ( AtapiWaitDrq (padapter
, 500) )
2130 OpDone (padapter
, DID_ERROR
<< 16);
2133 AtapiSendCdb (padapter
, pdev
, padapter
->atapiCdb
);
2137 if ( padapter
->reconPhase
)
2139 if ( padapter
->reconTimer
.data
)
2141 del_timer (&padapter
->reconTimer
);
2142 padapter
->reconTimer
.data
= 0;
2145 if ( (SCpnt
->device
->id
>= padapter
->numberOfDrives
) || SCpnt
->device
->lun
)
2147 OpDone (padapter
, DID_BAD_TARGET
<< 16);
2153 case SCSIOP_INQUIRY
: // inquiry CDB
2155 if ( cdb
[2] == SC_MY_RAID
)
2159 case MY_SCSI_REBUILD
:
2160 for ( z
= 0; z
< padapter
->numberOfDrives
; z
++ )
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
)) )
2166 padapter
->reconOn
= pdev
->reconOn
= pdev
->reconIsStarting
= TRUE
;
2169 OpDone (padapter
, DID_OK
<< 16);
2171 case MY_SCSI_ALARMMUTE
:
2172 MuteAlarm (padapter
);
2173 OpDone (padapter
, DID_OK
<< 16);
2175 case MY_SCSI_DEMOFAIL
:
2176 padapter
->demoFail
= TRUE
;
2177 OpDone (padapter
, DID_OK
<< 16);
2180 z
= cdb
[5]; // get index
2181 pdr
= (PDEVICE_RAID1
)SCpnt
->request_buffer
;
2182 if ( padapter
->raidData
[z
] )
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
;
2188 pdr
->TotalSectors
= padapter
->raidData
[z
^ 2]->reconstructPoint
;
2191 memset (pdr
, 0, sizeof (DEVICE_RAID1
));
2192 OpDone (padapter
, DID_OK
<< 16);
2197 padapter
->cmd
= IDE_COMMAND_IDENTIFY
;
2201 case SCSIOP_TEST_UNIT_READY
: // test unit ready CDB
2202 OpDone (padapter
, DID_OK
<< 16);
2204 case SCSIOP_READ_CAPACITY
: // read capctiy CDB
2206 PREAD_CAPACITY_DATA pdata
= (PREAD_CAPACITY_DATA
)SCpnt
->request_buffer
;
2208 pdata
->blksiz
= 0x20000;
2209 XANY2SCSI ((UCHAR
*)&pdata
->blks
, pdev
->blocks
);
2210 OpDone (padapter
, DID_OK
<< 16);
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
;
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
;
2223 case SCSIOP_READ6
: // read6 CDB
2224 padapter
->startSector
= SCSI2LONG (&cdb
[1]);
2225 padapter
->sectorCount
= cdb
[4];
2226 padapter
->cmd
= READ_CMD
;
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
;
2233 case SCSIOP_WRITE6
: // write6 CDB
2234 padapter
->startSector
= SCSI2LONG (&cdb
[1]);
2235 padapter
->sectorCount
= cdb
[4];
2236 padapter
->cmd
= WRITE_CMD
;
2239 DEB (printk ("pci2220i_queuecommand: Unsupported command %02X\n", *cdb
));
2240 OpDone (padapter
, DID_ERROR
<< 16);
2244 if ( padapter
->reconPhase
)
2247 padapter
->pdev
= pdev
;
2249 while ( padapter
->demoFail
)
2251 pdev
= padapter
->pdev
= &padapter
->device
[0];
2252 padapter
->demoFail
= FALSE
;
2254 (pdev
->DiskMirror
[0].status
& UCBF_SURVIVOR
) ||
2255 (pdev
->DiskMirror
[1].status
& UCBF_SURVIVOR
) )
2259 if ( pdev
->DiskMirror
[0].status
& UCBF_REBUILD
)
2260 padapter
->survivor
= 1;
2262 padapter
->survivor
= 0;
2263 DEB (printk ("\npci2220i: FAILURE 19"));
2264 if ( InitFailover (padapter
, pdev
) )
2269 StartTimer (padapter
);
2270 if ( pdev
->raid
&& (padapter
->cmd
== WRITE_CMD
) )
2272 rc
= IdeCmdBoth (padapter
, pdev
);
2274 rc
= WriteDataBoth (padapter
, pdev
);
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
) )
2283 OpDone (padapter
, DID_ERROR
<< 16);
2290 rc
= IdeCmd (padapter
, pdev
);
2291 if ( (padapter
->cmd
== WRITE_CMD
) && !rc
)
2292 rc
= WriteData (padapter
);
2295 del_timer (&padapter
->timer
);
2296 padapter
->expectingIRQ
= 0;
2299 padapter
->survivor
= (pdev
->spigot
^ 3) >> 1;
2300 DEB (printk ("\npci2220i: FAILURE 21"));
2301 if ( !InitFailover (padapter
, pdev
) )
2304 OpDone (padapter
, DID_ERROR
<< 16);
2310 /****************************************************************
2313 * Description: Read information from controller Flash memory.
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.
2322 ****************************************************************/
2323 static VOID
ReadFlash (PADAPTER2220I padapter
, VOID
*pdata
, ULONG base
, ULONG length
)
2328 UCHAR
*pd
= (UCHAR
*)pdata
;
2330 oldremap
= inl (padapter
->regRemap
); // save values to restore later
2331 olddesc
= inb_p (padapter
->regDesc
);
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
2338 outl (oldremap
, padapter
->regRemap
); // restore remap register values
2339 outb_p (olddesc
, padapter
->regDesc
);
2341 /****************************************************************
2344 * Description: Initialize the regester information.
2346 * Parameters: pshost - Pointer to SCSI host data structure.
2347 * bigd - PCI-2240I identifier
2348 * pcidev - Pointer to device data structure.
2350 * Returns: TRUE if failure to install.
2352 ****************************************************************/
2353 static USHORT
GetRegs (struct Scsi_Host
*pshost
, BOOL bigd
, struct pci_dev
*pcidev
)
2355 PADAPTER2220I padapter
;
2360 dma_addr_t consistentDma
;
2362 padapter
= HOSTDATA(pshost
);
2363 memset (padapter
, 0, sizeof (ADAPTER2220I
));
2364 memset (&DaleSetup
, 0, sizeof (DaleSetup
));
2365 memset (DiskMirror
, 0, sizeof (DiskMirror
));
2367 zr
= pci_resource_start (pcidev
, 1);
2368 zl
= pci_resource_start (pcidev
, 2);
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
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
;
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
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
2411 padapter
->numberOfDrives
= inb_p (padapter
->regScratchPad
+ BIGD_NUM_DRIVES
);
2412 if ( !bigd
&& !padapter
->numberOfDrives
) // if no devices on this board
2415 pshost
->irq
= pcidev
->irq
;
2417 for ( z
= 0; z
< Installed
; z
++ ) // scan for shared interrupts
2419 if ( PsiHost
[z
]->irq
== pshost
->irq
) // if shared then, don't posses
2422 if ( setirq
) // if not shared, posses
2424 if ( request_irq (pshost
->irq
, Irq_Handler
, SA_SHIRQ
, "pci2220i", padapter
) < 0 )
2426 if ( request_irq (pshost
->irq
, Irq_Handler
, SA_INTERRUPT
| SA_SHIRQ
, "pci2220i", padapter
) < 0 )
2428 printk ("Unable to allocate IRQ for PCI-2220I controller.\n");
2432 padapter
->irqOwned
= pshost
->irq
; // set IRQ as owned
2435 if ( padapter
->numberOfDrives
)
2436 consistent
= pci_alloc_consistent (pcidev
, SECTORSXFER
* BYTES_PER_SECTOR
, &consistentDma
);
2438 consistent
= pci_alloc_consistent (pcidev
, ATAPI_TRANSFER
, &consistentDma
);
2441 printk ("Unable to allocate DMA buffer for PCI-2220I controller.\n");
2442 free_irq (pshost
->irq
, padapter
);
2445 padapter
->kBuffer
= consistent
;
2446 padapter
->kBufferDma
= consistentDma
;
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
;
2453 outb_p (0x01, padapter
->regRange
); // fix our range register because other drivers want to tromp on it
2455 padapter
->timingMode
= inb_p (padapter
->regScratchPad
+ DALE_TIMING_MODE
);
2456 if ( padapter
->timingMode
>= 2 )
2459 padapter
->timingAddress
= ModeArray2
[padapter
->timingMode
- 2];
2461 padapter
->timingAddress
= ModeArray
[padapter
->timingMode
- 2];
2464 padapter
->timingPIO
= TRUE
;
2466 ReadFlash (padapter
, &DaleSetup
, DALE_FLASH_SETUP
, sizeof (SETUP
));
2467 ReadFlash (padapter
, &DiskMirror
, DALE_FLASH_RAID
, sizeof (DiskMirror
));
2471 /****************************************************************
2474 * Description: Complete the driver initialization process for a card
2476 * Parameters: padapter - Pointer to SCSI host data structure.
2477 * str - Pointer to board type string.
2481 ****************************************************************/
2482 VOID
SetupFinish (PADAPTER2220I padapter
, char *str
, int irq
)
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__
);
2493 /****************************************************************
2494 * Name: Pci2220i_Detect
2496 * Description: Detect and initialize our boards.
2498 * Parameters: tpnt - Pointer to SCSI host template structure.
2500 * Returns: Number of adapters installed.
2502 ****************************************************************/
2503 int Pci2220i_Detect (Scsi_Host_Template
*tpnt
)
2505 struct Scsi_Host
*pshost
;
2506 PADAPTER2220I padapter
;
2511 UCHAR spigot1
, spigot2
;
2513 struct pci_dev
*pcidev
= NULL
;
2515 while ( (pcidev
= pci_find_device (VENDOR_PSI
, DEVICE_DALE_1
, pcidev
)) != NULL
)
2517 if (pci_enable_device(pcidev
))
2519 pshost
= scsi_register (tpnt
, sizeof(ADAPTER2220I
));
2523 padapter
= HOSTDATA(pshost
);
2525 if ( GetRegs (pshost
, FALSE
, pcidev
) )
2528 scsi_set_device(pshost
, &pcidev
->dev
);
2529 pshost
->max_id
= padapter
->numberOfDrives
;
2530 for ( z
= 0; z
< padapter
->numberOfDrives
; z
++ )
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
;
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)) )
2549 if ( unit
> (unit
^ 2) )
2555 memcpy (pdev
->DiskMirror
, DiskMirror
, sizeof (DiskMirror
));
2556 padapter
->raidData
[0] = &pdev
->DiskMirror
[0];
2557 padapter
->raidData
[2] = &pdev
->DiskMirror
[1];
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);
2565 if ( !(pdev
->DiskMirror
[1].status
& UCBF_SURVIVOR
) && pdev
->lastsectorlba
[0] )
2567 if ( !(pdev
->DiskMirror
[0].status
& UCBF_SURVIVOR
) && pdev
->lastsectorlba
[1] )
2569 if ( pdev
->DiskMirror
[0].status
& DiskMirror
[1].status
& UCBF_SURVIVOR
)
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);
2577 if ( spigot1
&& spigot2
&& raidon
)
2580 if ( pdev
->DiskMirror
[0].status
& UCBF_REBUILD
)
2584 if ( (pdev
->DiskMirror
[0].status
& UCBF_REBUILD
) || (pdev
->DiskMirror
[1].status
& UCBF_REBUILD
) )
2585 padapter
->reconOn
= pdev
->reconOn
= pdev
->reconIsStarting
= TRUE
;
2591 if ( pdev
->DiskMirror
[0].status
& UCBF_REBUILD
)
2593 pdev
->DiskMirror
[0].status
= UCBF_MIRRORED
| UCBF_SURVIVOR
;
2598 if ( pdev
->DiskMirror
[1].status
& UCBF_REBUILD
)
2600 pdev
->DiskMirror
[1].status
= UCBF_MIRRORED
| UCBF_SURVIVOR
;
2603 if ( DaleSetup
.rebootRebuild
&& raidon
)
2604 padapter
->reconOn
= pdev
->reconOn
= pdev
->reconIsStarting
= TRUE
;
2612 SetupFinish (padapter
, "2220", pshost
->irq
);
2614 if ( ++Installed
< MAXADAPTER
)
2618 scsi_unregister (pshost
);
2621 while ( (pcidev
= pci_find_device (VENDOR_PSI
, DEVICE_BIGD_1
, pcidev
)) != NULL
)
2623 pshost
= scsi_register (tpnt
, sizeof(ADAPTER2220I
));
2624 padapter
= HOSTDATA(pshost
);
2626 if ( GetRegs (pshost
, TRUE
, pcidev
) )
2629 for ( z
= 0; z
< BIGD_MAXDRIVES
; z
++ )
2630 DiskMirror
[z
].status
= inb_p (padapter
->regScratchPad
+ BIGD_RAID_0_STATUS
+ z
);
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
++ )
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
;
2646 if ( (DiskMirror
[unit
].signature
== SIGNATURE
) && (DiskMirror
[unit
^ 2].signature
== SIGNATURE
) &&
2647 (DiskMirror
[unit
].pairIdentifier
== (DiskMirror
[unit
^ 2].pairIdentifier
^ 1)) )
2650 if ( unit
> (unit
^ 2) )
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);
2668 if ( !(pdev
->DiskMirror
[1].status
& UCBF_SURVIVOR
) && pdev
->lastsectorlba
[0] )
2670 if ( !(pdev
->DiskMirror
[0].status
& UCBF_SURVIVOR
) && pdev
->lastsectorlba
[1] )
2672 if ( pdev
->DiskMirror
[0].status
& pdev
->DiskMirror
[1].status
& UCBF_SURVIVOR
)
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);
2680 if ( spigot1
&& spigot2
&& raidon
)
2683 if ( pdev
->DiskMirror
[0].status
& UCBF_REBUILD
)
2684 pdev
->spigot
= pdev
->spigots
[1];
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
;
2694 if ( pdev
->DiskMirror
[0].status
& UCBF_REBUILD
)
2696 pdev
->DiskMirror
[0].status
= UCBF_MIRRORED
| UCBF_SURVIVOR
;
2697 pdev
->spigot
= pdev
->spigots
[0];
2701 if ( pdev
->DiskMirror
[1].status
& UCBF_REBUILD
)
2703 pdev
->DiskMirror
[1].status
= UCBF_MIRRORED
| UCBF_SURVIVOR
;
2704 pdev
->spigot
= pdev
->spigots
[1];
2706 if ( DaleSetup
.rebootRebuild
&& raidon
)
2707 padapter
->reconOn
= pdev
->reconOn
= pdev
->reconIsStarting
= TRUE
;
2711 if ( !padapter
->numberOfDrives
) // If no ATA devices then scan ATAPI
2714 for ( spigot1
= 0; spigot1
< 4; spigot1
++ )
2716 for ( device
= 0; device
< 2; device
++ )
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
) )
2724 DEB (printk (" Device found "));
2725 if ( !AtapiIdentify (padapter
, pdev
) )
2727 DEB (printk (" Device verified"));
2732 pdev
->spigot
= pdev
->byte6
= 0;
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
2746 SetupFinish (padapter
, "2240", pshost
->irq
);
2748 if ( ++Installed
< MAXADAPTER
)
2752 scsi_unregister (pshost
);
2755 NumAdapters
= Installed
;
2758 /****************************************************************
2759 * Name: Pci2220i_Abort
2761 * Description: Process the Abort command from the SCSI manager.
2763 * Parameters: SCpnt - Pointer to SCSI command structure.
2765 * Returns: Allways snooze.
2767 ****************************************************************/
2768 int Pci2220i_Abort (Scsi_Cmnd
*SCpnt
)
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
2773 if ( !padapter
->SCpnt
)
2774 return SCSI_ABORT_NOT_RUNNING
;
2776 if ( padapter
->atapi
)
2778 if ( AtapiReset (padapter
, pdev
) )
2779 return SCSI_ABORT_ERROR
;
2780 OpDone (padapter
, DID_ABORT
<< 16);
2781 return SCSI_ABORT_SUCCESS
;
2783 return SCSI_ABORT_SNOOZE
;
2785 /****************************************************************
2786 * Name: Pci2220i_Reset
2788 * Description: Process the Reset command from the SCSI manager.
2790 * Parameters: SCpnt - Pointer to SCSI command structure.
2791 * flags - Flags about the reset command
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
2799 ****************************************************************/
2800 int Pci2220i_Reset (Scsi_Cmnd
*SCpnt
, unsigned int reset_flags
)
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
2805 if ( padapter
->atapi
)
2807 if ( AtapiReset (padapter
, pdev
) )
2808 return SCSI_RESET_ERROR
;
2809 return SCSI_RESET_SUCCESS
;
2811 return SCSI_RESET_PUNT
;
2813 /****************************************************************
2814 * Name: Pci2220i_Release
2816 * Description: Release resources allocated for a single each adapter.
2818 * Parameters: pshost - Pointer to SCSI command structure.
2822 ****************************************************************/
2823 int Pci2220i_Release (struct Scsi_Host
*pshost
)
2825 PADAPTER2220I padapter
= HOSTDATA (pshost
);
2828 if ( padapter
->reconOn
)
2830 padapter
->reconOn
= FALSE
; // shut down the hot reconstruct
2831 if ( padapter
->reconPhase
)
2833 if ( padapter
->reconTimer
.data
) // is the timer running?
2835 del_timer (&padapter
->reconTimer
);
2836 padapter
->reconTimer
.data
= 0;
2840 // save RAID status on the board
2841 if ( padapter
->bigD
)
2843 outb_p (padapter
->failRegister
, padapter
->regScratchPad
+ BIGD_ALARM_IMAGE
);
2844 for ( z
= 0; z
< BIGD_MAXDRIVES
; z
++ )
2846 if ( padapter
->raidData
)
2847 outb_p (padapter
->raidData
[z
]->status
, padapter
->regScratchPad
+ BIGD_RAID_0_STATUS
+ z
);
2849 outb_p (0, padapter
->regScratchPad
+ BIGD_RAID_0_STATUS
);
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
);
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
);
2864 pci_free_consistent (padapter
->pcidev
, ATAPI_TRANSFER
, padapter
->kBuffer
, padapter
->kBufferDma
);
2865 scsi_unregister(pshost
);
2869 /****************************************************************
2870 * Name: Pci2220i_BiosParam
2872 * Description: Process the biosparam request from the SCSI manager to
2873 * return C/H/S data.
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.
2881 ****************************************************************/
2882 int Pci2220i_BiosParam (struct scsi_device
*sdev
, struct block_device
*dev
,
2883 sector_t capacity
, int geom
[])
2887 if ( !(HOSTDATA(sdev
->host
))->atapi
)
2889 pdev
= &(HOSTDATA(sdev
->host
)->device
[sdev
->id
]);
2891 geom
[0] = pdev
->heads
;
2892 geom
[1] = pdev
->sectors
;
2893 geom
[2] = pdev
->cylinders
;
2898 MODULE_LICENSE("Dual BSD/GPL");
2900 static 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
,
2911 .sg_tablesize
= SG_ALL
,
2913 .use_clustering
= DISABLE_CLUSTERING
,
2915 #include "scsi_module.c"