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 //#define DEBUG 1
38 
39 #include <linux/module.h>
40 #include <linux/kernel.h>
41 #include <linux/types.h>
42 #include <linux/string.h>
43 #include <linux/slab.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/kdev_t.h>
51 #include <linux/blk.h>
52 #include <linux/timer.h>
53 #include <linux/spinlock.h>
54 #include <asm/dma.h>
55 #include <asm/system.h>
56 #include <asm/io.h>
57 #include "scsi.h"
58 #include "hosts.h"
59 #include "pci2220i.h"
60 #include "psi_dale.h"
61 
62 
63 #define	PCI2220I_VERSION		"2.10"
64 #define	READ_CMD				IDE_CMD_READ_MULTIPLE
65 #define	WRITE_CMD				IDE_CMD_WRITE_MULTIPLE
66 #define	MAX_BUS_MASTER_BLOCKS	SECTORSXFER		// This is the maximum we can bus master
67 
68 #ifdef DEBUG
69 #define DEB(x) x
70 #define STOP_HERE()	{int st;for(st=0;st<100;st++){st=1;}}
71 #else
72 #define DEB(x)
73 #define STOP_HERE()
74 #endif
75 
76 #define MAXADAPTER 4					// Increase this and the sizes of the arrays below, if you need more.
77 
78 
79 typedef struct
80 	{
81 	UCHAR			byte6;				// device select register image
82 	UCHAR			spigot;				// spigot number
83 	UCHAR			spigots[2];			// RAID spigots
84 	UCHAR			deviceID[2];		// device ID codes
85 	USHORT			sectors;			// number of sectors per track
86 	USHORT			heads;				// number of heads
87 	USHORT			cylinders;			// number of cylinders for this device
88 	USHORT			spareword;			// placeholder
89 	ULONG			blocks;				// number of blocks on device
90 	DISK_MIRROR		DiskMirror[2];		// RAID status and control
91 	ULONG			lastsectorlba[2];	// last addressable sector on the drive
92 	USHORT			raid;				// RAID active flag
93 	USHORT			mirrorRecon;
94 	UCHAR			reconOn;
95 	USHORT			reconCount;
96 	USHORT			reconIsStarting;	// indicate hot reconstruct is starting
97 	UCHAR			cmdDrqInt;			// flag for command interrupt
98 	UCHAR			packet;				// command packet size in bytes
99 	}	OUR_DEVICE, *POUR_DEVICE;
100 
101 typedef struct
102 	{
103 	USHORT		 bigD;					// identity is a PCI-2240I if true, otherwise a PCI-2220I
104 	USHORT		 atapi;					// this interface is for ATAPI devices only
105 	ULONG		 regDmaDesc;			// address of the DMA discriptor register for direction of transfer
106 	ULONG		 regDmaCmdStat;			// Byte #1 of DMA command status register
107 	ULONG		 regDmaAddrPci;			// 32 bit register for PCI address of DMA
108 	ULONG		 regDmaAddrLoc;			// 32 bit register for local bus address of DMA
109 	ULONG		 regDmaCount;			// 32 bit register for DMA transfer count
110 	ULONG		 regDmaMode;			// 32 bit register for DMA mode control
111 	ULONG		 regRemap;				// 32 bit local space remap
112 	ULONG		 regDesc;				// 32 bit local region descriptor
113 	ULONG		 regRange;				// 32 bit local range
114 	ULONG		 regIrqControl;			// 16 bit Interrupt enable/disable and status
115 	ULONG		 regScratchPad;			// scratch pad I/O base address
116 	ULONG		 regBase;				// Base I/O register for data space
117 	ULONG		 regData;				// data register I/O address
118 	ULONG		 regError;				// error register I/O address
119 	ULONG		 regSectCount;			// sector count register I/O address
120 	ULONG		 regLba0;				// least significant byte of LBA
121 	ULONG		 regLba8;				// next least significant byte of LBA
122 	ULONG		 regLba16;				// next most significan byte of LBA
123 	ULONG		 regLba24;				// head and most 4 significant bits of LBA
124 	ULONG		 regStatCmd;			// status on read and command on write register
125 	ULONG		 regStatSel;			// board status on read and spigot select on write register
126 	ULONG		 regFail;				// fail bits control register
127 	ULONG		 regAltStat;			// alternate status and drive control register
128 	ULONG		 basePort;				// PLX base I/O port
129 	USHORT		 timingMode;			// timing mode currently set for adapter
130 	USHORT		 timingPIO;				// TRUE if PIO timing is active
131 	struct pci_dev	*pcidev;
132 	ULONG		 timingAddress;			// address to use on adapter for current timing mode
133 	ULONG		 irqOwned;				// owned IRQ or zero if shared
134 	UCHAR		 numberOfDrives;		// saved number of drives on this controller
135 	UCHAR		 failRegister;			// current inverted data in fail register
136 	OUR_DEVICE	 device[BIGD_MAXDRIVES];
137 	DISK_MIRROR	*raidData[BIGD_MAXDRIVES];
138 	ULONG		 startSector;
139 	USHORT		 sectorCount;
140 	ULONG		 readCount;
141 	UCHAR		*currentSgBuffer;
142 	ULONG		 currentSgCount;
143 	USHORT		 nextSg;
144 	UCHAR		 cmd;
145 	Scsi_Cmnd	*SCpnt;
146 	POUR_DEVICE	 pdev;					// current device opearating on
147 	USHORT		 devInReconIndex;
148 	USHORT		 expectingIRQ;
149 	USHORT		 reconOn;				// Hot reconstruct is to be done.
150 	USHORT		 reconPhase;			// Hot reconstruct operation is in progress.
151 	ULONG		 reconSize;
152 	USHORT		 demoFail;				// flag for RAID failure demonstration
153 	USHORT		 survivor;
154 	USHORT		 failinprog;
155 	struct timer_list	reconTimer;
156 	struct timer_list	timer;
157 	UCHAR		*kBuffer;
158 	dma_addr_t	 kBufferDma;
159 	UCHAR		 reqSense;
160 	UCHAR		 atapiCdb[16];
161 	UCHAR		 atapiSpecial;
162 	}	ADAPTER2220I, *PADAPTER2220I;
163 
164 #define HOSTDATA(host) ((PADAPTER2220I)&host->hostdata)
165 
166 #define	RECON_PHASE_READY		0x01
167 #define	RECON_PHASE_COPY		0x02
168 #define	RECON_PHASE_UPDATE		0x03
169 #define	RECON_PHASE_LAST		0x04
170 #define	RECON_PHASE_END			0x07
171 #define	RECON_PHASE_MARKING		0x80
172 #define	RECON_PHASE_FAILOVER	0xFF
173 
174 static struct	Scsi_Host 	   *PsiHost[MAXADAPTER] = {NULL,};  // One for each adapter
175 static			int				NumAdapters = 0;
176 static			int				Installed = 0;
177 static			SETUP			DaleSetup;
178 static			DISK_MIRROR		DiskMirror[BIGD_MAXDRIVES];
179 static			ULONG			ModeArray[] = {DALE_DATA_MODE2, DALE_DATA_MODE3, DALE_DATA_MODE4, DALE_DATA_MODE5};
180 static			ULONG			ModeArray2[] = {BIGD_DATA_MODE2, BIGD_DATA_MODE3, BIGD_DATA_MODE4, BIGD_DATA_MODE5};
181 
182 static void ReconTimerExpiry (unsigned long data);
183 
184 /*******************************************************************************************************
185  *	Name:			Alarm
186  *
187  *	Description:	Sound the for the given device
188  *
189  *	Parameters:		padapter - Pointer adapter data structure.
190  *					device	 - Device number.
191  *
192  *	Returns:		Nothing.
193  *
194  ******************************************************************************************************/
Alarm(PADAPTER2220I padapter,UCHAR device)195 static void Alarm (PADAPTER2220I padapter, UCHAR device)
196 	{
197 	UCHAR	zc;
198 
199 	if ( padapter->bigD )
200 		{
201 		zc = device | (FAIL_ANY | FAIL_AUDIBLE);
202 		if ( padapter->failRegister & FAIL_ANY )
203 			zc |= FAIL_MULTIPLE;
204 
205 		padapter->failRegister = zc;
206 		outb_p (~zc, padapter->regFail);
207 		}
208 	else
209 		outb_p (0x3C | (1 << device), padapter->regFail);			// sound alarm and set fail light
210 	}
211 /****************************************************************
212  *	Name:	MuteAlarm	:LOCAL
213  *
214  *	Description:	Mute the audible alarm.
215  *
216  *	Parameters:		padapter - Pointer adapter data structure.
217  *
218  *	Returns:		TRUE if drive does not assert DRQ in time.
219  *
220  ****************************************************************/
MuteAlarm(PADAPTER2220I padapter)221 static void MuteAlarm (PADAPTER2220I padapter)
222 	{
223 	UCHAR	old;
224 
225 	if ( padapter->bigD )
226 		{
227 		padapter->failRegister &= ~FAIL_AUDIBLE;
228 		outb_p (~padapter->failRegister, padapter->regFail);
229 		}
230 	else
231 		{
232 		old = (inb_p (padapter->regStatSel) >> 3) | (inb_p (padapter->regStatSel) & 0x83);
233 		outb_p (old | 0x40, padapter->regFail);
234 		}
235 	}
236 /****************************************************************
237  *	Name:	WaitReady	:LOCAL
238  *
239  *	Description:	Wait for device ready.
240  *
241  *	Parameters:		padapter - Pointer adapter data structure.
242  *
243  *	Returns:		TRUE if drive does not assert DRQ in time.
244  *
245  ****************************************************************/
WaitReady(PADAPTER2220I padapter)246 static int WaitReady (PADAPTER2220I padapter)
247 	{
248 	ULONG	z;
249 	UCHAR	status;
250 
251 	for ( z = 0;  z < (TIMEOUT_READY * 4);  z++ )
252 		{
253 		status = inb_p (padapter->regStatCmd);
254 		if ( (status & (IDE_STATUS_DRDY | IDE_STATUS_BUSY)) == IDE_STATUS_DRDY )
255 			return 0;
256 		udelay (250);
257 		}
258 	return status;
259 	}
260 /****************************************************************
261  *	Name:	WaitReadyReset	:LOCAL
262  *
263  *	Description:	Wait for device ready.
264  *
265  *	Parameters:		padapter - Pointer adapter data structure.
266  *
267  *	Returns:		TRUE if drive does not assert DRQ in time.
268  *
269  ****************************************************************/
WaitReadyReset(PADAPTER2220I padapter)270 static int WaitReadyReset (PADAPTER2220I padapter)
271 	{
272 	ULONG	z;
273 	UCHAR	status;
274 
275 	for ( z = 0;  z < (125 * 16);  z++ )				// wait up to 1/4 second
276 		{
277 		status = inb_p (padapter->regStatCmd);
278 		if ( (status & (IDE_STATUS_DRDY | IDE_STATUS_BUSY)) == IDE_STATUS_DRDY )
279 			{
280 			DEB (printk ("\nPCI2220I:  Reset took %ld mSec to be ready", z / 8));
281 			return 0;
282 			}
283 		udelay (125);
284 		}
285 	DEB (printk ("\nPCI2220I:  Reset took more than 2 Seconds to come ready, Disk Failure"));
286 	return status;
287 	}
288 /****************************************************************
289  *	Name:	WaitDrq	:LOCAL
290  *
291  *	Description:	Wait for device ready for data transfer.
292  *
293  *	Parameters:		padapter - Pointer adapter data structure.
294  *
295  *	Returns:		TRUE if drive does not assert DRQ in time.
296  *
297  ****************************************************************/
WaitDrq(PADAPTER2220I padapter)298 static int WaitDrq (PADAPTER2220I padapter)
299 	{
300 	ULONG	z;
301 	UCHAR	status;
302 
303 	for ( z = 0;  z < (TIMEOUT_DRQ * 4);  z++ )
304 		{
305 		status = inb_p (padapter->regStatCmd);
306 		if ( status & IDE_STATUS_DRQ )
307 			return 0;
308 		udelay (250);
309 		}
310 	return status;
311 	}
312 /****************************************************************
313  *	Name:	AtapiWaitReady	:LOCAL
314  *
315  *	Description:	Wait for device busy and DRQ to be cleared.
316  *
317  *	Parameters:		padapter - Pointer adapter data structure.
318  *					msec	 - Number of milliseconds to wait.
319  *
320  *	Returns:		TRUE if drive does not clear busy in time.
321  *
322  ****************************************************************/
AtapiWaitReady(PADAPTER2220I padapter,int msec)323 static int AtapiWaitReady (PADAPTER2220I padapter, int msec)
324 	{
325 	int z;
326 
327 	for ( z = 0;  z < (msec * 16);  z++ )
328 		{
329 		if ( !(inb_p (padapter->regStatCmd) & (IDE_STATUS_BUSY | IDE_STATUS_DRQ)) )
330 			return FALSE;
331 		udelay (125);
332 		}
333 	return TRUE;
334 	}
335 /****************************************************************
336  *	Name:	AtapiWaitDrq	:LOCAL
337  *
338  *	Description:	Wait for device ready for data transfer.
339  *
340  *	Parameters:		padapter - Pointer adapter data structure.
341  *					msec	 - Number of milliseconds to wait.
342  *
343  *	Returns:		TRUE if drive does not assert DRQ in time.
344  *
345  ****************************************************************/
AtapiWaitDrq(PADAPTER2220I padapter,int msec)346 static int AtapiWaitDrq (PADAPTER2220I padapter, int msec)
347 	{
348 	ULONG	z;
349 
350 	for ( z = 0;  z < (msec * 16);  z++ )
351 		{
352 		if ( inb_p (padapter->regStatCmd) & IDE_STATUS_DRQ )
353 			return 0;
354 		udelay (128);
355 		}
356 	return TRUE;
357 	}
358 /****************************************************************
359  *	Name:	HardReset	:LOCAL
360  *
361  *	Description:	Wait for device ready for data transfer.
362  *
363  *	Parameters:		padapter - Pointer adapter data structure.
364  *					pdev	 - Pointer to device.
365  *					spigot	 - Spigot number.
366  *
367  *	Returns:		TRUE if drive does not assert DRQ in time.
368  *
369  ****************************************************************/
HardReset(PADAPTER2220I padapter,POUR_DEVICE pdev,UCHAR spigot)370 static int HardReset (PADAPTER2220I padapter, POUR_DEVICE pdev, UCHAR spigot)
371 	{
372 	DEB (printk ("\npci2220i:RESET  spigot = %X  devices = %d, %d", spigot, pdev->deviceID[0], pdev->deviceID[1]));
373 	mdelay (100);										// just wait 100 mSec to let drives flush
374 	SelectSpigot (padapter, spigot | SEL_IRQ_OFF);
375 
376 	outb_p (0x0E, padapter->regAltStat);					// reset the suvivor
377 	udelay (100);											// wait a little
378 	outb_p (0x08, padapter->regAltStat);					// clear the reset
379 	udelay (100);
380 
381 	outb_p (0xA0, padapter->regLba24);						// select the master drive
382 	if ( WaitReadyReset (padapter) )
383 		{
384 		DEB (printk ("\npci2220i: master not ready after reset"));
385 		return TRUE;
386 		}
387 	outb_p (0xB0, padapter->regLba24);						// try the slave drive
388 	if ( (inb_p (padapter->regStatCmd) & (IDE_STATUS_DRDY | IDE_STATUS_BUSY)) == IDE_STATUS_DRDY )
389 		{
390 		DEB (printk ("\nPCI2220I: initializing slave drive on spigot %X", spigot));
391 		outb_p (SECTORSXFER, padapter->regSectCount);
392 		WriteCommand (padapter, IDE_CMD_SET_MULTIPLE);
393 		if ( WaitReady (padapter) )
394 			{
395 			DEB (printk ("\npci2220i: slave not ready after set multiple"));
396 			return TRUE;
397 			}
398 		}
399 
400 	outb_p (0xA0, padapter->regLba24);				// select the drive
401 	outb_p (SECTORSXFER, padapter->regSectCount);
402 	WriteCommand (padapter, IDE_CMD_SET_MULTIPLE);
403 	if ( WaitReady (padapter) )
404 		{
405 		DEB (printk ("\npci2220i: master not ready after set multiple"));
406 		return TRUE;
407 		}
408 	return FALSE;
409 	}
410 /****************************************************************
411  *	Name:	AtapiReset	:LOCAL
412  *
413  *	Description:	Wait for device ready for data transfer.
414  *
415  *	Parameters:		padapter - Pointer adapter data structure.
416  *					pdev	 - Pointer to device.
417  *
418  *	Returns:		TRUE if drive does not come ready.
419  *
420  ****************************************************************/
AtapiReset(PADAPTER2220I padapter,POUR_DEVICE pdev)421 static int AtapiReset (PADAPTER2220I padapter, POUR_DEVICE pdev)
422 	{
423 	SelectSpigot (padapter, pdev->spigot);
424 	AtapiDevice (padapter, pdev->byte6);
425 	AtapiCountLo (padapter, 0);
426 	AtapiCountHi (padapter, 0);
427 	WriteCommand (padapter, IDE_COMMAND_ATAPI_RESET);
428 	udelay (125);
429 	if ( AtapiWaitReady (padapter, 1000) )
430 		return TRUE;
431 	if ( inb_p (padapter->regStatCmd) || (inb_p (padapter->regLba8) != 0x14) || (inb_p (padapter->regLba16) != 0xEB) )
432 		return TRUE;
433 	return FALSE;
434 	}
435 /****************************************************************
436  *	Name:	WalkScatGath	:LOCAL
437  *
438  *	Description:	Transfer data to/from scatter/gather buffers.
439  *
440  *	Parameters:		padapter - Pointer adapter data structure.
441  *					datain   - TRUE if data read.
442  *					length   - Number of bytes to transfer.
443  *
444  *	Returns:		Nothing.
445  *
446  ****************************************************************/
WalkScatGath(PADAPTER2220I padapter,UCHAR datain,ULONG length)447 static void WalkScatGath (PADAPTER2220I padapter, UCHAR datain, ULONG length)
448 	{
449 	ULONG	 count;
450 	UCHAR	*buffer = padapter->kBuffer;
451 
452 	while ( length )
453 		{
454 		count = ( length > padapter->currentSgCount ) ? padapter->currentSgCount : length;
455 
456 		if ( datain )
457 			memcpy (padapter->currentSgBuffer, buffer, count);
458 		else
459 			memcpy (buffer, padapter->currentSgBuffer, count);
460 
461 		padapter->currentSgCount -= count;
462 		if ( !padapter->currentSgCount )
463 			{
464 			if ( padapter->nextSg < padapter->SCpnt->use_sg )
465 				{
466 				padapter->currentSgBuffer = ((struct scatterlist *)padapter->SCpnt->request_buffer)[padapter->nextSg].address;
467 				padapter->currentSgCount = ((struct scatterlist *)padapter->SCpnt->request_buffer)[padapter->nextSg].length;
468 				padapter->nextSg++;
469 				}
470 			}
471 		else
472 			padapter->currentSgBuffer += count;
473 
474 		length -= count;
475 		buffer += count;
476 		}
477 	}
478 /****************************************************************
479  *	Name:	BusMaster	:LOCAL
480  *
481  *	Description:	Do a bus master I/O.
482  *
483  *	Parameters:		padapter - Pointer adapter data structure.
484  *					datain	 - TRUE if data read.
485  *					irq		 - TRUE if bus master interrupt expected.
486  *
487  *	Returns:		Nothing.
488  *
489  ****************************************************************/
BusMaster(PADAPTER2220I padapter,UCHAR datain,UCHAR irq)490 static void BusMaster (PADAPTER2220I padapter, UCHAR datain, UCHAR irq)
491 	{
492 	ULONG zl;
493 
494 	zl = ( padapter->sectorCount > MAX_BUS_MASTER_BLOCKS ) ? MAX_BUS_MASTER_BLOCKS : padapter->sectorCount;
495 	padapter->sectorCount -= zl;
496 	zl *= (ULONG)BYTES_PER_SECTOR;
497 
498 	if ( datain )
499 		{
500 		padapter->readCount = zl;
501 		outb_p (8, padapter->regDmaDesc);							// read operation
502 		if ( padapter->bigD )
503 			{
504 			if ( irq && !padapter->sectorCount )
505 				outb_p (0x0C, padapter->regDmaMode);				// interrupt on
506 			else
507 				outb_p (0x08, padapter->regDmaMode);				// no interrupt
508 			}
509 		else
510 			{
511 			if ( irq && !padapter->sectorCount )
512 				outb_p (0x05, padapter->regDmaMode);				// interrupt on
513 			else
514 				outb_p (0x01, padapter->regDmaMode);				// no interrupt
515 			}
516 		}
517 	else
518 		{
519 		outb_p (0x00, padapter->regDmaDesc);						// write operation
520 		if ( padapter->bigD )
521 			outb_p (0x08, padapter->regDmaMode);					// no interrupt
522 		else
523 			outb_p (0x01, padapter->regDmaMode);					// no interrupt
524 		WalkScatGath (padapter, FALSE, zl);
525 		}
526 
527 	outl (padapter->timingAddress, padapter->regDmaAddrLoc);
528 	outl (padapter->kBufferDma, padapter->regDmaAddrPci);
529 	outl (zl, padapter->regDmaCount);
530 	outb_p (0x03, padapter->regDmaCmdStat);							// kick the DMA engine in gear
531 	}
532 /****************************************************************
533  *	Name:	AtapiBusMaster	:LOCAL
534  *
535  *	Description:	Do a bus master I/O.
536  *
537  *	Parameters:		padapter - Pointer adapter data structure.
538  *					datain	 - TRUE if data read.
539  *					length	 - Number of bytes to transfer.
540  *
541  *	Returns:		Nothing.
542  *
543  ****************************************************************/
AtapiBusMaster(PADAPTER2220I padapter,UCHAR datain,ULONG length)544 static void AtapiBusMaster (PADAPTER2220I padapter, UCHAR datain, ULONG length)
545 	{
546 	outl (padapter->timingAddress, padapter->regDmaAddrLoc);
547 	outl (padapter->kBufferDma, padapter->regDmaAddrPci);
548 	outl (length, padapter->regDmaCount);
549 	if ( datain )
550 		{
551 		if ( padapter->readCount )
552 				WalkScatGath (padapter, TRUE, padapter->readCount);
553 		outb_p (0x08, padapter->regDmaDesc);						// read operation
554 		outb_p (0x08, padapter->regDmaMode);						// no interrupt
555 		padapter->readCount = length;
556 		}
557 	else
558 		{
559 		outb_p (0x00, padapter->regDmaDesc);						// write operation
560 		outb_p (0x08, padapter->regDmaMode);						// no interrupt
561 		if ( !padapter->atapiSpecial )
562 			WalkScatGath (padapter, FALSE, length);
563 		}
564 	outb_p (0x03, padapter->regDmaCmdStat);							// kick the DMA engine in gear
565 	}
566 /****************************************************************
567  *	Name:	WriteData	:LOCAL
568  *
569  *	Description:	Write data to device.
570  *
571  *	Parameters:		padapter - Pointer adapter data structure.
572  *
573  *	Returns:		TRUE if drive does not assert DRQ in time.
574  *
575  ****************************************************************/
WriteData(PADAPTER2220I padapter)576 static int WriteData (PADAPTER2220I padapter)
577 	{
578 	ULONG	zl;
579 
580 	if ( !WaitDrq (padapter) )
581 		{
582 		if ( padapter->timingPIO )
583 			{
584 			zl = (padapter->sectorCount > MAX_BUS_MASTER_BLOCKS) ? MAX_BUS_MASTER_BLOCKS : padapter->sectorCount;
585 			WalkScatGath (padapter, FALSE, zl * BYTES_PER_SECTOR);
586 			outsw (padapter->regData, padapter->kBuffer, zl * (BYTES_PER_SECTOR / 2));
587 			padapter->sectorCount -= zl;
588 			}
589 		else
590 			BusMaster (padapter, 0, 0);
591 		return 0;
592 		}
593 	padapter->cmd = 0;												// null out the command byte
594 	return 1;
595 	}
596 /****************************************************************
597  *	Name:	WriteDataBoth	:LOCAL
598  *
599  *	Description:	Write data to device.
600  *
601  *	Parameters:		padapter - Pointer to adapter structure.
602  *					pdev	 - Pointer to device structure
603  *
604  *	Returns:		Index + 1 of drive not failed or zero for OK.
605  *
606  ****************************************************************/
WriteDataBoth(PADAPTER2220I padapter,POUR_DEVICE pdev)607 static int WriteDataBoth (PADAPTER2220I padapter, POUR_DEVICE pdev)
608 	{
609 	ULONG	zl;
610 	UCHAR	status0, status1;
611 
612 	SelectSpigot (padapter, pdev->spigots[0]);
613 	status0 = WaitDrq (padapter);
614 	if ( !status0 )
615 		{
616 		SelectSpigot (padapter, pdev->spigots[1]);
617 		status1 = WaitDrq (padapter);
618 		if ( !status1 )
619 			{
620 			SelectSpigot (padapter, pdev->spigots[0] | pdev->spigots[1] | padapter->bigD);
621 			if ( padapter->timingPIO )
622 				{
623 				zl = (padapter->sectorCount > MAX_BUS_MASTER_BLOCKS) ? MAX_BUS_MASTER_BLOCKS : padapter->sectorCount;
624 				WalkScatGath (padapter, FALSE, zl * BYTES_PER_SECTOR);
625 				outsw (padapter->regData, padapter->kBuffer, zl * (BYTES_PER_SECTOR / 2));
626 				padapter->sectorCount -= zl;
627 				}
628 			else
629 				BusMaster (padapter, 0, 0);
630 			return 0;
631 			}
632 		}
633 	padapter->cmd = 0;												// null out the command byte
634 	if ( status0 )
635 		return 2;
636 	return 1;
637 	}
638 /****************************************************************
639  *	Name:	IdeCmd	:LOCAL
640  *
641  *	Description:	Process an IDE command.
642  *
643  *	Parameters:		padapter - Pointer adapter data structure.
644  *					pdev	 - Pointer to device.
645  *
646  *	Returns:		Zero if no error or status register contents on error.
647  *
648  ****************************************************************/
IdeCmd(PADAPTER2220I padapter,POUR_DEVICE pdev)649 static UCHAR IdeCmd (PADAPTER2220I padapter, POUR_DEVICE pdev)
650 	{
651 	UCHAR	status;
652 
653 	SelectSpigot (padapter, pdev->spigot | padapter->bigD);							// select the spigot
654 	outb_p (pdev->byte6 | ((UCHAR *)(&padapter->startSector))[3], padapter->regLba24);			// select the drive
655 	status = WaitReady (padapter);
656 	if ( !status )
657 		{
658 		outb_p (padapter->sectorCount, padapter->regSectCount);
659 		outb_p (((UCHAR *)(&padapter->startSector))[0], padapter->regLba0);
660 		outb_p (((UCHAR *)(&padapter->startSector))[1], padapter->regLba8);
661 		outb_p (((UCHAR *)(&padapter->startSector))[2], padapter->regLba16);
662 		padapter->expectingIRQ = TRUE;
663 		WriteCommand (padapter, padapter->cmd);
664 		return 0;
665 		}
666 
667 	padapter->cmd = 0;									// null out the command byte
668 	return status;
669 	}
670 /****************************************************************
671  *	Name:	IdeCmdBoth	:LOCAL
672  *
673  *	Description:	Process an IDE command to both drivers.
674  *
675  *	Parameters:		padapter - Pointer adapter data structure.
676  *					pdev	 - Pointer to device structure
677  *
678  *	Returns:		Index + 1 of drive not failed or zero for OK.
679  *
680  ****************************************************************/
IdeCmdBoth(PADAPTER2220I padapter,POUR_DEVICE pdev)681 static UCHAR IdeCmdBoth (PADAPTER2220I padapter, POUR_DEVICE pdev)
682 	{
683 	UCHAR	status0;
684 	UCHAR	status1;
685 
686 	SelectSpigot (padapter, pdev->spigots[0] | pdev->spigots[1]);								// select the spigots
687 	outb_p (padapter->pdev->byte6 | ((UCHAR *)(&padapter->startSector))[3], padapter->regLba24);// select the drive
688 	SelectSpigot (padapter, pdev->spigots[0]);
689 	status0 = WaitReady (padapter);
690 	if ( !status0 )
691 		{
692 		SelectSpigot (padapter, pdev->spigots[1]);
693 		status1 = WaitReady (padapter);
694 		if ( !status1 )
695 			{
696 			SelectSpigot (padapter, pdev->spigots[0] | pdev->spigots[1] | padapter->bigD);
697 			outb_p (padapter->sectorCount, padapter->regSectCount);
698 			outb_p (((UCHAR *)(&padapter->startSector))[0], padapter->regLba0);
699 			outb_p (((UCHAR *)(&padapter->startSector))[1], padapter->regLba8);
700 			outb_p (((UCHAR *)(&padapter->startSector))[2], padapter->regLba16);
701 			padapter->expectingIRQ = TRUE;
702 			WriteCommand (padapter, padapter->cmd);
703 			return 0;
704 			}
705 		}
706 	padapter->cmd = 0;									// null out the command byte
707 	if ( status0 )
708 		return 2;
709 	return 1;
710 	}
711 /****************************************************************
712  *	Name:	OpDone	:LOCAL
713  *
714  *	Description:	Complete an operatoin done sequence.
715  *
716  *	Parameters:		padapter - Pointer to host data block.
717  *					spigot	 - Spigot select code.
718  *					device	 - Device byte code.
719  *
720  *	Returns:		Nothing.
721  *
722  ****************************************************************/
OpDone(PADAPTER2220I padapter,ULONG result)723 static void OpDone (PADAPTER2220I padapter, ULONG result)
724 	{
725 	Scsi_Cmnd	   *SCpnt = padapter->SCpnt;
726 
727 	if ( padapter->reconPhase )
728 		{
729 		padapter->reconPhase = 0;
730 		if ( padapter->SCpnt )
731 			{
732 			Pci2220i_QueueCommand (SCpnt, SCpnt->scsi_done);
733 			}
734 		else
735 			{
736 			if ( padapter->reconOn )
737 				{
738 				ReconTimerExpiry ((unsigned long)padapter);
739 				}
740 			}
741 		}
742 	else
743 		{
744 		padapter->cmd = 0;
745 		padapter->SCpnt = NULL;
746 		padapter->pdev = NULL;
747 		SCpnt->result = result;
748 		SCpnt->scsi_done (SCpnt);
749 		if ( padapter->reconOn && !padapter->reconTimer.data )
750 			{
751 			padapter->reconTimer.expires = jiffies + (HZ / 4);	// start in 1/4 second
752 			padapter->reconTimer.data = (unsigned long)padapter;
753 			add_timer (&padapter->reconTimer);
754 			}
755 		}
756 	}
757 /****************************************************************
758  *	Name:	InlineIdentify	:LOCAL
759  *
760  *	Description:	Do an intline inquiry on a drive.
761  *
762  *	Parameters:		padapter - Pointer to host data block.
763  *					spigot	 - Spigot select code.
764  *					device	 - Device byte code.
765  *
766  *	Returns:		Last addressable sector or zero if none.
767  *
768  ****************************************************************/
InlineIdentify(PADAPTER2220I padapter,UCHAR spigot,UCHAR device)769 static ULONG InlineIdentify (PADAPTER2220I padapter, UCHAR spigot, UCHAR device)
770 	{
771 	PIDENTIFY_DATA	pid = (PIDENTIFY_DATA)padapter->kBuffer;
772 
773 	SelectSpigot (padapter, spigot | SEL_IRQ_OFF);					// select the spigot
774 	outb_p ((device << 4) | 0xA0, padapter->regLba24);				// select the drive
775 	if ( WaitReady (padapter) )
776 		return 0;
777 	WriteCommand (padapter, IDE_COMMAND_IDENTIFY);
778 	if ( WaitDrq (padapter) )
779 		return 0;
780 	insw (padapter->regData, padapter->kBuffer, sizeof (IDENTIFY_DATA) >> 1);
781 	return (pid->LBATotalSectors - 1);
782 	}
783 /****************************************************************
784  *	Name:	AtapiIdentify	:LOCAL
785  *
786  *	Description:	Do an intline inquiry on a drive.
787  *
788  *	Parameters:		padapter - Pointer to host data block.
789  *					pdev	 - Pointer to device table.
790  *
791  *	Returns:		TRUE on error.
792  *
793  ****************************************************************/
AtapiIdentify(PADAPTER2220I padapter,POUR_DEVICE pdev)794 static ULONG AtapiIdentify (PADAPTER2220I padapter, POUR_DEVICE pdev)
795 	{
796 	ATAPI_GENERAL_0		ag0;
797 	USHORT				zs;
798 	int					z;
799 
800 	AtapiDevice (padapter, pdev->byte6);
801 	WriteCommand (padapter, IDE_COMMAND_ATAPI_IDENTIFY);
802 	if ( AtapiWaitDrq (padapter, 3000) )
803 		return TRUE;
804 
805 	*(USHORT *)&ag0 = inw_p (padapter->regData);
806 	for ( z = 0;  z < 255;  z++ )
807 		zs = inw_p (padapter->regData);
808 
809 	if ( ag0.ProtocolType == 2 )
810 		{
811 		if ( ag0.CmdDrqType == 1 )
812 			pdev->cmdDrqInt = TRUE;
813 		switch ( ag0.CmdPacketSize )
814 			{
815 			case 0:
816 				pdev->packet = 6;
817 				break;
818 			case 1:
819 				pdev->packet = 8;
820 				break;
821 			default:
822 				pdev->packet = 6;
823 				break;
824 			}
825 		return FALSE;
826 		}
827 	return TRUE;
828 	}
829 /****************************************************************
830  *	Name:	Atapi2Scsi
831  *
832  *	Description:	Convert ATAPI data to SCSI data.
833  *
834  *	Parameters:		padapter - Pointer adapter data structure.
835  *					SCpnt	 - Pointer to SCSI command structure.
836  *
837  *	Returns:		Nothing.
838  *
839  ****************************************************************/
Atapi2Scsi(PADAPTER2220I padapter,Scsi_Cmnd * SCpnt)840 void Atapi2Scsi (PADAPTER2220I padapter, Scsi_Cmnd *SCpnt)
841 	{
842 	UCHAR	*buff = padapter->currentSgBuffer;
843 
844 	switch ( SCpnt->cmnd[0] )
845 		{
846 		case SCSIOP_MODE_SENSE:
847 			buff[0] = padapter->kBuffer[1];
848 			buff[1] = padapter->kBuffer[2];
849 			buff[2] = padapter->kBuffer[3];
850 			buff[3] = padapter->kBuffer[7];
851 			memcpy (&buff[4], &padapter->kBuffer[8], padapter->atapiCdb[8] - 8);
852 			break;
853 		case SCSIOP_INQUIRY:
854 			padapter->kBuffer[2] = 2;
855 			memcpy (buff, padapter->kBuffer, padapter->currentSgCount);
856 			break;
857 		default:
858 			if ( padapter->readCount )
859 				WalkScatGath (padapter, TRUE, padapter->readCount);
860 			break;
861 		}
862 	}
863 /****************************************************************
864  *	Name:	Scsi2Atapi
865  *
866  *	Description:	Convert SCSI packet command to Atapi packet command.
867  *
868  *	Parameters:		padapter - Pointer adapter data structure.
869  *					SCpnt	 - Pointer to SCSI command structure.
870  *
871  *	Returns:		Nothing.
872  *
873  ****************************************************************/
Scsi2Atapi(PADAPTER2220I padapter,Scsi_Cmnd * SCpnt)874 static void Scsi2Atapi (PADAPTER2220I padapter, Scsi_Cmnd *SCpnt)
875 	{
876 	UCHAR	*cdb = SCpnt->cmnd;
877 	UCHAR	*buff = padapter->currentSgBuffer;
878 
879 	switch (cdb[0])
880 		{
881 		case SCSIOP_READ6:
882             padapter->atapiCdb[0] = SCSIOP_READ;
883 			padapter->atapiCdb[1] = cdb[1] & 0xE0;
884             padapter->atapiCdb[3] = cdb[1] & 0x1F;
885 			padapter->atapiCdb[4] = cdb[2];
886 			padapter->atapiCdb[5] = cdb[3];
887 			padapter->atapiCdb[8] = cdb[4];
888 			padapter->atapiCdb[9] = cdb[5];
889 			break;
890 		case SCSIOP_WRITE6:
891             padapter->atapiCdb[0] = SCSIOP_WRITE;
892 			padapter->atapiCdb[1] = cdb[1] & 0xE0;
893             padapter->atapiCdb[3] = cdb[1] & 0x1F;
894 			padapter->atapiCdb[4] = cdb[2];
895 			padapter->atapiCdb[5] = cdb[3];
896 			padapter->atapiCdb[8] = cdb[4];
897 			padapter->atapiCdb[9] = cdb[5];
898 			break;
899         case SCSIOP_MODE_SENSE:
900             padapter->atapiCdb[0] = SCSIOP_MODE_SENSE10;
901 			padapter->atapiCdb[2] = cdb[2];
902 			padapter->atapiCdb[8] = cdb[4] + 4;
903             break;
904 
905         case SCSIOP_MODE_SELECT:
906 			padapter->atapiSpecial = TRUE;
907 			padapter->atapiCdb[0] = SCSIOP_MODE_SELECT10;
908 			padapter->atapiCdb[1] = cdb[1] | 0x10;
909 			memcpy (padapter->kBuffer, buff, 4);
910 			padapter->kBuffer[4] = padapter->kBuffer[5] = 0;
911 			padapter->kBuffer[6] = padapter->kBuffer[7] = 0;
912 			memcpy (&padapter->kBuffer[8], &buff[4], cdb[4] - 4);
913 			padapter->atapiCdb[8] = cdb[4] + 4;
914 			break;
915 	    }
916 	}
917 /****************************************************************
918  *	Name:	AtapiSendCdb
919  *
920  *	Description:	Send the CDB packet to the device.
921  *
922  *	Parameters:		padapter - Pointer adapter data structure.
923  *					pdev	 - Pointer to device.
924  *					cdb		 - Pointer to 16 byte SCSI cdb.
925  *
926  *	Returns:		Nothing.
927  *
928  ****************************************************************/
AtapiSendCdb(PADAPTER2220I padapter,POUR_DEVICE pdev,CHAR * cdb)929 static void AtapiSendCdb (PADAPTER2220I padapter, POUR_DEVICE pdev, CHAR *cdb)
930 	{
931 	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]));
932 	outsw (padapter->regData, cdb, pdev->packet);
933 	}
934 /****************************************************************
935  *	Name:	AtapiRequestSense
936  *
937  *	Description:	Send the CDB packet to the device.
938  *
939  *	Parameters:		padapter - Pointer adapter data structure.
940  *					pdev	 - Pointer to device.
941  *					SCpnt	 - Pointer to SCSI command structure.
942  *					pass	 - If true then this is the second pass to send cdb.
943  *
944  *	Returns:		TRUE on error.
945  *
946  ****************************************************************/
AtapiRequestSense(PADAPTER2220I padapter,POUR_DEVICE pdev,Scsi_Cmnd * SCpnt,UCHAR pass)947 static int AtapiRequestSense (PADAPTER2220I padapter, POUR_DEVICE pdev, Scsi_Cmnd *SCpnt, UCHAR pass)
948 	{
949 	UCHAR	cdb[16] = {SCSIOP_REQUEST_SENSE,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0};
950 
951 	DEB (printk ("\nPCI2242I: AUTO REQUEST SENSE"));
952 	cdb[4] = (UCHAR)(sizeof (SCpnt->sense_buffer));
953 	if ( !pass )
954 		{
955 		padapter->reqSense = TRUE;
956 	 	AtapiCountLo (padapter, cdb[4]);
957 		AtapiCountHi (padapter, 0);
958 		outb_p (0, padapter->regError);
959 		WriteCommand (padapter, IDE_COMMAND_ATAPI_PACKET);
960 		if ( pdev->cmdDrqInt )
961 			return FALSE;
962 
963 		if ( AtapiWaitDrq (padapter, 500) )
964 			return TRUE;
965 		}
966 	AtapiSendCdb (padapter, pdev, cdb);
967 	return FALSE;
968 	}
969 /****************************************************************
970  *	Name:	InlineReadSignature	:LOCAL
971  *
972  *	Description:	Do an inline read RAID sigature.
973  *
974  *	Parameters:		padapter - Pointer adapter data structure.
975  *					pdev	 - Pointer to device.
976  *					index	 - index of data to read.
977  *
978  *	Returns:		Zero if no error or status register contents on error.
979  *
980  ****************************************************************/
InlineReadSignature(PADAPTER2220I padapter,POUR_DEVICE pdev,int index)981 static UCHAR InlineReadSignature (PADAPTER2220I padapter, POUR_DEVICE pdev, int index)
982 	{
983 	UCHAR	status;
984 	ULONG	zl = pdev->lastsectorlba[index];
985 
986 	SelectSpigot (padapter, pdev->spigots[index] | SEL_IRQ_OFF);	// select the spigot without interrupts
987 	outb_p (pdev->byte6 | ((UCHAR *)&zl)[3], padapter->regLba24);
988 	status = WaitReady (padapter);
989 	if ( !status )
990 		{
991 		outb_p (((UCHAR *)&zl)[2], padapter->regLba16);
992 		outb_p (((UCHAR *)&zl)[1], padapter->regLba8);
993 		outb_p (((UCHAR *)&zl)[0], padapter->regLba0);
994 		outb_p (1, padapter->regSectCount);
995 		WriteCommand (padapter, IDE_COMMAND_READ);
996 		status = WaitDrq (padapter);
997 		if ( !status )
998 			{
999 			insw (padapter->regData, padapter->kBuffer, BYTES_PER_SECTOR / 2);
1000 			((ULONG *)(&pdev->DiskMirror[index]))[0] = ((ULONG *)(&padapter->kBuffer[DISK_MIRROR_POSITION]))[0];
1001 			((ULONG *)(&pdev->DiskMirror[index]))[1] = ((ULONG *)(&padapter->kBuffer[DISK_MIRROR_POSITION]))[1];
1002 			// some drives assert DRQ before IRQ so let's make sure we clear the IRQ
1003 			WaitReady (padapter);
1004 			return 0;
1005 			}
1006 		}
1007 	return status;
1008 	}
1009 /****************************************************************
1010  *	Name:	DecodeError	:LOCAL
1011  *
1012  *	Description:	Decode and process device errors.
1013  *
1014  *	Parameters:		padapter - Pointer to adapter data.
1015  *					status - Status register code.
1016  *
1017  *	Returns:		The driver status code.
1018  *
1019  ****************************************************************/
DecodeError(PADAPTER2220I padapter,UCHAR status)1020 static ULONG DecodeError (PADAPTER2220I	padapter, UCHAR status)
1021 	{
1022 	UCHAR			error;
1023 
1024 	padapter->expectingIRQ = 0;
1025 	if ( status & IDE_STATUS_WRITE_FAULT )
1026 		{
1027 		return DID_PARITY << 16;
1028 		}
1029 	if ( status & IDE_STATUS_BUSY )
1030 		return DID_BUS_BUSY << 16;
1031 
1032 	error = inb_p (padapter->regError);
1033 	DEB(printk ("\npci2220i error register: %x", error));
1034 	switch ( error )
1035 		{
1036 		case IDE_ERROR_AMNF:
1037 		case IDE_ERROR_TKONF:
1038 		case IDE_ERROR_ABRT:
1039 		case IDE_ERROR_IDFN:
1040 		case IDE_ERROR_UNC:
1041 		case IDE_ERROR_BBK:
1042 		default:
1043 			return DID_ERROR << 16;
1044 		}
1045 	return DID_ERROR << 16;
1046 	}
1047 /****************************************************************
1048  *	Name:	StartTimer	:LOCAL
1049  *
1050  *	Description:	Start the timer.
1051  *
1052  *	Parameters:		ipadapter - Pointer adapter data structure.
1053  *
1054  *	Returns:		Nothing.
1055  *
1056  ****************************************************************/
StartTimer(PADAPTER2220I padapter)1057 static void StartTimer (PADAPTER2220I padapter)
1058 	{
1059 	padapter->timer.expires = jiffies + TIMEOUT_DATA;
1060 	add_timer (&padapter->timer);
1061 	}
1062 /****************************************************************
1063  *	Name:	WriteSignature	:LOCAL
1064  *
1065  *	Description:	Start the timer.
1066  *
1067  *	Parameters:		padapter - Pointer adapter data structure.
1068  *					pdev	 - Pointer to our device.
1069  *					spigot	 - Selected spigot.
1070  *					index	 - index of mirror signature on device.
1071  *
1072  *	Returns:		TRUE on any error.
1073  *
1074  ****************************************************************/
WriteSignature(PADAPTER2220I padapter,POUR_DEVICE pdev,UCHAR spigot,int index)1075 static int WriteSignature (PADAPTER2220I padapter, POUR_DEVICE pdev, UCHAR spigot, int index)
1076 	{
1077 	ULONG	zl;
1078 
1079 	SelectSpigot (padapter, spigot);
1080 	zl = pdev->lastsectorlba[index];
1081 	outb_p (pdev->byte6 | ((UCHAR *)&zl)[3], padapter->regLba24);
1082 	outb_p (((UCHAR *)&zl)[2], padapter->regLba16);
1083 	outb_p (((UCHAR *)&zl)[1], padapter->regLba8);
1084 	outb_p (((UCHAR *)&zl)[0], padapter->regLba0);
1085 	outb_p (1, padapter->regSectCount);
1086 
1087 	WriteCommand (padapter, IDE_COMMAND_WRITE);
1088 	if ( WaitDrq (padapter) )
1089 		return TRUE;
1090 	StartTimer (padapter);
1091 	padapter->expectingIRQ = TRUE;
1092 
1093 	((ULONG *)(&padapter->kBuffer[DISK_MIRROR_POSITION]))[0] = ((ULONG *)(&pdev->DiskMirror[index]))[0];
1094 	((ULONG *)(&padapter->kBuffer[DISK_MIRROR_POSITION]))[1] = ((ULONG *)(&pdev->DiskMirror[index]))[1];
1095 	outsw (padapter->regData, padapter->kBuffer, BYTES_PER_SECTOR / 2);
1096 	return FALSE;
1097 	}
1098 /*******************************************************************************************************
1099  *	Name:			InitFailover
1100  *
1101  *	Description:	This is the beginning of the failover routine
1102  *
1103  *	Parameters:		SCpnt	 - Pointer to SCSI command structure.
1104  *					padapter - Pointer adapter data structure.
1105  *					pdev	 - Pointer to our device.
1106  *
1107  *	Returns:		TRUE on error.
1108  *
1109  ******************************************************************************************************/
InitFailover(PADAPTER2220I padapter,POUR_DEVICE pdev)1110 static int InitFailover (PADAPTER2220I padapter, POUR_DEVICE pdev)
1111 	{
1112 	UCHAR	spigot;
1113 
1114 	DEB (printk ("\npci2220i:  Initialize failover process - survivor = %d", pdev->deviceID[padapter->survivor]));
1115 	pdev->raid = FALSE;									//initializes system for non raid mode
1116 	pdev->reconOn = FALSE;
1117 	spigot = pdev->spigots[padapter->survivor];
1118 
1119 	if ( pdev->DiskMirror[padapter->survivor].status & UCBF_REBUILD )
1120 		{
1121 		DEB (printk ("\n         failed, is survivor"));
1122 		return (TRUE);
1123 		}
1124 
1125 	if ( HardReset (padapter, pdev, spigot) )
1126 		{
1127 		DEB (printk ("\n         failed, reset"));
1128 		return TRUE;
1129 		}
1130 
1131 	Alarm (padapter, pdev->deviceID[padapter->survivor ^ 1]);
1132 	pdev->DiskMirror[padapter->survivor].status = UCBF_MIRRORED | UCBF_SURVIVOR;	//clear present status
1133 
1134 	if ( WriteSignature (padapter, pdev, spigot, padapter->survivor) )
1135 		{
1136 		DEB (printk ("\n         failed, write signature"));
1137 		return TRUE;
1138 		}
1139 	padapter->failinprog = TRUE;
1140 	return FALSE;
1141 	}
1142 /****************************************************************
1143  *	Name:	TimerExpiry	:LOCAL
1144  *
1145  *	Description:	Timer expiry routine.
1146  *
1147  *	Parameters:		data - Pointer adapter data structure.
1148  *
1149  *	Returns:		Nothing.
1150  *
1151  ****************************************************************/
TimerExpiry(unsigned long data)1152 static void TimerExpiry (unsigned long data)
1153 	{
1154 	PADAPTER2220I	padapter = (PADAPTER2220I)data;
1155 	POUR_DEVICE		pdev = padapter->pdev;
1156 	UCHAR			status = IDE_STATUS_BUSY;
1157 	UCHAR			temp, temp1;
1158     unsigned long		flags;
1159 
1160     /*
1161      * Disable interrupts, if they aren't already disabled and acquire
1162      * the I/O spinlock.
1163      */
1164     spin_lock_irqsave (&io_request_lock, flags);
1165 	DEB (printk ("\nPCI2220I: Timeout expired "));
1166 
1167 	if ( padapter->failinprog )
1168 		{
1169 		DEB (printk ("in failover process"));
1170 		OpDone (padapter, DecodeError (padapter, inb_p (padapter->regStatCmd)));
1171 		goto timerExpiryDone;
1172 		}
1173 
1174 	while ( padapter->reconPhase )
1175 		{
1176 		DEB (printk ("in recon phase %X", padapter->reconPhase));
1177 		switch ( padapter->reconPhase )
1178 			{
1179 			case RECON_PHASE_MARKING:
1180 			case RECON_PHASE_LAST:
1181 				padapter->survivor = ( pdev->spigot == pdev->spigots[0] ) ? 1 : 0;
1182 				DEB (printk ("\npci2220i: FAILURE 1"));
1183 				if ( InitFailover (padapter, pdev) )
1184 					OpDone (padapter, DID_ERROR << 16);
1185 				goto timerExpiryDone;
1186 
1187 			case RECON_PHASE_READY:
1188 				OpDone (padapter, DID_ERROR << 16);
1189 				goto timerExpiryDone;
1190 
1191 			case RECON_PHASE_COPY:
1192 				padapter->survivor = ( pdev->spigot == pdev->spigots[0] ) ? 0 : 1;
1193 				DEB (printk ("\npci2220i: FAILURE 2"));
1194 				DEB (printk ("\n       spig/stat = %X", inb_p (padapter->regStatSel));
1195 				if ( InitFailover (padapter, pdev) )
1196 					OpDone (padapter, DID_ERROR << 16);
1197 				goto timerExpiryDone;
1198 
1199 			case RECON_PHASE_UPDATE:
1200 				padapter->survivor = ( pdev->spigot == pdev->spigots[0] ) ? 0 : 1;
1201 				DEB (printk ("\npci2220i: FAILURE 3")));
1202 				if ( InitFailover (padapter, pdev) )
1203 					OpDone (padapter, DID_ERROR << 16);
1204 				goto timerExpiryDone;
1205 
1206 			case RECON_PHASE_END:
1207 				padapter->survivor = ( pdev->spigot == pdev->spigots[0] ) ? 0 : 1;
1208 				DEB (printk ("\npci2220i: FAILURE 4"));
1209 				if ( InitFailover (padapter, pdev) )
1210 					OpDone (padapter, DID_ERROR << 16);
1211 				goto timerExpiryDone;
1212 
1213 			default:
1214 				goto timerExpiryDone;
1215 			}
1216 		}
1217 
1218 	while ( padapter->cmd )
1219 		{
1220 		outb_p (0x08, padapter->regDmaCmdStat);					// cancel interrupt from DMA engine
1221 		if ( pdev->raid )
1222 			{
1223 			if ( padapter->cmd == WRITE_CMD )
1224 				{
1225 				DEB (printk ("in RAID write operation"));
1226 				temp = ( pdev->spigot & (SEL_1 | SEL_2) ) ? SEL_1 : SEL_3;
1227 				if ( inb_p (padapter->regStatSel) & temp )
1228 					{
1229 					DEB (printk ("\npci2220i: Determined A OK"));
1230 					SelectSpigot (padapter, temp | SEL_IRQ_OFF); // Masking the interrupt during spigot select
1231 					temp = inb_p (padapter->regStatCmd);
1232 					}
1233 				else
1234 					temp = IDE_STATUS_BUSY;
1235 
1236 				temp1 = ( pdev->spigot & (SEL_1 | SEL_2) ) ? SEL_2 : SEL_4;
1237 				if ( inb (padapter->regStatSel) & temp1 )
1238 					{
1239 					DEB (printk ("\npci2220i: Determined B OK"));
1240 					SelectSpigot (padapter, temp1 | SEL_IRQ_OFF); // Masking the interrupt during spigot select
1241 					temp1 = inb_p (padapter->regStatCmd);
1242 					}
1243 				else
1244 					temp1 = IDE_STATUS_BUSY;
1245 
1246 				if ( (temp & IDE_STATUS_BUSY) || (temp1 & IDE_STATUS_BUSY) )
1247 					{
1248 					DEB (printk ("\npci2220i: Status A: %X   B: %X", temp & 0xFF, temp1 & 0xFF));
1249 	 				if ( (temp & IDE_STATUS_BUSY) && (temp1 & IDE_STATUS_BUSY) )
1250 						{
1251 						status = temp;
1252 						break;
1253 						}
1254 					else
1255 						{
1256 						if ( temp & IDE_STATUS_BUSY )
1257 							padapter->survivor = 1;
1258 						else
1259 							padapter->survivor = 0;
1260 						if ( InitFailover (padapter, pdev) )
1261 							{
1262 							status = inb_p (padapter->regStatCmd);
1263 							break;
1264 							}
1265 						goto timerExpiryDone;
1266 						}
1267 					}
1268 				}
1269 			else
1270 				{
1271 				DEB (printk ("in RAID read operation"));
1272 				padapter->survivor = ( pdev->spigot == pdev->spigots[0] ) ? 0 : 1;
1273 				DEB (printk ("\npci2220i: FAILURE 6"));
1274 				if ( InitFailover (padapter, pdev) )
1275 					{
1276 					status = inb_p (padapter->regStatCmd);
1277 					break;
1278 					}
1279 				goto timerExpiryDone;
1280 				}
1281 			}
1282 		else
1283 			{
1284 			DEB (printk ("in I/O operation"));
1285 			status = inb_p (padapter->regStatCmd);
1286 			}
1287 		break;
1288 		}
1289 
1290 	OpDone (padapter, DecodeError (padapter, status));
1291 
1292 timerExpiryDone:;
1293     /*
1294      * Release the I/O spinlock and restore the original flags
1295      * which will enable interrupts if and only if they were
1296      * enabled on entry.
1297      */
1298     spin_unlock_irqrestore (&io_request_lock, flags);
1299 	}
1300 /****************************************************************
1301  *	Name:			SetReconstruct	:LOCAL
1302  *
1303  *	Description:	Set the reconstruct up.
1304  *
1305  *	Parameters:		pdev	- Pointer to device structure.
1306  *					index	- Mirror index number.
1307  *
1308  *	Returns:		Number of sectors on new disk required.
1309  *
1310  ****************************************************************/
SetReconstruct(POUR_DEVICE pdev,int index)1311 static LONG SetReconstruct (POUR_DEVICE pdev, int index)
1312 	{
1313 	pdev->DiskMirror[index].status = UCBF_MIRRORED;							// setup the flags
1314 	pdev->DiskMirror[index ^ 1].status = UCBF_MIRRORED | UCBF_REBUILD;
1315 	pdev->DiskMirror[index ^ 1].reconstructPoint = 0;						// start the reconstruct
1316 	pdev->reconCount = 1990;												// mark target drive early
1317 	return pdev->DiskMirror[index].reconstructPoint;
1318 	}
1319 /****************************************************************
1320  *	Name:	ReconTimerExpiry	:LOCAL
1321  *
1322  *	Description:	Reconstruct timer expiry routine.
1323  *
1324  *	Parameters:		data - Pointer adapter data structure.
1325  *
1326  *	Returns:		Nothing.
1327  *
1328  ****************************************************************/
ReconTimerExpiry(unsigned long data)1329 static void ReconTimerExpiry (unsigned long data)
1330 	{
1331 	PADAPTER2220I	padapter;
1332 	POUR_DEVICE		pdev;
1333 	ULONG			testsize = 0;
1334 	PIDENTIFY_DATA	pid;
1335 	USHORT			minmode;
1336 	ULONG			zl;
1337 	UCHAR			zc;
1338 	USHORT			z;
1339     unsigned long	flags;
1340 
1341     /*
1342      * Disable interrupts, if they aren't already disabled and acquire
1343      * the I/O spinlock.
1344      */
1345     spin_lock_irqsave (&io_request_lock, flags);
1346 
1347 	padapter = (PADAPTER2220I)data;
1348 	if ( padapter->SCpnt )
1349 		goto reconTimerExpiry;
1350 
1351 	padapter->reconTimer.data = 0;
1352 	for ( z = padapter->devInReconIndex + 1;  z < BIGD_MAXDRIVES;  z++ )
1353 		{
1354 		if ( padapter->device[z].reconOn )
1355 			break;
1356 		}
1357 	if ( z < BIGD_MAXDRIVES )
1358 		pdev = &padapter->device[z];
1359 	else
1360 		{
1361 		for ( z = 0;  z < BIGD_MAXDRIVES;  z++ )
1362 			{
1363 			if ( padapter->device[z].reconOn )
1364 				break;
1365 			}
1366 		if ( z < BIGD_MAXDRIVES )
1367 			pdev = &padapter->device[z];
1368 		else
1369 			{
1370 			padapter->reconOn = FALSE;
1371 			goto reconTimerExpiry;
1372 			}
1373 		}
1374 
1375 	padapter->devInReconIndex = z;
1376 	pid = (PIDENTIFY_DATA)padapter->kBuffer;
1377 	padapter->pdev = pdev;
1378 	if ( pdev->reconIsStarting )
1379 		{
1380 		pdev->reconIsStarting = FALSE;
1381 		pdev->reconOn = FALSE;
1382 
1383 		while ( (pdev->DiskMirror[0].signature == SIGNATURE) && (pdev->DiskMirror[1].signature == SIGNATURE) &&
1384 			 (pdev->DiskMirror[0].pairIdentifier == (pdev->DiskMirror[1].pairIdentifier ^ 1)) )
1385 			{
1386 			if ( (pdev->DiskMirror[0].status & UCBF_MATCHED) && (pdev->DiskMirror[1].status & UCBF_MATCHED) )
1387 				break;;
1388 
1389 			if ( pdev->DiskMirror[0].status & UCBF_SURVIVOR )				// is first drive survivor?
1390 				testsize = SetReconstruct (pdev, 0);
1391 			else
1392 				if ( pdev->DiskMirror[1].status & UCBF_SURVIVOR )			// is second drive survivor?
1393 					testsize = SetReconstruct (pdev, 1);
1394 
1395 			if ( (pdev->DiskMirror[0].status & UCBF_REBUILD) || (pdev->DiskMirror[1].status & UCBF_REBUILD) )
1396 				{
1397 				if ( pdev->DiskMirror[0].status & UCBF_REBUILD )
1398 					pdev->mirrorRecon = 0;
1399 				else
1400 					pdev->mirrorRecon = 1;
1401 				pdev->reconOn = TRUE;
1402 				}
1403 			break;
1404 			}
1405 
1406 		if ( !pdev->reconOn )
1407 			goto reconTimerExpiry;
1408 
1409 		if ( padapter->bigD )
1410 			{
1411 			padapter->failRegister = 0;
1412 			outb_p (~padapter->failRegister, padapter->regFail);
1413 			}
1414 		else
1415 			{
1416 			zc = ((inb_p (padapter->regStatSel) >> 3) | inb_p (padapter->regStatSel)) & 0x83;		// mute the alarm
1417 			outb_p (0xFF, padapter->regFail);
1418 			}
1419 
1420 		while ( 1 )
1421 			{
1422 			DEB (printk ("\npci2220i: hard reset issue"));
1423 			if ( HardReset (padapter, pdev, pdev->spigots[pdev->mirrorRecon]) )
1424 				{
1425 				DEB (printk ("\npci2220i: sub 1"));
1426 				break;
1427 				}
1428 
1429 			pdev->lastsectorlba[pdev->mirrorRecon] = InlineIdentify (padapter, pdev->spigots[pdev->mirrorRecon], pdev->deviceID[pdev->mirrorRecon] & 1);
1430 
1431 			if ( pdev->lastsectorlba[pdev->mirrorRecon] < testsize )
1432 				{
1433 				DEB (printk ("\npci2220i: sub 2 %ld %ld", pdev->lastsectorlba[pdev->mirrorRecon], testsize));
1434 				break;
1435 				}
1436 
1437 	        // test LBA and multiper sector transfer compatability
1438 			if (!pid->SupportLBA || (pid->NumSectorsPerInt < SECTORSXFER) || !pid->Valid_64_70 )
1439 				{
1440 				DEB (printk ("\npci2220i: sub 3"));
1441 				break;
1442 				}
1443 
1444 	        // test PIO/bus matering mode compatability
1445 			if ( (pid->MinPIOCycleWithoutFlow > 240) && !pid->SupportIORDYDisable && !padapter->timingPIO )
1446 				{
1447 				DEB (printk ("\npci2220i: sub 4"));
1448 				break;
1449 				}
1450 
1451 			if ( pid->MinPIOCycleWithoutFlow <= 120 )	// setup timing mode of drive
1452 				minmode = 5;
1453 			else
1454 				{
1455 				if ( pid->MinPIOCylceWithFlow <= 150 )
1456 					minmode = 4;
1457 				else
1458 					{
1459 					if ( pid->MinPIOCylceWithFlow <= 180 )
1460 						minmode = 3;
1461 					else
1462 						{
1463 						if ( pid->MinPIOCylceWithFlow <= 240 )
1464 							minmode = 2;
1465 						else
1466 							{
1467 							DEB (printk ("\npci2220i: sub 5"));
1468 							break;
1469 							}
1470 						}
1471 					}
1472 				}
1473 
1474 			if ( padapter->timingMode > minmode )									// set minimum timing mode
1475 				padapter->timingMode = minmode;
1476 			if ( padapter->timingMode >= 2 )
1477 				padapter->timingAddress	= ModeArray[padapter->timingMode - 2];
1478 			else
1479 				padapter->timingPIO = TRUE;
1480 
1481 			padapter->reconOn = TRUE;
1482 			break;
1483 			}
1484 
1485 		if ( !pdev->reconOn )
1486 			{
1487 			padapter->survivor = pdev->mirrorRecon ^ 1;
1488 			padapter->reconPhase = RECON_PHASE_FAILOVER;
1489 			DEB (printk ("\npci2220i: FAILURE 7"));
1490 			InitFailover (padapter, pdev);
1491 			goto reconTimerExpiry;
1492 			}
1493 
1494 		pdev->raid = TRUE;
1495 
1496 		if ( WriteSignature (padapter, pdev, pdev->spigot, pdev->mirrorRecon ^ 1) )
1497 			goto reconTimerExpiry;
1498 		padapter->reconPhase = RECON_PHASE_MARKING;
1499 		goto reconTimerExpiry;
1500 		}
1501 
1502 	//**********************************
1503 	// reconstruct copy starts here
1504 	//**********************************
1505 	if ( pdev->reconCount++ > 2000 )
1506 		{
1507 		pdev->reconCount = 0;
1508 		if ( WriteSignature (padapter, pdev, pdev->spigots[pdev->mirrorRecon], pdev->mirrorRecon) )
1509 			{
1510 			padapter->survivor = pdev->mirrorRecon ^ 1;
1511 			padapter->reconPhase = RECON_PHASE_FAILOVER;
1512 			DEB (printk ("\npci2220i: FAILURE 8"));
1513 			InitFailover (padapter, pdev);
1514 			goto reconTimerExpiry;
1515 			}
1516 		padapter->reconPhase = RECON_PHASE_UPDATE;
1517 		goto reconTimerExpiry;
1518 		}
1519 
1520 	zl = pdev->DiskMirror[pdev->mirrorRecon].reconstructPoint;
1521 	padapter->reconSize = pdev->DiskMirror[pdev->mirrorRecon ^ 1].reconstructPoint - zl;
1522 	if ( padapter->reconSize > MAX_BUS_MASTER_BLOCKS )
1523 		padapter->reconSize = MAX_BUS_MASTER_BLOCKS;
1524 
1525 	if ( padapter->reconSize )
1526 		{
1527 		SelectSpigot (padapter, pdev->spigots[0] | pdev->spigots[1]);	// select the spigots
1528 		outb_p (pdev->byte6 | ((UCHAR *)(&zl))[3], padapter->regLba24);	// select the drive
1529 		SelectSpigot (padapter, pdev->spigot);
1530 		if ( WaitReady (padapter) )
1531 			goto reconTimerExpiry;
1532 
1533 		SelectSpigot (padapter, pdev->spigots[pdev->mirrorRecon]);
1534 		if ( WaitReady (padapter) )
1535 			{
1536 			padapter->survivor = pdev->mirrorRecon ^ 1;
1537 			padapter->reconPhase = RECON_PHASE_FAILOVER;
1538 			DEB (printk ("\npci2220i: FAILURE 9"));
1539 			InitFailover (padapter, pdev);
1540 			goto reconTimerExpiry;
1541 			}
1542 
1543 		SelectSpigot (padapter, pdev->spigots[0] | pdev->spigots[1]);
1544 		outb_p (padapter->reconSize & 0xFF, padapter->regSectCount);
1545 		outb_p (((UCHAR *)(&zl))[0], padapter->regLba0);
1546 		outb_p (((UCHAR *)(&zl))[1], padapter->regLba8);
1547 		outb_p (((UCHAR *)(&zl))[2], padapter->regLba16);
1548 		padapter->expectingIRQ = TRUE;
1549 		padapter->reconPhase = RECON_PHASE_READY;
1550 		SelectSpigot (padapter, pdev->spigots[pdev->mirrorRecon]);
1551 		WriteCommand (padapter, WRITE_CMD);
1552 		StartTimer (padapter);
1553 		SelectSpigot (padapter, pdev->spigot);
1554 		WriteCommand (padapter, READ_CMD);
1555 		goto reconTimerExpiry;
1556 		}
1557 
1558 	pdev->DiskMirror[pdev->mirrorRecon].status = UCBF_MIRRORED | UCBF_MATCHED;
1559 	pdev->DiskMirror[pdev->mirrorRecon ^ 1].status = UCBF_MIRRORED | UCBF_MATCHED;
1560 	if ( WriteSignature (padapter, pdev, pdev->spigot, pdev->mirrorRecon ^ 1) )
1561 		goto reconTimerExpiry;
1562 	padapter->reconPhase = RECON_PHASE_LAST;
1563 
1564 reconTimerExpiry:;
1565     /*
1566      * Release the I/O spinlock and restore the original flags
1567      * which will enable interrupts if and only if they were
1568      * enabled on entry.
1569      */
1570     spin_unlock_irqrestore (&io_request_lock, flags);
1571 	}
1572 /****************************************************************
1573  *	Name:	Irq_Handler	:LOCAL
1574  *
1575  *	Description:	Interrupt handler.
1576  *
1577  *	Parameters:		irq		- Hardware IRQ number.
1578  *					dev_id	-
1579  *					regs	-
1580  *
1581  *	Returns:		TRUE if drive is not ready in time.
1582  *
1583  ****************************************************************/
Irq_Handler(int irq,void * dev_id,struct pt_regs * regs)1584 static void Irq_Handler (int irq, void *dev_id, struct pt_regs *regs)
1585 	{
1586 	struct Scsi_Host   *shost = NULL;	// Pointer to host data block
1587 	PADAPTER2220I		padapter;		// Pointer to adapter control structure
1588 	POUR_DEVICE			pdev;
1589 	Scsi_Cmnd		   *SCpnt;
1590 	UCHAR				status;
1591 	UCHAR				status1;
1592 	ATAPI_STATUS		statusa;
1593 	ATAPI_REASON		reasona;
1594 	ATAPI_ERROR			errora;
1595 	int					z;
1596 	ULONG				zl;
1597     unsigned long		flags;
1598 
1599     /*
1600      * Disable interrupts, if they aren't already disabled and acquire
1601      * the I/O spinlock.
1602      */
1603     spin_lock_irqsave (&io_request_lock, flags);
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 irq_return;
1623 		}
1624 
1625 	padapter = HOSTDATA(shost);
1626 	pdev = padapter->pdev;
1627 	SCpnt = padapter->SCpnt;
1628 	outb_p (0x08, padapter->regDmaCmdStat);									// cancel interrupt from DMA engine
1629 
1630 	if ( padapter->atapi && SCpnt )
1631 		{
1632 		*(char *)&statusa = inb_p (padapter->regStatCmd);						// read the device status
1633 		*(char *)&reasona = inb_p (padapter->regSectCount);						// read the device interrupt reason
1634 
1635 		if ( !statusa.bsy )
1636 			{
1637 			if ( statusa.drq )													// test for transfer phase
1638 				{
1639 				if ( !reasona.cod )												// test for data phase
1640 					{
1641 					z = (ULONG)inb_p (padapter->regLba8) | (ULONG)(inb_p (padapter->regLba16) << 8);
1642 					if ( padapter->reqSense )
1643 						insw (padapter->regData, SCpnt->sense_buffer, z / 2);
1644 					else
1645 						AtapiBusMaster (padapter, reasona.io, z);
1646 					goto irq_return;
1647 					}
1648 				if ( reasona.cod && !reasona.io )								// test for command packet phase
1649 					{
1650 					if ( padapter->reqSense )
1651 						AtapiRequestSense (padapter, pdev, SCpnt, TRUE);
1652 					else
1653 						AtapiSendCdb (padapter, pdev, padapter->atapiCdb);
1654 					goto irq_return;
1655 					}
1656 				}
1657 			else
1658 				{
1659 				if ( reasona.io && statusa.drdy )								// test for status phase
1660 					{
1661 					Atapi2Scsi (padapter, SCpnt);
1662 					if ( statusa.check )
1663 						{
1664 						*(UCHAR *)&errora = inb_p (padapter->regError);			// read the device error
1665 						if ( errora.senseKey )
1666 							{
1667 							if ( padapter->reqSense || AtapiRequestSense (padapter, pdev, SCpnt, FALSE) )
1668 								OpDone (padapter, DID_ERROR << 16);
1669 							}
1670 						else
1671 							{
1672 							if ( errora.ili || errora.abort )
1673 								OpDone (padapter, DID_ERROR << 16);
1674 							else
1675 								OpDone (padapter, DID_OK << 16);
1676 							}
1677 						}
1678 					else
1679 						if ( padapter->reqSense )
1680 							{
1681 							DEB (printk ("PCI2242I: Sense codes - %X %X %X ", ((UCHAR *)SCpnt->sense_buffer)[0], ((UCHAR *)SCpnt->sense_buffer)[12], ((UCHAR *)SCpnt->sense_buffer)[13]));
1682 							OpDone (padapter, (DRIVER_SENSE << 24) | (DID_OK << 16) | 2);
1683 							}
1684 						else
1685 							OpDone (padapter, DID_OK << 16);
1686 					}
1687 				}
1688 			}
1689 		goto irq_return;
1690 		}
1691 
1692 	if ( !padapter->expectingIRQ || !(SCpnt || padapter->reconPhase) )
1693 		{
1694 		DEB(printk ("\npci2220i Unsolicited interrupt\n"));
1695 		STOP_HERE ();
1696 		goto irq_return;
1697 		}
1698 	padapter->expectingIRQ = 0;
1699 
1700 	if ( padapter->failinprog )
1701 		{
1702 		DEB (printk ("\npci2220i interrupt failover complete"));
1703 		padapter->failinprog = FALSE;
1704 		status = inb_p (padapter->regStatCmd);								// read the device status
1705 		if ( status & (IDE_STATUS_ERROR | IDE_STATUS_WRITE_FAULT) )
1706 			{
1707 			DEB (printk ("\npci2220i: interrupt failover error from drive %X", status));
1708 			padapter->cmd = 0;
1709 			}
1710 		else
1711 			{
1712 			DEB (printk ("\npci2220i: restarting failed opertation."));
1713 			pdev->spigot = (padapter->survivor) ? pdev->spigots[1] : pdev->spigots[0];
1714 			del_timer (&padapter->timer);
1715 			if ( padapter->reconPhase )
1716 				OpDone (padapter, DID_OK << 16);
1717 			else
1718 				Pci2220i_QueueCommand (SCpnt, SCpnt->scsi_done);
1719 			goto irq_return;
1720 			}
1721 		}
1722 
1723 	if ( padapter->reconPhase )
1724 		{
1725 		switch ( padapter->reconPhase )
1726 			{
1727 			case RECON_PHASE_MARKING:
1728 			case RECON_PHASE_LAST:
1729 				status = inb_p (padapter->regStatCmd);						// read the device status
1730 				del_timer (&padapter->timer);
1731 				if ( padapter->reconPhase == RECON_PHASE_LAST )
1732 					{
1733 					if ( status & (IDE_STATUS_ERROR | IDE_STATUS_WRITE_FAULT) )
1734 						{
1735 						padapter->survivor = ( pdev->spigot == pdev->spigots[0] ) ? 1 : 0;
1736 						DEB (printk ("\npci2220i: FAILURE 10"));
1737 						if ( InitFailover (padapter, pdev) )
1738 							OpDone (padapter, DecodeError (padapter, status));
1739 						goto irq_return;
1740 						}
1741 					if ( WriteSignature (padapter, pdev, pdev->spigots[pdev->mirrorRecon], pdev->mirrorRecon) )
1742 						{
1743 						padapter->survivor = ( pdev->spigot == pdev->spigots[0] ) ? 0 : 1;
1744 						DEB (printk ("\npci2220i: FAILURE 11"));
1745 						if ( InitFailover (padapter, pdev) )
1746 							OpDone (padapter, DecodeError (padapter, status));
1747 						goto irq_return;
1748 						}
1749 					padapter->reconPhase = RECON_PHASE_END;
1750 					goto irq_return;
1751 					}
1752 				OpDone (padapter, DID_OK << 16);
1753 				goto irq_return;
1754 
1755 			case RECON_PHASE_READY:
1756 				status = inb_p (padapter->regStatCmd);						// read the device status
1757 				if ( status & (IDE_STATUS_ERROR | IDE_STATUS_WRITE_FAULT) )
1758 					{
1759 					del_timer (&padapter->timer);
1760 					OpDone (padapter, DecodeError (padapter, status));
1761 					goto irq_return;
1762 					}
1763 				SelectSpigot (padapter, pdev->spigots[pdev->mirrorRecon]);
1764 				if ( WaitDrq (padapter) )
1765 					{
1766 					del_timer (&padapter->timer);
1767 					padapter->survivor = ( pdev->spigot == pdev->spigots[0] ) ? 0 : 1;
1768 					DEB (printk ("\npci2220i: FAILURE 12"));
1769 					if ( InitFailover (padapter, pdev) )
1770 						OpDone (padapter, DecodeError (padapter, status));
1771 					goto irq_return;
1772 					}
1773 				SelectSpigot (padapter, pdev->spigot | SEL_COPY | padapter->bigD);
1774 				padapter->reconPhase = RECON_PHASE_COPY;
1775 				padapter->expectingIRQ = TRUE;
1776 				if ( padapter->timingPIO )
1777 					{
1778 					insw (padapter->regData, padapter->kBuffer, padapter->reconSize * (BYTES_PER_SECTOR / 2));
1779 					}
1780 				else
1781 					{
1782 					if ( (padapter->timingMode > 3) )
1783 						{
1784 						if ( padapter->bigD )
1785 							outl (BIGD_DATA_MODE3, padapter->regDmaAddrLoc);
1786 						else
1787 							outl (DALE_DATA_MODE3, padapter->regDmaAddrLoc);
1788 						}
1789 					else
1790 						outl (padapter->timingAddress, padapter->regDmaAddrLoc);
1791 					outl (padapter->kBufferDma, padapter->regDmaAddrPci);
1792 					outl (padapter->reconSize * BYTES_PER_SECTOR, padapter->regDmaCount);
1793 					outb_p (8, padapter->regDmaDesc);						// read operation
1794 					if ( padapter->bigD )
1795 						outb_p (8, padapter->regDmaMode);					// no interrupt
1796 					else
1797 						outb_p (1, padapter->regDmaMode);					// no interrupt
1798 					outb_p (0x03, padapter->regDmaCmdStat);					// kick the DMA engine in gear
1799 					}
1800 				goto irq_return;
1801 
1802 			case RECON_PHASE_COPY:
1803 				pdev->DiskMirror[pdev->mirrorRecon].reconstructPoint += padapter->reconSize;
1804 
1805 			case RECON_PHASE_UPDATE:
1806 				SelectSpigot (padapter, pdev->spigots[pdev->mirrorRecon] | SEL_IRQ_OFF);
1807 				status = inb_p (padapter->regStatCmd);						// read the device status
1808 				del_timer (&padapter->timer);
1809 				if ( status & (IDE_STATUS_ERROR | IDE_STATUS_WRITE_FAULT) )
1810 					{
1811 					padapter->survivor = ( pdev->spigot == pdev->spigots[0] ) ? 0 : 1;
1812 					DEB (printk ("\npci2220i: FAILURE 13"));
1813 					DEB (printk ("\n  status register = %X   error = %X", status, inb_p (padapter->regError)));
1814 					if ( InitFailover (padapter, pdev) )
1815 						OpDone (padapter, DecodeError (padapter, status));
1816 					goto irq_return;
1817 					}
1818 				OpDone (padapter, DID_OK << 16);
1819 				goto irq_return;
1820 
1821 			case RECON_PHASE_END:
1822 				status = inb_p (padapter->regStatCmd);						// read the device status
1823 				del_timer (&padapter->timer);
1824 				if ( status & (IDE_STATUS_ERROR | IDE_STATUS_WRITE_FAULT) )
1825 					{
1826 					padapter->survivor = ( pdev->spigot == pdev->spigots[0] ) ? 0 : 1;
1827 					DEB (printk ("\npci2220i: FAILURE 14"));
1828 					if ( InitFailover (padapter, pdev) )
1829 						OpDone (padapter, DecodeError (padapter, status));
1830 					goto irq_return;
1831 					}
1832 				pdev->reconOn = 0;
1833 				if ( padapter->bigD )
1834 					{
1835 					for ( z = 0;  z < padapter->numberOfDrives;  z++ )
1836 						{
1837 						if ( padapter->device[z].DiskMirror[0].status & UCBF_SURVIVOR )
1838 							{
1839 							Alarm (padapter, padapter->device[z].deviceID[0] ^ 2);
1840 							MuteAlarm (padapter);
1841 							}
1842 						if ( padapter->device[z].DiskMirror[1].status & UCBF_SURVIVOR )
1843 							{
1844 							Alarm (padapter, padapter->device[z].deviceID[1] ^ 2);
1845 							MuteAlarm (padapter);
1846 							}
1847 						}
1848 					}
1849 				OpDone (padapter, DID_OK << 16);
1850 				goto irq_return;
1851 
1852 			default:
1853 				goto irq_return;
1854 			}
1855 		}
1856 
1857 	switch ( padapter->cmd )												// decide how to handle the interrupt
1858 		{
1859 		case READ_CMD:
1860 			if ( padapter->sectorCount )
1861 				{
1862 				status = inb_p (padapter->regStatCmd);						// read the device status
1863 				if ( status & (IDE_STATUS_ERROR | IDE_STATUS_WRITE_FAULT) )
1864 					{
1865 					if ( pdev->raid )
1866 						{
1867 						padapter->survivor = ( pdev->spigot == pdev->spigots[0] ) ? 1 : 0;
1868 						del_timer (&padapter->timer);
1869 						DEB (printk ("\npci2220i: FAILURE 15"));
1870 						if ( !InitFailover (padapter, pdev) )
1871 							goto irq_return;
1872 						}
1873 					break;
1874 					}
1875 				if ( padapter->timingPIO )
1876 					{
1877 					insw (padapter->regData, padapter->kBuffer, padapter->readCount / 2);
1878 					padapter->sectorCount -= padapter->readCount / BYTES_PER_SECTOR;
1879 					WalkScatGath (padapter, TRUE, padapter->readCount);
1880 					if ( !padapter->sectorCount )
1881 						{
1882 						status = 0;
1883 						break;
1884 						}
1885 					}
1886 				else
1887 					{
1888 					if ( padapter->readCount )
1889 						WalkScatGath (padapter, TRUE, padapter->readCount);
1890 					BusMaster (padapter, 1, 1);
1891 					}
1892 				padapter->expectingIRQ = TRUE;
1893 				goto irq_return;
1894 				}
1895 			if ( padapter->readCount && !padapter->timingPIO )
1896 				WalkScatGath (padapter, TRUE, padapter->readCount);
1897 			status = 0;
1898 			break;
1899 
1900 		case WRITE_CMD:
1901 			if ( pdev->raid )
1902 				{
1903 				SelectSpigot (padapter, pdev->spigots[0] | SEL_IRQ_OFF);
1904 				status = inb_p (padapter->regStatCmd);								// read the device status
1905 				SelectSpigot (padapter, pdev->spigots[1] | SEL_IRQ_OFF);
1906 				status1 = inb_p (padapter->regStatCmd);								// read the device status
1907 				}
1908 			else
1909 				SelectSpigot (padapter, pdev->spigot | SEL_IRQ_OFF);
1910 				status = inb_p (padapter->regStatCmd);								// read the device status
1911 				status1 = 0;
1912 
1913 			if ( status & (IDE_STATUS_ERROR | IDE_STATUS_WRITE_FAULT) )
1914 				{
1915 				if ( pdev->raid && !(status1 & (IDE_STATUS_ERROR | IDE_STATUS_WRITE_FAULT)) )
1916 					{
1917 					padapter->survivor = 1;
1918 					del_timer (&padapter->timer);
1919 					SelectSpigot (padapter, pdev->spigot | SEL_IRQ_OFF);
1920 					DEB (printk ("\npci2220i: FAILURE 16  status = %X  error = %X", status, inb_p (padapter->regError)));
1921 					if ( !InitFailover (padapter, pdev) )
1922 						goto irq_return;
1923 					}
1924 				break;
1925 				}
1926 			if ( pdev->raid )
1927 				{
1928 				if ( status1 & (IDE_STATUS_ERROR | IDE_STATUS_WRITE_FAULT) )
1929 					{
1930 					padapter->survivor = 0;
1931 					del_timer (&padapter->timer);
1932 					DEB (printk ("\npci2220i: FAILURE 17  status = %X  error = %X", status1, inb_p (padapter->regError)));
1933 					if ( !InitFailover (padapter, pdev) )
1934 						goto irq_return;
1935 					status = status1;
1936 					break;
1937 					}
1938 				if ( padapter->sectorCount )
1939 					{
1940 					status = WriteDataBoth (padapter, pdev);
1941 					if ( status )
1942 						{
1943 						padapter->survivor = status >> 1;
1944 						del_timer (&padapter->timer);
1945 						DEB (printk ("\npci2220i: FAILURE 18"));
1946 						if ( !InitFailover (padapter, pdev) )
1947 							goto irq_return;
1948 						SelectSpigot (padapter, pdev->spigots[status] | SEL_IRQ_OFF);
1949 						status = inb_p (padapter->regStatCmd);								// read the device status
1950 						break;
1951 						}
1952 					padapter->expectingIRQ = TRUE;
1953 					goto irq_return;
1954 					}
1955 				status = 0;
1956 				break;
1957 				}
1958 			if ( padapter->sectorCount )
1959 				{
1960 				SelectSpigot (padapter, pdev->spigot | padapter->bigD);
1961 				status = WriteData (padapter);
1962 				if ( status )
1963 					break;
1964 				padapter->expectingIRQ = TRUE;
1965 				goto irq_return;
1966 				}
1967 			status = 0;
1968 			break;
1969 
1970 		case IDE_COMMAND_IDENTIFY:
1971 			{
1972 			PINQUIRYDATA	pinquiryData  = SCpnt->request_buffer;
1973 			PIDENTIFY_DATA	pid = (PIDENTIFY_DATA)padapter->kBuffer;
1974 
1975 			status = inb_p (padapter->regStatCmd);
1976 			if ( status & IDE_STATUS_DRQ )
1977 				{
1978 				insw (padapter->regData, pid, sizeof (IDENTIFY_DATA) >> 1);
1979 
1980 				memset (pinquiryData, 0, SCpnt->request_bufflen);		// Zero INQUIRY data structure.
1981 				pinquiryData->DeviceType = 0;
1982 				pinquiryData->Versions = 2;
1983 				pinquiryData->AdditionalLength = 35 - 4;
1984 
1985 				// Fill in vendor identification fields.
1986 				for ( z = 0;  z < 20;  z += 2 )
1987 					{
1988 					pinquiryData->VendorId[z]	  = ((UCHAR *)pid->ModelNumber)[z + 1];
1989 					pinquiryData->VendorId[z + 1] = ((UCHAR *)pid->ModelNumber)[z];
1990 					}
1991 
1992 				// Initialize unused portion of product id.
1993 				for ( z = 0;  z < 4;  z++ )
1994 					pinquiryData->ProductId[12 + z] = ' ';
1995 
1996 				// Move firmware revision from IDENTIFY data to
1997 				// product revision in INQUIRY data.
1998 				for ( z = 0;  z < 4;  z += 2 )
1999 					{
2000 					pinquiryData->ProductRevisionLevel[z]	 = ((UCHAR *)pid->FirmwareRevision)[z + 1];
2001 					pinquiryData->ProductRevisionLevel[z + 1] = ((UCHAR *)pid->FirmwareRevision)[z];
2002 					}
2003 				if ( pdev == padapter->device )
2004 					*((USHORT *)(&pinquiryData->VendorSpecific)) = DEVICE_DALE_1;
2005 
2006 				status = 0;
2007 				}
2008 			break;
2009 			}
2010 
2011 		default:
2012 			status = 0;
2013 			break;
2014 		}
2015 
2016 	del_timer (&padapter->timer);
2017 	if ( status )
2018 		{
2019 		DEB (printk ("\npci2220i Interrupt handler return error"));
2020 		zl = DecodeError (padapter, status);
2021 		}
2022 	else
2023 		zl = DID_OK << 16;
2024 
2025 	OpDone (padapter, zl);
2026 irq_return:;
2027     /*
2028      * Release the I/O spinlock and restore the original flags
2029      * which will enable interrupts if and only if they were
2030      * enabled on entry.
2031      */
2032     spin_unlock_irqrestore (&io_request_lock, flags);
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  ****************************************************************/
Pci2220i_QueueCommand(Scsi_Cmnd * SCpnt,void (* done)(Scsi_Cmnd *))2045 int 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->host);			// Pointer to adapter control structure
2049 	POUR_DEVICE		pdev	 = &padapter->device[SCpnt->target];// 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->target, SCpnt->lun, *cdb));
2081 		padapter->pdev = pdev;
2082 		if ( !pdev->byte6 || SCpnt->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->target >= padapter->numberOfDrives) || SCpnt->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 	}
internal_done(Scsi_Cmnd * SCpnt)2310 static void internal_done(Scsi_Cmnd *SCpnt)
2311 	{
2312 	SCpnt->SCp.Status++;
2313 	}
2314 /****************************************************************
2315  *	Name:	Pci2220i_Command
2316  *
2317  *	Description:	Process a command from the SCSI manager.
2318  *
2319  *	Parameters:		SCpnt - Pointer to SCSI command structure.
2320  *
2321  *	Returns:		Status code.
2322  *
2323  ****************************************************************/
Pci2220i_Command(Scsi_Cmnd * SCpnt)2324 int Pci2220i_Command (Scsi_Cmnd *SCpnt)
2325 	{
2326 	Pci2220i_QueueCommand (SCpnt, internal_done);
2327     SCpnt->SCp.Status = 0;
2328 	while (!SCpnt->SCp.Status)
2329 		barrier ();
2330 	return SCpnt->result;
2331 	}
2332 /****************************************************************
2333  *	Name:			ReadFlash
2334  *
2335  *	Description:	Read information from controller Flash memory.
2336  *
2337  *	Parameters:		padapter - Pointer to host interface data structure.
2338  *					pdata	 - Pointer to data structures.
2339  *					base	 - base address in Flash.
2340  *					length	 - lenght of data space in bytes.
2341  *
2342  *	Returns:		Nothing.
2343  *
2344  ****************************************************************/
ReadFlash(PADAPTER2220I padapter,VOID * pdata,ULONG base,ULONG length)2345 static VOID ReadFlash (PADAPTER2220I padapter, VOID *pdata, ULONG base, ULONG length)
2346 	{
2347 	ULONG	 oldremap;
2348 	UCHAR	 olddesc;
2349 	ULONG	 z;
2350 	UCHAR	*pd = (UCHAR *)pdata;
2351 
2352 	oldremap = inl (padapter->regRemap);							// save values to restore later
2353 	olddesc  = inb_p (padapter->regDesc);
2354 
2355 	outl (base | 1, padapter->regRemap);							// remap to Flash space as specified
2356 	outb_p (0x40, padapter->regDesc);								// describe remap region as 8 bit
2357 	for ( z = 0;  z < length;  z++)									// get "length" data count
2358 		*pd++ = inb_p (padapter->regBase + z);						// read in the data
2359 
2360 	outl (oldremap, padapter->regRemap);							// restore remap register values
2361 	outb_p (olddesc, padapter->regDesc);
2362 	}
2363 /****************************************************************
2364  *	Name:			GetRegs
2365  *
2366  *	Description:	Initialize the regester information.
2367  *
2368  *	Parameters:		pshost		  - Pointer to SCSI host data structure.
2369  *					bigd		  - PCI-2240I identifier
2370  *					pcidev		  - Pointer to device data structure.
2371  *
2372  *	Returns:		TRUE if failure to install.
2373  *
2374  ****************************************************************/
GetRegs(struct Scsi_Host * pshost,BOOL bigd,struct pci_dev * pcidev)2375 static USHORT GetRegs (struct Scsi_Host *pshost, BOOL bigd, struct pci_dev *pcidev)
2376 	{
2377 	PADAPTER2220I	padapter;
2378 	int				setirq;
2379 	int				z;
2380 	USHORT			zr, zl;
2381 	UCHAR		   *consistent;
2382 	dma_addr_t		consistentDma;
2383 
2384 	padapter = HOSTDATA(pshost);
2385 	memset (padapter, 0, sizeof (ADAPTER2220I));
2386 	memset (&DaleSetup, 0, sizeof (DaleSetup));
2387 	memset (DiskMirror, 0, sizeof (DiskMirror));
2388 
2389 	zr = pci_resource_start (pcidev, 1);
2390 	zl = pci_resource_start (pcidev, 2);
2391 
2392 	padapter->basePort = zr;
2393 	padapter->regRemap		= zr + RTR_LOCAL_REMAP;					// 32 bit local space remap
2394 	padapter->regDesc		= zr + RTR_REGIONS;	  					// 32 bit local region descriptor
2395 	padapter->regRange		= zr + RTR_LOCAL_RANGE;					// 32 bit local range
2396 	padapter->regIrqControl	= zr + RTR_INT_CONTROL_STATUS;			// 16 bit interupt control and status
2397 	padapter->regScratchPad	= zr + RTR_MAILBOX;	  					// 16 byte scratchpad I/O base address
2398 
2399 	padapter->regBase		= zl;
2400 	padapter->regData		= zl + REG_DATA;						// data register I/O address
2401 	padapter->regError		= zl + REG_ERROR;						// error register I/O address
2402 	padapter->regSectCount	= zl + REG_SECTOR_COUNT;				// sector count register I/O address
2403 	padapter->regLba0		= zl + REG_LBA_0;						// least significant byte of LBA
2404 	padapter->regLba8		= zl + REG_LBA_8;						// next least significant byte of LBA
2405 	padapter->regLba16		= zl + REG_LBA_16;						// next most significan byte of LBA
2406 	padapter->regLba24		= zl + REG_LBA_24;						// head and most 4 significant bits of LBA
2407 	padapter->regStatCmd	= zl + REG_STAT_CMD;					// status on read and command on write register
2408 	padapter->regStatSel	= zl + REG_STAT_SEL;					// board status on read and spigot select on write register
2409 	padapter->regFail		= zl + REG_FAIL;
2410 	padapter->regAltStat	= zl + REG_ALT_STAT;
2411 	padapter->pcidev		= pcidev;
2412 
2413 	if ( bigd )
2414 		{
2415 		padapter->regDmaDesc	= zr + RTR_DMA0_DESC_PTR;			// address of the DMA discriptor register for direction of transfer
2416 		padapter->regDmaCmdStat	= zr + RTR_DMA_COMMAND_STATUS;		// Byte #0 of DMA command status register
2417 		padapter->regDmaAddrPci	= zr + RTR_DMA0_PCI_ADDR;			// 32 bit register for PCI address of DMA
2418 		padapter->regDmaAddrLoc	= zr + RTR_DMA0_LOCAL_ADDR;			// 32 bit register for local bus address of DMA
2419 		padapter->regDmaCount	= zr + RTR_DMA0_COUNT;				// 32 bit register for DMA transfer count
2420 		padapter->regDmaMode	= zr + RTR_DMA0_MODE + 1;			// 32 bit register for DMA mode control
2421 		padapter->bigD			= SEL_NEW_SPEED_1;					// set spigot speed control bit
2422 		}
2423 	else
2424 		{
2425 		padapter->regDmaDesc	= zl + RTL_DMA1_DESC_PTR;			// address of the DMA discriptor register for direction of transfer
2426 		padapter->regDmaCmdStat	= zl + RTL_DMA_COMMAND_STATUS + 1;	// Byte #1 of DMA command status register
2427 		padapter->regDmaAddrPci	= zl + RTL_DMA1_PCI_ADDR;			// 32 bit register for PCI address of DMA
2428 		padapter->regDmaAddrLoc	= zl + RTL_DMA1_LOCAL_ADDR;			// 32 bit register for local bus address of DMA
2429 		padapter->regDmaCount	= zl + RTL_DMA1_COUNT;				// 32 bit register for DMA transfer count
2430 		padapter->regDmaMode	= zl + RTL_DMA1_MODE + 1;			// 32 bit register for DMA mode control
2431 		}
2432 
2433 	padapter->numberOfDrives = inb_p (padapter->regScratchPad + BIGD_NUM_DRIVES);
2434 	if ( !bigd && !padapter->numberOfDrives )						// if no devices on this board
2435 		return TRUE;
2436 
2437 	pshost->irq = pcidev->irq;
2438 	setirq = 1;
2439 	for ( z = 0;  z < Installed;  z++ )								// scan for shared interrupts
2440 		{
2441 		if ( PsiHost[z]->irq == pshost->irq )						// if shared then, don't posses
2442 			setirq = 0;
2443 		}
2444 	if ( setirq )													// if not shared, posses
2445 		{
2446 		if ( request_irq (pshost->irq, Irq_Handler, SA_SHIRQ, "pci2220i", padapter) < 0 )
2447 			{
2448 			if ( request_irq (pshost->irq, Irq_Handler, SA_INTERRUPT | SA_SHIRQ, "pci2220i", padapter) < 0 )
2449 				{
2450 				printk ("Unable to allocate IRQ for PCI-2220I controller.\n");
2451 				return TRUE;
2452 				}
2453 			}
2454 		padapter->irqOwned = pshost->irq;							// set IRQ as owned
2455 		}
2456 
2457 	if ( padapter->numberOfDrives )
2458 		consistent = pci_alloc_consistent (pcidev, SECTORSXFER * BYTES_PER_SECTOR, &consistentDma);
2459 	else
2460 		consistent = pci_alloc_consistent (pcidev, ATAPI_TRANSFER, &consistentDma);
2461 	if ( !consistent )
2462 		{
2463 		printk ("Unable to allocate DMA buffer for PCI-2220I controller.\n");
2464 		free_irq (pshost->irq, padapter);
2465 		return TRUE;
2466 		}
2467 	padapter->kBuffer = consistent;
2468 	padapter->kBufferDma = consistentDma;
2469 
2470 	PsiHost[Installed]	= pshost;									// save SCSI_HOST pointer
2471 	pshost->io_port		= padapter->basePort;
2472 	pshost->n_io_port	= 0xFF;
2473 	pshost->unique_id	= padapter->regBase;
2474 
2475 	outb_p (0x01, padapter->regRange);								// fix our range register because other drivers want to tromp on it
2476 
2477 	padapter->timingMode = inb_p (padapter->regScratchPad + DALE_TIMING_MODE);
2478 	if ( padapter->timingMode >= 2 )
2479 		{
2480 		if ( bigd )
2481 			padapter->timingAddress	= ModeArray2[padapter->timingMode - 2];
2482 		else
2483 			padapter->timingAddress	= ModeArray[padapter->timingMode - 2];
2484 		}
2485 	else
2486 		padapter->timingPIO = TRUE;
2487 
2488 	ReadFlash (padapter, &DaleSetup, DALE_FLASH_SETUP, sizeof (SETUP));
2489 	ReadFlash (padapter, &DiskMirror, DALE_FLASH_RAID, sizeof (DiskMirror));
2490 
2491 	return FALSE;
2492 	}
2493 /****************************************************************
2494  *	Name:			SetupFinish
2495  *
2496  *	Description:	Complete the driver initialization process for a card
2497  *
2498  *	Parameters:		padapter  - Pointer to SCSI host data structure.
2499  *					str		  - Pointer to board type string.
2500  *
2501  *	Returns:		Nothing.
2502  *
2503  ****************************************************************/
SetupFinish(PADAPTER2220I padapter,char * str,int irq)2504 VOID SetupFinish (PADAPTER2220I padapter, char *str, int irq)
2505 	{
2506 	init_timer (&padapter->timer);
2507 	padapter->timer.function = TimerExpiry;
2508 	padapter->timer.data = (unsigned long)padapter;
2509 	init_timer (&padapter->reconTimer);
2510 	padapter->reconTimer.function = ReconTimerExpiry;
2511 	padapter->reconTimer.data = (unsigned long)padapter;
2512 	printk("\nPCI-%sI EIDE CONTROLLER: at I/O = %lX/%lX  IRQ = %d\n", str, padapter->basePort, padapter->regBase, irq);
2513 	printk("Version %s, Compiled %s %s\n\n", PCI2220I_VERSION, __DATE__, __TIME__);
2514 	}
2515 /****************************************************************
2516  *	Name:	Pci2220i_Detect
2517  *
2518  *	Description:	Detect and initialize our boards.
2519  *
2520  *	Parameters:		tpnt - Pointer to SCSI host template structure.
2521  *
2522  *	Returns:		Number of adapters installed.
2523  *
2524  ****************************************************************/
Pci2220i_Detect(Scsi_Host_Template * tpnt)2525 int Pci2220i_Detect (Scsi_Host_Template *tpnt)
2526 	{
2527 	struct Scsi_Host   *pshost;
2528 	PADAPTER2220I	    padapter;
2529 	POUR_DEVICE			pdev;
2530 	int					unit;
2531 	int					z;
2532 	USHORT				raidon;
2533 	UCHAR				spigot1, spigot2;
2534 	UCHAR				device;
2535 	struct pci_dev	   *pcidev = NULL;
2536 
2537 	if ( !pci_present () )
2538 		{
2539 		printk ("pci2220i: PCI BIOS not present\n");
2540 		return 0;
2541 		}
2542 
2543 	while ( (pcidev = pci_find_device (VENDOR_PSI, DEVICE_DALE_1, pcidev)) != NULL )
2544 		{
2545 		if (pci_enable_device(pcidev))
2546 			continue;
2547 		pshost = scsi_register (tpnt, sizeof(ADAPTER2220I));
2548 		if(pshost==NULL)
2549 			continue;
2550 
2551 		padapter = HOSTDATA(pshost);
2552 
2553 		if ( GetRegs (pshost, FALSE, pcidev) )
2554 			goto unregister;
2555 
2556 		scsi_set_pci_device(pshost, pcidev);
2557 		pshost->max_id = padapter->numberOfDrives;
2558 		for ( z = 0;  z < padapter->numberOfDrives;  z++ )
2559 			{
2560 			unit = inb_p (padapter->regScratchPad + DALE_CHANNEL_DEVICE_0 + z) & 0x0F;
2561 			pdev = &padapter->device[z];
2562 			pdev->byte6		= (UCHAR)(((unit & 1) << 4) | 0xE0);
2563 			pdev->spigot	= (UCHAR)(1 << (unit >> 1));
2564 			pdev->sectors	= DaleSetup.setupDevice[unit].sectors;
2565 			pdev->heads		= DaleSetup.setupDevice[unit].heads;
2566 			pdev->cylinders = DaleSetup.setupDevice[unit].cylinders;
2567 			pdev->blocks	= DaleSetup.setupDevice[unit].blocks;
2568 
2569 			if ( !z )
2570 				{
2571 				DiskMirror[0].status = inb_p (padapter->regScratchPad + DALE_RAID_0_STATUS);
2572 				DiskMirror[1].status = inb_p (padapter->regScratchPad + DALE_RAID_1_STATUS);
2573 				if ( (DiskMirror[0].signature == SIGNATURE) && (DiskMirror[1].signature == SIGNATURE) &&
2574 				     (DiskMirror[0].pairIdentifier == (DiskMirror[1].pairIdentifier ^ 1)) )
2575 					{
2576 					raidon = TRUE;
2577 					if ( unit > (unit ^ 2) )
2578 						unit = unit ^ 2;
2579 					}
2580 				else
2581 					raidon = FALSE;
2582 
2583 				memcpy (pdev->DiskMirror, DiskMirror, sizeof (DiskMirror));
2584 				padapter->raidData[0] = &pdev->DiskMirror[0];
2585 				padapter->raidData[2] = &pdev->DiskMirror[1];
2586 
2587 				spigot1 = spigot2 = FALSE;
2588 				pdev->spigots[0] = 1;
2589 				pdev->spigots[1] = 2;
2590 				pdev->lastsectorlba[0] = InlineIdentify (padapter, 1, 0);
2591 				pdev->lastsectorlba[1] = InlineIdentify (padapter, 2, 0);
2592 
2593 				if ( !(pdev->DiskMirror[1].status & UCBF_SURVIVOR) && pdev->lastsectorlba[0] )
2594 					spigot1 = TRUE;
2595 				if ( !(pdev->DiskMirror[0].status & UCBF_SURVIVOR) && pdev->lastsectorlba[1] )
2596 					spigot2 = TRUE;
2597 				if ( pdev->DiskMirror[0].status & DiskMirror[1].status & UCBF_SURVIVOR )
2598 					spigot1 = TRUE;
2599 
2600 				if ( spigot1 && (pdev->DiskMirror[0].status & UCBF_REBUILD) )
2601 					InlineReadSignature (padapter, pdev, 0);
2602 				if ( spigot2 && (pdev->DiskMirror[1].status & UCBF_REBUILD) )
2603 					InlineReadSignature (padapter, pdev, 1);
2604 
2605 				if ( spigot1 && spigot2 && raidon )
2606 					{
2607 					pdev->raid = 1;
2608 					if ( pdev->DiskMirror[0].status & UCBF_REBUILD )
2609 						pdev->spigot = 2;
2610 					else
2611 						pdev->spigot = 1;
2612 					if ( (pdev->DiskMirror[0].status & UCBF_REBUILD) || (pdev->DiskMirror[1].status & UCBF_REBUILD) )
2613 						padapter->reconOn = pdev->reconOn = pdev->reconIsStarting = TRUE;
2614 					}
2615 				else
2616 					{
2617 					if ( spigot1 )
2618 						{
2619 						if ( pdev->DiskMirror[0].status & UCBF_REBUILD )
2620 							goto unregister;
2621 						pdev->DiskMirror[0].status = UCBF_MIRRORED | UCBF_SURVIVOR;
2622 						pdev->spigot = 1;
2623 						}
2624 					else
2625 						{
2626 						if ( pdev->DiskMirror[1].status & UCBF_REBUILD )
2627 							goto unregister;
2628 						pdev->DiskMirror[1].status = UCBF_MIRRORED | UCBF_SURVIVOR;
2629 						pdev->spigot = 2;
2630 						}
2631 					if ( DaleSetup.rebootRebuild && raidon )
2632 						padapter->reconOn = pdev->reconOn = pdev->reconIsStarting = TRUE;
2633 					}
2634 
2635 				if ( raidon )
2636 					break;
2637 				}
2638 			}
2639 
2640 		SetupFinish (padapter, "2220", pshost->irq);
2641 
2642 		if ( ++Installed < MAXADAPTER )
2643 			continue;
2644 		break;;
2645 unregister:;
2646 		scsi_unregister (pshost);
2647 		}
2648 
2649 	while ( (pcidev = pci_find_device (VENDOR_PSI, DEVICE_BIGD_1, pcidev)) != NULL )
2650 		{
2651 		pshost = scsi_register (tpnt, sizeof(ADAPTER2220I));
2652 		padapter = HOSTDATA(pshost);
2653 
2654 		if ( GetRegs (pshost, TRUE, pcidev) )
2655 			goto unregister1;
2656 
2657 		for ( z = 0;  z < BIGD_MAXDRIVES;  z++ )
2658 			DiskMirror[z].status = inb_p (padapter->regScratchPad + BIGD_RAID_0_STATUS + z);
2659 
2660 		scsi_set_pci_device(pshost, pcidev);
2661 		pshost->max_id = padapter->numberOfDrives;
2662 		padapter->failRegister = inb_p (padapter->regScratchPad + BIGD_ALARM_IMAGE);
2663 		for ( z = 0;  z < padapter->numberOfDrives;  z++ )
2664 			{
2665 			unit = inb_p (padapter->regScratchPad + BIGD_DEVICE_0 + z);
2666 			pdev = &padapter->device[z];
2667 			pdev->byte6		= (UCHAR)(((unit & 1) << 4) | 0xE0);
2668 			pdev->spigot	= (UCHAR)(1 << (unit >> 1));
2669 			pdev->sectors	= DaleSetup.setupDevice[unit].sectors;
2670 			pdev->heads		= DaleSetup.setupDevice[unit].heads;
2671 			pdev->cylinders = DaleSetup.setupDevice[unit].cylinders;
2672 			pdev->blocks	= DaleSetup.setupDevice[unit].blocks;
2673 
2674 			if ( (DiskMirror[unit].signature == SIGNATURE) && (DiskMirror[unit ^ 2].signature == SIGNATURE) &&
2675 			     (DiskMirror[unit].pairIdentifier == (DiskMirror[unit ^ 2].pairIdentifier ^ 1)) )
2676 				{
2677 				raidon = TRUE;
2678 				if ( unit > (unit ^ 2) )
2679 					unit = unit ^ 2;
2680 				}
2681 			else
2682 				raidon = FALSE;
2683 
2684 			spigot1 = spigot2 = FALSE;
2685 			memcpy (&pdev->DiskMirror[0], &DiskMirror[unit], sizeof (DISK_MIRROR));
2686 			memcpy (&pdev->DiskMirror[1], &DiskMirror[unit ^ 2], sizeof (DISK_MIRROR));
2687 			padapter->raidData[unit]	 = &pdev->DiskMirror[0];
2688 			padapter->raidData[unit ^ 2] = &pdev->DiskMirror[1];
2689 			pdev->spigots[0] = 1 << (unit >> 1);
2690 			pdev->spigots[1] = 1 << ((unit ^ 2) >> 1);
2691 			pdev->deviceID[0] = unit;
2692 			pdev->deviceID[1] = unit ^ 2;
2693 			pdev->lastsectorlba[0] = InlineIdentify (padapter, pdev->spigots[0], unit & 1);
2694 			pdev->lastsectorlba[1] = InlineIdentify (padapter, pdev->spigots[1], unit & 1);
2695 
2696 			if ( !(pdev->DiskMirror[1].status & UCBF_SURVIVOR) && pdev->lastsectorlba[0] )
2697 				spigot1 = TRUE;
2698 			if ( !(pdev->DiskMirror[0].status & UCBF_SURVIVOR) && pdev->lastsectorlba[1] )
2699 				spigot2 = TRUE;
2700 			if ( pdev->DiskMirror[0].status & pdev->DiskMirror[1].status & UCBF_SURVIVOR )
2701 				spigot1 = TRUE;
2702 
2703 			if ( spigot1 && (pdev->DiskMirror[0].status & UCBF_REBUILD) )
2704 				InlineReadSignature (padapter, pdev, 0);
2705 			if ( spigot2 && (pdev->DiskMirror[1].status & UCBF_REBUILD) )
2706 				InlineReadSignature (padapter, pdev, 1);
2707 
2708 			if ( spigot1 && spigot2 && raidon )
2709 				{
2710 				pdev->raid = 1;
2711 				if ( pdev->DiskMirror[0].status & UCBF_REBUILD )
2712 					pdev->spigot = pdev->spigots[1];
2713 				else
2714 					pdev->spigot = pdev->spigots[0];
2715 				if ( (pdev->DiskMirror[0].status & UCBF_REBUILD) || (pdev->DiskMirror[1].status & UCBF_REBUILD) )
2716 					padapter->reconOn = pdev->reconOn = pdev->reconIsStarting = TRUE;
2717 				}
2718 			else
2719 				{
2720 				if ( spigot1 )
2721 					{
2722 					if ( pdev->DiskMirror[0].status & UCBF_REBUILD )
2723 						goto unregister1;
2724 					pdev->DiskMirror[0].status = UCBF_MIRRORED | UCBF_SURVIVOR;
2725 					pdev->spigot = pdev->spigots[0];
2726 					}
2727 				else
2728 					{
2729 					if ( pdev->DiskMirror[1].status & UCBF_REBUILD )
2730 						goto unregister;
2731 					pdev->DiskMirror[1].status = UCBF_MIRRORED | UCBF_SURVIVOR;
2732 					pdev->spigot = pdev->spigots[1];
2733 					}
2734 				if ( DaleSetup.rebootRebuild && raidon )
2735 					padapter->reconOn = pdev->reconOn = pdev->reconIsStarting = TRUE;
2736 				}
2737 			}
2738 
2739 		if ( !padapter->numberOfDrives )									// If no ATA devices then scan ATAPI
2740 			{
2741 			unit = 0;
2742 			for ( spigot1 = 0;  spigot1 < 4;  spigot1++ )
2743 				{
2744 				for ( device = 0;  device < 2;  device++ )
2745 					{
2746 					DEB (printk ("\nPCI2242I: scanning for ID %d ", (spigot1 * 2) + device));
2747 					pdev = &(padapter->device[(spigot1 * 2) + device]);
2748 					pdev->byte6 = 0x0A | (device << 4);
2749 					pdev->spigot = 1 << spigot1;
2750 					if ( !AtapiReset (padapter, pdev) )
2751 						{
2752 						DEB (printk (" Device found "));
2753 						if ( !AtapiIdentify (padapter, pdev) )
2754 							{
2755 							DEB (printk (" Device verified"));
2756 							unit++;
2757 							continue;
2758 							}
2759 						}
2760 					pdev->spigot = pdev->byte6 = 0;
2761 					}
2762 				}
2763 
2764 			if ( unit )
2765 				{
2766 				padapter->atapi = TRUE;
2767 				padapter->timingAddress = DALE_DATA_MODE3;
2768 				outw_p (0x0900, padapter->regIrqControl);					// Turn our interrupts on
2769 				outw_p (0x0C41, padapter->regDmaMode - 1);					// setup for 16 bits, ready enabled, done IRQ enabled, no incriment
2770 				outb_p (0xFF, padapter->regFail);							// all fail lights and alarm off
2771 				pshost->max_id = 8;
2772 				}
2773 			}
2774 		SetupFinish (padapter, "2240", pshost->irq);
2775 
2776 		if ( ++Installed < MAXADAPTER )
2777 			continue;
2778 		break;;
2779 unregister1:;
2780 		scsi_unregister (pshost);
2781 		}
2782 
2783 	NumAdapters = Installed;
2784 	return Installed;
2785 	}
2786 /****************************************************************
2787  *	Name:	Pci2220i_Abort
2788  *
2789  *	Description:	Process the Abort command from the SCSI manager.
2790  *
2791  *	Parameters:		SCpnt - Pointer to SCSI command structure.
2792  *
2793  *	Returns:		Allways snooze.
2794  *
2795  ****************************************************************/
Pci2220i_Abort(Scsi_Cmnd * SCpnt)2796 int Pci2220i_Abort (Scsi_Cmnd *SCpnt)
2797 	{
2798 	PADAPTER2220I	padapter = HOSTDATA(SCpnt->host);			// Pointer to adapter control structure
2799 	POUR_DEVICE		pdev	 = &padapter->device[SCpnt->target];// Pointer to device information
2800 
2801 	if ( !padapter->SCpnt )
2802 		return SCSI_ABORT_NOT_RUNNING;
2803 
2804 	if ( padapter->atapi )
2805 		{
2806 		if ( AtapiReset (padapter, pdev) )
2807 			return SCSI_ABORT_ERROR;
2808 		OpDone (padapter, DID_ABORT << 16);
2809 		return SCSI_ABORT_SUCCESS;
2810 		}
2811 	return SCSI_ABORT_SNOOZE;
2812 	}
2813 /****************************************************************
2814  *	Name:	Pci2220i_Reset
2815  *
2816  *	Description:	Process the Reset command from the SCSI manager.
2817  *
2818  *	Parameters:		SCpnt - Pointer to SCSI command structure.
2819  *					flags - Flags about the reset command
2820  *
2821  *	Returns:		No active command at this time, so this means
2822  *					that each time we got some kind of response the
2823  *					last time through.  Tell the mid-level code to
2824  *					request sense information in order to decide what
2825  *					to do next.
2826  *
2827  ****************************************************************/
Pci2220i_Reset(Scsi_Cmnd * SCpnt,unsigned int reset_flags)2828 int Pci2220i_Reset (Scsi_Cmnd *SCpnt, unsigned int reset_flags)
2829 	{
2830 	PADAPTER2220I	padapter = HOSTDATA(SCpnt->host);			// Pointer to adapter control structure
2831 	POUR_DEVICE		pdev	 = &padapter->device[SCpnt->target];// Pointer to device information
2832 
2833 	if ( padapter->atapi )
2834 		{
2835 		if ( AtapiReset (padapter, pdev) )
2836 			return SCSI_RESET_ERROR;
2837 		return SCSI_RESET_SUCCESS;
2838 		}
2839 	return SCSI_RESET_PUNT;
2840 	}
2841 /****************************************************************
2842  *	Name:	Pci2220i_Release
2843  *
2844  *	Description:	Release resources allocated for a single each adapter.
2845  *
2846  *	Parameters:		pshost - Pointer to SCSI command structure.
2847  *
2848  *	Returns:		zero.
2849  *
2850  ****************************************************************/
Pci2220i_Release(struct Scsi_Host * pshost)2851 int Pci2220i_Release (struct Scsi_Host *pshost)
2852 	{
2853     PADAPTER2220I	padapter = HOSTDATA (pshost);
2854 	USHORT			z;
2855 
2856 	if ( padapter->reconOn )
2857 		{
2858 		padapter->reconOn = FALSE;						// shut down the hot reconstruct
2859 		if ( padapter->reconPhase )
2860 			mdelay (300);
2861 		if ( padapter->reconTimer.data )				// is the timer running?
2862 			{
2863 			del_timer (&padapter->reconTimer);
2864 			padapter->reconTimer.data = 0;
2865 			}
2866 		}
2867 
2868 	// save RAID status on the board
2869 	if ( padapter->bigD )
2870 		{
2871 		outb_p (padapter->failRegister, padapter->regScratchPad + BIGD_ALARM_IMAGE);
2872 		for ( z = 0;  z < BIGD_MAXDRIVES;  z++ )
2873 			{
2874 			if ( padapter->raidData )
2875 				outb_p (padapter->raidData[z]->status, padapter->regScratchPad + BIGD_RAID_0_STATUS + z);
2876 			else
2877 				outb_p (0, padapter->regScratchPad + BIGD_RAID_0_STATUS);
2878 			}
2879 		}
2880 	else
2881 		{
2882 		outb_p (padapter->device[0].DiskMirror[0].status, padapter->regScratchPad + DALE_RAID_0_STATUS);
2883 		outb_p (padapter->device[0].DiskMirror[1].status, padapter->regScratchPad + DALE_RAID_1_STATUS);
2884 		}
2885 
2886 	if ( padapter->irqOwned )
2887 		free_irq (pshost->irq, padapter);
2888     release_region (pshost->io_port, pshost->n_io_port);
2889 	if ( padapter->numberOfDrives )
2890 		pci_free_consistent (padapter->pcidev, SECTORSXFER * BYTES_PER_SECTOR, padapter->kBuffer, padapter->kBufferDma);
2891 	else
2892 		pci_free_consistent (padapter->pcidev, ATAPI_TRANSFER, padapter->kBuffer, padapter->kBufferDma);
2893     scsi_unregister(pshost);
2894     return 0;
2895 	}
2896 
2897 #include "sd.h"
2898 
2899 /****************************************************************
2900  *	Name:	Pci2220i_BiosParam
2901  *
2902  *	Description:	Process the biosparam request from the SCSI manager to
2903  *					return C/H/S data.
2904  *
2905  *	Parameters:		disk - Pointer to SCSI disk structure.
2906  *					dev	 - Major/minor number from kernel.
2907  *					geom - Pointer to integer array to place geometry data.
2908  *
2909  *	Returns:		zero.
2910  *
2911  ****************************************************************/
Pci2220i_BiosParam(Scsi_Disk * disk,kdev_t dev,int geom[])2912 int Pci2220i_BiosParam (Scsi_Disk *disk, kdev_t dev, int geom[])
2913 	{
2914 	POUR_DEVICE	pdev;
2915 
2916 	if ( !(HOSTDATA(disk->device->host))->atapi )
2917 		{
2918 		pdev = &(HOSTDATA(disk->device->host)->device[disk->device->id]);
2919 
2920 		geom[0] = pdev->heads;
2921 		geom[1] = pdev->sectors;
2922 		geom[2] = pdev->cylinders;
2923 		}
2924 	return 0;
2925 	}
2926 
2927 MODULE_LICENSE("Dual BSD/GPL");
2928 
2929 /* Eventually this will go into an include file, but this will be later */
2930 static Scsi_Host_Template driver_template = PCI2220I;
2931 
2932 #include "scsi_module.c"
2933