1 /**************************************************************************** 2 * Perceptive Solutions, Inc. PCI-2220I device driver for Linux. 4 * pci2220i.c - Linux Host Driver for PCI-2220I EIDE RAID Adapters 6 * Copyright (c) 1997-1999 Perceptive Solutions, Inc. 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that redistributions of source 11 * code retain the above copyright notice and this comment without 14 * Technical updates and product information at: 15 * http://www.psidisk.com 17 * Please send questions, comments, bug reports to: 18 * tech@psidisk.com Technical Support 21 * Revisions 1.10 Mar-26-1999 22 * - Updated driver for RAID and hot reconstruct support. 24 * Revisions 1.11 Mar-26-1999 25 * - Fixed spinlock and PCI configuration. 27 ****************************************************************************/ 29 #include <linux/module.h> 30 #include <linux/kernel.h> 31 #include <linux/types.h> 32 #include <linux/string.h> 33 #include <linux/malloc.h> 34 #include <linux/pci.h> 35 #include <linux/ioport.h> 36 #include <linux/delay.h> 37 #include <linux/sched.h> 38 #include <linux/proc_fs.h> 39 #include <linux/stat.h> 40 #include <linux/kdev_t.h> 41 #include <linux/blk.h> 42 #include <linux/timer.h> 44 #include <asm/system.h> 50 #if LINUX_VERSION_CODE >= LINUXVERSION(2,1,95) 51 #include <linux/spinlock.h> 53 #if LINUX_VERSION_CODE < LINUXVERSION(2,1,93) 54 #include <linux/bios32.h> 57 #define PCI2220I_VERSION"1.11" 58 //#define READ_CMD IDE_COMMAND_READ 59 //#define WRITE_CMD IDE_COMMAND_WRITE 60 //#define MAX_BUS_MASTER_BLOCKS 1 // This is the maximum we can bus master 61 #define READ_CMD IDE_CMD_READ_MULTIPLE 62 #define WRITE_CMD IDE_CMD_WRITE_MULTIPLE 63 #define MAX_BUS_MASTER_BLOCKS SECTORSXFER// This is the maximum we can bus master 66 struct proc_dir_entry Proc_Scsi_Pci2220i
= 67 { PROC_SCSI_PCI2220I
,8,"pci2220i", S_IFDIR
| S_IRUGO
| S_IXUGO
,2}; 73 #define STOP_HERE() {int st;for(st=0;st<100;st++){st=1;}} 79 #define MAXADAPTER 4// Increase this and the sizes of the arrays below, if you need more. 84 UCHAR device
;// device code 85 UCHAR byte6
;// device select register image 86 UCHAR spigot
;// spigot number 87 UCHAR sparebyte
;// placeholder 88 USHORT sectors
;// number of sectors per track 89 USHORT heads
;// number of heads 90 USHORT cylinders
;// number of cylinders for this device 91 USHORT spareword
;// placeholder 92 ULONG blocks
;// number of blocks on device 93 DISK_MIRROR DiskMirror
[2];// RAID status and control 94 ULONG lastsectorlba
[2];// last addressable sector on the drive 95 USHORT raid
;// RAID active flag 99 } OUR_DEVICE
, *POUR_DEVICE
; 103 USHORT regDmaDesc
;// address of the DMA discriptor register for direction of transfer 104 USHORT regDmaCmdStat
;// Byte #1 of DMA command status register 105 USHORT regDmaAddrPci
;// 32 bit register for PCI address of DMA 106 USHORT regDmaAddrLoc
;// 32 bit register for local bus address of DMA 107 USHORT regDmaCount
;// 32 bit register for DMA transfer count 108 USHORT regDmaMode
;// 32 bit register for DMA mode control 109 USHORT regRemap
;// 32 bit local space remap 110 USHORT regDesc
;// 32 bit local region descriptor 111 USHORT regRange
;// 32 bit local range 112 USHORT regIrqControl
;// 16 bit Interrupt enable/disable and status 113 USHORT regScratchPad
;// scratch pad I/O base address 114 USHORT regBase
;// Base I/O register for data space 115 USHORT regData
;// data register I/O address 116 USHORT regError
;// error register I/O address 117 USHORT regSectCount
;// sector count register I/O address 118 USHORT regLba0
;// least significant byte of LBA 119 USHORT regLba8
;// next least significant byte of LBA 120 USHORT regLba16
;// next most significan byte of LBA 121 USHORT regLba24
;// head and most 4 significant bits of LBA 122 USHORT regStatCmd
;// status on read and command on write register 123 USHORT regStatSel
;// board status on read and spigot select on write register 124 USHORT regFail
;// fail bits control register 125 USHORT regAltStat
;// alternate status and drive control register 126 USHORT basePort
;// PLX base I/O port 127 USHORT timingMode
;// timing mode currently set for adapter 128 USHORT timingPIO
;// TRUE if PIO timing is active 129 ULONG timingAddress
;// address to use on adapter for current timing mode 130 ULONG irqOwned
;// owned IRQ or zero if shared 131 OUR_DEVICE device
[DALE_MAXDRIVES
]; 132 DISK_MIRROR
*raidData
[8]; 138 POUR_DEVICE pdev
;// current device opearating on 140 USHORT reconIsStarting
;// indicate hot reconstruct is starting 141 USHORT reconOn
;// Hot reconstruct is to be done. 142 USHORT reconPhase
;// Hot reconstruct operation is in progress. 144 USHORT demoFail
;// flag for RAID failure demonstration 147 struct timer_list reconTimer
; 148 struct timer_list timer
; 150 } ADAPTER2220I
, *PADAPTER2220I
; 152 #define HOSTDATA(host) ((PADAPTER2220I)&host->hostdata) 154 #define RECON_PHASE_READY 0x01 155 #define RECON_PHASE_COPY 0x02 156 #define RECON_PHASE_UPDATE 0x03 157 #define RECON_PHASE_LAST 0x04 158 #define RECON_PHASE_END 0x07 159 #define RECON_PHASE_MARKING 0x80 160 #define RECON_PHASE_FAILOVER 0xFF 162 static struct Scsi_Host
*PsiHost
[MAXADAPTER
] = {NULL
,};// One for each adapter 163 static int NumAdapters
=0; 164 static SETUP DaleSetup
; 165 static DISK_MIRROR DiskMirror
[2]; 166 static ULONG ModeArray
[] = {DALE_DATA_MODE2
, DALE_DATA_MODE3
, DALE_DATA_MODE4
, DALE_DATA_MODE4P
}; 168 static voidReconTimerExpiry(unsigned long data
); 170 /**************************************************************** 171 * Name: MuteAlarm :LOCAL 173 * Description: Mute the audible alarm. 175 * Parameters: padapter - Pointer adapter data structure. 177 * Returns: TRUE if drive does not assert DRQ in time. 179 ****************************************************************/ 180 static voidMuteAlarm(PADAPTER2220I padapter
) 184 old
= (inb_p(padapter
->regStatSel
) >>3) | (inb_p(padapter
->regStatSel
) &0x83); 185 outb_p(old
|0x40, padapter
->regFail
); 187 /**************************************************************** 188 * Name: WaitReady :LOCAL 190 * Description: Wait for device ready. 192 * Parameters: padapter - Pointer adapter data structure. 194 * Returns: TRUE if drive does not assert DRQ in time. 196 ****************************************************************/ 197 static intWaitReady(PADAPTER2220I padapter
) 202 for( z
=0; z
< (TIMEOUT_READY
*4); z
++ ) 204 status
=inb_p(padapter
->regStatCmd
); 205 if( (status
& (IDE_STATUS_DRDY
| IDE_STATUS_BUSY
)) == IDE_STATUS_DRDY
) 211 /**************************************************************** 212 * Name: WaitReadyReset :LOCAL 214 * Description: Wait for device ready. 216 * Parameters: padapter - Pointer adapter data structure. 218 * Returns: TRUE if drive does not assert DRQ in time. 220 ****************************************************************/ 221 static intWaitReadyReset(PADAPTER2220I padapter
) 226 for( z
=0; z
< (250*4); z
++ )// wait up to 1/4 second 228 status
=inb_p(padapter
->regStatCmd
); 229 if( (status
& (IDE_STATUS_DRDY
| IDE_STATUS_BUSY
)) == IDE_STATUS_DRDY
) 231 DEB(printk("\nPCI2220I: Reset took %ld mSec to be ready", z
/4)); 236 DEB(printk("\nPCI2220I: Reset took more than 1 Second to come ready, Disk Failure")); 239 /**************************************************************** 240 * Name: WaitDrq :LOCAL 242 * Description: Wait for device ready for data transfer. 244 * Parameters: padapter - Pointer adapter data structure. 246 * Returns: TRUE if drive does not assert DRQ in time. 248 ****************************************************************/ 249 static intWaitDrq(PADAPTER2220I padapter
) 254 for( z
=0; z
< (TIMEOUT_DRQ
*4); z
++ ) 256 status
=inb_p(padapter
->regStatCmd
); 257 if( status
& IDE_STATUS_DRQ
) 263 /**************************************************************** 264 * Name: HardReset :LOCAL 266 * Description: Wait for device ready for data transfer. 268 * Parameters: padapter - Pointer adapter data structure. 269 * pdev - Pointer to device. 270 * spigot - Spigot number. 272 * Returns: TRUE if drive does not assert DRQ in time. 274 ****************************************************************/ 275 static intHardReset(PADAPTER2220I padapter
, POUR_DEVICE pdev
, UCHAR spigot
) 277 SelectSpigot(padapter
, spigot
|0x80); 279 outb_p(0x0E, padapter
->regAltStat
);// reset the suvivor 280 udelay(100);// wait a little 281 outb_p(0x08, padapter
->regAltStat
);// clear the reset 283 outb_p(0xA0, padapter
->regLba24
);//Specify drive 285 outb_p(pdev
->byte6
, padapter
->regLba24
);// select the drive 286 if(WaitReadyReset(padapter
) ) 288 outb_p(SECTORSXFER
, padapter
->regSectCount
); 289 WriteCommand(padapter
, IDE_CMD_SET_MULTIPLE
); 290 if(WaitReady(padapter
) ) 294 /**************************************************************** 295 * Name: BusMaster :LOCAL 297 * Description: Do a bus master I/O. 299 * Parameters: padapter - Pointer adapter data structure. 300 * datain - TRUE if data read. 301 * irq - TRUE if bus master interrupt expected. 303 * Returns: TRUE if drive does not assert DRQ in time. 305 ****************************************************************/ 306 static voidBusMaster(PADAPTER2220I padapter
, UCHAR datain
, UCHAR irq
) 310 outl(padapter
->timingAddress
, padapter
->regDmaAddrLoc
); 311 outl(virt_to_bus(padapter
->buffer
), padapter
->regDmaAddrPci
); 312 zl
= (padapter
->sectorCount
> MAX_BUS_MASTER_BLOCKS
) ? MAX_BUS_MASTER_BLOCKS
: padapter
->sectorCount
; 313 padapter
->sectorCount
-= zl
; 314 zl
*= (ULONG
)BYTES_PER_SECTOR
; 315 padapter
->buffer
+= zl
; 316 outl(zl
, padapter
->regDmaCount
); 319 outb_p(8, padapter
->regDmaDesc
);// read operation 320 if( irq
&& !padapter
->sectorCount
) 321 outb_p(5, padapter
->regDmaMode
);// interrupt on 323 outb_p(1, padapter
->regDmaMode
);// no interrupt 327 outb_p(0, padapter
->regDmaDesc
);// write operation 328 outb_p(1, padapter
->regDmaMode
);// no interrupt 330 outb_p(0x03, padapter
->regDmaCmdStat
);// kick the DMA engine in gear 332 /**************************************************************** 333 * Name: WriteData :LOCAL 335 * Description: Write data to device. 337 * Parameters: padapter - Pointer adapter data structure. 339 * Returns: TRUE if drive does not assert DRQ in time. 341 ****************************************************************/ 342 static intWriteData(PADAPTER2220I padapter
) 346 if( !WaitDrq(padapter
) ) 348 if( padapter
->timingPIO
) 350 zl
= (padapter
->sectorCount
> MAX_BUS_MASTER_BLOCKS
) ? MAX_BUS_MASTER_BLOCKS
: padapter
->sectorCount
; 351 outsw(padapter
->regData
, padapter
->buffer
, zl
* (BYTES_PER_SECTOR
/2)); 352 padapter
->sectorCount
-= zl
; 353 padapter
->buffer
+= zl
* BYTES_PER_SECTOR
; 356 BusMaster(padapter
,0,0); 359 padapter
->cmd
=0;// null out the command byte 362 /**************************************************************** 363 * Name: WriteDataBoth :LOCAL 365 * Description: Write data to device. 367 * Parameters: padapter - Pointer adapter data structure. 369 * Returns: TRUE if drive does not assert DRQ in time. 371 ****************************************************************/ 372 static intWriteDataBoth(PADAPTER2220I padapter
) 375 UCHAR status0
, status1
; 377 SelectSpigot(padapter
,1); 378 status0
=WaitDrq(padapter
); 381 SelectSpigot(padapter
,2); 382 status1
=WaitDrq(padapter
); 385 SelectSpigot(padapter
,3); 386 if( padapter
->timingPIO
) 388 zl
= (padapter
->sectorCount
> MAX_BUS_MASTER_BLOCKS
) ? MAX_BUS_MASTER_BLOCKS
: padapter
->sectorCount
; 389 outsw(padapter
->regData
, padapter
->buffer
, zl
* (BYTES_PER_SECTOR
/2)); 390 padapter
->sectorCount
-= zl
; 391 padapter
->buffer
+= zl
* BYTES_PER_SECTOR
; 394 BusMaster(padapter
,0,0); 398 padapter
->cmd
=0;// null out the command byte 403 /**************************************************************** 404 * Name: IdeCmd :LOCAL 406 * Description: Process an IDE command. 408 * Parameters: padapter - Pointer adapter data structure. 409 * pdev - Pointer to device. 411 * Returns: Zero if no error or status register contents on error. 413 ****************************************************************/ 414 static UCHAR
IdeCmd(PADAPTER2220I padapter
, POUR_DEVICE pdev
) 418 SelectSpigot(padapter
, pdev
->spigot
);// select the spigot 419 outb_p(pdev
->byte6
| ((UCHAR
*)(&padapter
->startSector
))[3], padapter
->regLba24
);// select the drive 420 status
=WaitReady(padapter
); 423 outb_p(padapter
->sectorCount
, padapter
->regSectCount
); 424 outb_p(((UCHAR
*)(&padapter
->startSector
))[0], padapter
->regLba0
); 425 outb_p(((UCHAR
*)(&padapter
->startSector
))[1], padapter
->regLba8
); 426 outb_p(((UCHAR
*)(&padapter
->startSector
))[2], padapter
->regLba16
); 427 padapter
->expectingIRQ
= TRUE
; 428 WriteCommand(padapter
, padapter
->cmd
); 432 padapter
->cmd
=0;// null out the command byte 435 /**************************************************************** 436 * Name: IdeCmdBoth :LOCAL 438 * Description: Process an IDE command to both drivers. 440 * Parameters: padapter - Pointer adapter data structure. 442 * Returns: Zero if no error or spigot of error. 444 ****************************************************************/ 445 static UCHAR
IdeCmdBoth(PADAPTER2220I padapter
) 450 SelectSpigot(padapter
,3);// select the spigots 451 outb_p(padapter
->pdev
->byte6
| ((UCHAR
*)(&padapter
->startSector
))[3], padapter
->regLba24
);// select the drive 452 SelectSpigot(padapter
,1); 453 status0
=WaitReady(padapter
); 456 SelectSpigot(padapter
,2); 457 status1
=WaitReady(padapter
); 460 SelectSpigot(padapter
,3); 461 outb_p(padapter
->sectorCount
, padapter
->regSectCount
); 462 outb_p(((UCHAR
*)(&padapter
->startSector
))[0], padapter
->regLba0
); 463 outb_p(((UCHAR
*)(&padapter
->startSector
))[1], padapter
->regLba8
); 464 outb_p(((UCHAR
*)(&padapter
->startSector
))[2], padapter
->regLba16
); 465 padapter
->expectingIRQ
= TRUE
; 466 WriteCommand(padapter
, padapter
->cmd
); 470 padapter
->cmd
=0;// null out the command byte 475 /**************************************************************** 476 * Name: OpDone :LOCAL 478 * Description: Complete an operatoin done sequence. 480 * Parameters: padapter - Pointer to host data block. 481 * spigot - Spigot select code. 482 * device - Device byte code. 486 ****************************************************************/ 487 static voidOpDone(PADAPTER2220I padapter
, ULONG result
) 489 Scsi_Cmnd
*SCpnt
= padapter
->SCpnt
; 491 if( padapter
->reconPhase
) 493 padapter
->reconPhase
=0; 494 if( padapter
->SCpnt
) 496 Pci2220i_QueueCommand(SCpnt
, SCpnt
->scsi_done
); 500 if( padapter
->reconOn
) 502 ReconTimerExpiry((unsigned long)padapter
); 509 padapter
->SCpnt
= NULL
; 510 SCpnt
->result
= result
; 511 SCpnt
->scsi_done(SCpnt
); 512 if( padapter
->reconOn
&& !padapter
->reconTimer
.data
) 514 padapter
->reconTimer
.expires
= jiffies
+ (HZ
/4);// start in 1/4 second 515 padapter
->reconTimer
.data
= (unsigned long)padapter
; 516 add_timer(&padapter
->reconTimer
); 520 /**************************************************************** 521 * Name: InlineIdentify :LOCAL 523 * Description: Do an intline inquiry on a drive. 525 * Parameters: padapter - Pointer to host data block. 526 * spigot - Spigot select code. 527 * device - Device byte code. 529 * Returns: Last addressable sector or zero if none. 531 ****************************************************************/ 532 static ULONG
InlineIdentify(PADAPTER2220I padapter
, UCHAR spigot
, UCHAR device
) 534 PIDENTIFY_DATA pid
= (PIDENTIFY_DATA
)padapter
->kBuffer
; 536 SelectSpigot(padapter
, spigot
|0x80);// select the spigot 537 outb_p(device
<<4, padapter
->regLba24
);// select the drive 538 if(WaitReady(padapter
) ) 540 WriteCommand(padapter
, IDE_COMMAND_IDENTIFY
); 541 if(WaitDrq(padapter
) ) 543 insw(padapter
->regData
, padapter
->kBuffer
,sizeof(IDENTIFY_DATA
) >>1); 544 return(pid
->LBATotalSectors
-1); 546 /**************************************************************** 547 * Name: InlineReadSignature :LOCAL 549 * Description: Do an inline read RAID sigature. 551 * Parameters: padapter - Pointer adapter data structure. 552 * pdev - Pointer to device. 553 * index - index of data to read. 555 * Returns: Zero if no error or status register contents on error. 557 ****************************************************************/ 558 static UCHAR
InlineReadSignature(PADAPTER2220I padapter
, POUR_DEVICE pdev
,int index
) 561 UCHAR spigot
=1<< index
; 562 ULONG zl
= pdev
->lastsectorlba
[index
]; 564 SelectSpigot(padapter
, spigot
|0x80);// select the spigot without interrupts 565 outb_p(pdev
->byte6
| ((UCHAR
*)&zl
)[3], padapter
->regLba24
); 566 status
=WaitReady(padapter
); 569 outb_p(((UCHAR
*)&zl
)[2], padapter
->regLba16
); 570 outb_p(((UCHAR
*)&zl
)[1], padapter
->regLba8
); 571 outb_p(((UCHAR
*)&zl
)[0], padapter
->regLba0
); 572 outb_p(1, padapter
->regSectCount
); 573 WriteCommand(padapter
, IDE_COMMAND_READ
); 574 status
=WaitDrq(padapter
); 577 insw(padapter
->regData
, padapter
->kBuffer
, BYTES_PER_SECTOR
/2); 578 ((ULONG
*)(&pdev
->DiskMirror
[index
]))[0] = ((ULONG
*)(&padapter
->kBuffer
[DISK_MIRROR_POSITION
]))[0]; 579 ((ULONG
*)(&pdev
->DiskMirror
[index
]))[1] = ((ULONG
*)(&padapter
->kBuffer
[DISK_MIRROR_POSITION
]))[1]; 580 // some drives assert DRQ before IRQ so let's make sure we clear the IRQ 587 /**************************************************************** 588 * Name: DecodeError :LOCAL 590 * Description: Decode and process device errors. 592 * Parameters: padapter - Pointer to adapter data. 593 * status - Status register code. 595 * Returns: The driver status code. 597 ****************************************************************/ 598 static ULONG
DecodeError(PADAPTER2220I padapter
, UCHAR status
) 602 padapter
->expectingIRQ
=0; 603 if( status
& IDE_STATUS_WRITE_FAULT
) 605 return DID_PARITY
<<16; 607 if( status
& IDE_STATUS_BUSY
) 608 return DID_BUS_BUSY
<<16; 610 error
=inb_p(padapter
->regError
); 611 DEB(printk("\npci2220i error register: %x", error
)); 615 case IDE_ERROR_TKONF
: 621 return DID_ERROR
<<16; 623 return DID_ERROR
<<16; 625 /**************************************************************** 626 * Name: StartTimer :LOCAL 628 * Description: Start the timer. 630 * Parameters: ipadapter - Pointer adapter data structure. 634 ****************************************************************/ 635 static voidStartTimer(PADAPTER2220I padapter
) 637 padapter
->timer
.expires
= jiffies
+ TIMEOUT_DATA
; 638 add_timer(&padapter
->timer
); 640 /**************************************************************** 641 * Name: WriteSignature :LOCAL 643 * Description: Start the timer. 645 * Parameters: padapter - Pointer adapter data structure. 646 * pdev - Pointer to our device. 647 * spigot - Selected spigot. 648 * index - index of mirror signature on device. 650 * Returns: TRUE on any error. 652 ****************************************************************/ 653 static intWriteSignature(PADAPTER2220I padapter
, POUR_DEVICE pdev
, UCHAR spigot
,int index
) 657 SelectSpigot(padapter
, spigot
); 658 zl
= pdev
->lastsectorlba
[index
]; 659 outb_p(pdev
->byte6
| ((UCHAR
*)&zl
)[3], padapter
->regLba24
); 660 outb_p(((UCHAR
*)&zl
)[2], padapter
->regLba16
); 661 outb_p(((UCHAR
*)&zl
)[1], padapter
->regLba8
); 662 outb_p(((UCHAR
*)&zl
)[0], padapter
->regLba0
); 663 outb_p(1, padapter
->regSectCount
); 665 WriteCommand(padapter
, IDE_COMMAND_WRITE
); 666 if(WaitDrq(padapter
) ) 668 StartTimer(padapter
); 669 padapter
->expectingIRQ
= TRUE
; 671 ((ULONG
*)(&padapter
->kBuffer
[DISK_MIRROR_POSITION
]))[0] = ((ULONG
*)(&pdev
->DiskMirror
[index
]))[0]; 672 ((ULONG
*)(&padapter
->kBuffer
[DISK_MIRROR_POSITION
]))[1] = ((ULONG
*)(&pdev
->DiskMirror
[index
]))[1]; 673 outsw(padapter
->regData
, padapter
->kBuffer
, BYTES_PER_SECTOR
/2); 676 /******************************************************************************************************* 679 * Description: This is the beginning of the failover routine 681 * Parameters: SCpnt - Pointer to SCSI command structure. 682 * padapter - Pointer adapter data structure. 683 * pdev - Pointer to our device. 685 * Returns: TRUE on error. 687 ******************************************************************************************************/ 688 static intInitFailover(PADAPTER2220I padapter
, POUR_DEVICE pdev
) 692 DEB(printk("\npci2220i: Initialize failover process - survivor = %d", padapter
->survivor
)); 693 pdev
->raid
= FALSE
;//initializes system for non raid mode 695 padapter
->reconOn
= FALSE
; 696 spigot
= (padapter
->survivor
) ?2:1; 698 if( pdev
->DiskMirror
[padapter
->survivor
].status
& UCBF_REBUILD
) 701 if(HardReset(padapter
, pdev
, spigot
) ) 704 outb_p(0x3C| spigot
, padapter
->regFail
);// sound alarm and set fail light 705 pdev
->DiskMirror
[padapter
->survivor
].status
= UCBF_MIRRORED
| UCBF_SURVIVOR
;//clear present status 707 if(WriteSignature(padapter
, pdev
, spigot
, padapter
->survivor
) ) 709 padapter
->failinprog
= TRUE
; 712 /**************************************************************** 713 * Name: TimerExpiry :LOCAL 715 * Description: Timer expiry routine. 717 * Parameters: data - Pointer adapter data structure. 721 ****************************************************************/ 722 static voidTimerExpiry(unsigned long data
) 724 PADAPTER2220I padapter
= (PADAPTER2220I
)data
; 725 POUR_DEVICE pdev
= padapter
->pdev
; 726 UCHAR status
= IDE_STATUS_BUSY
; 728 #if LINUX_VERSION_CODE < LINUXVERSION(2,1,95) 730 #else/* version >= v2.1.95 */ 732 #endif/* version >= v2.1.95 */ 734 #if LINUX_VERSION_CODE < LINUXVERSION(2,1,95) 735 /* Disable interrupts, if they aren't already disabled. */ 738 #else/* version >= v2.1.95 */ 740 * Disable interrupts, if they aren't already disabled and acquire 743 spin_lock_irqsave(&io_request_lock
, flags
); 744 #endif/* version >= v2.1.95 */ 745 DEB(printk("\nPCI2220I: Timeout expired ")); 747 if( padapter
->failinprog
) 749 DEB(printk("in failover process")); 750 OpDone(padapter
,DecodeError(padapter
,inb_p(padapter
->regStatCmd
))); 751 goto timerExpiryDone
; 754 while( padapter
->reconPhase
) 756 DEB(printk("in recon phase %X", padapter
->reconPhase
)); 757 switch( padapter
->reconPhase
) 759 case RECON_PHASE_MARKING
: 760 case RECON_PHASE_LAST
: 761 padapter
->survivor
= (pdev
->spigot
^3) >>1; 762 DEB(printk("\npci2220i: FAILURE 1")); 763 if(InitFailover(padapter
, pdev
) ) 764 OpDone(padapter
, DID_ERROR
<<16); 765 goto timerExpiryDone
; 767 case RECON_PHASE_READY
: 768 OpDone(padapter
, DID_ERROR
<<16); 769 goto timerExpiryDone
; 771 case RECON_PHASE_COPY
: 772 padapter
->survivor
= (pdev
->spigot
) >>1; 773 DEB(printk("\npci2220i: FAILURE 2")); 774 DEB(printk("\nspig/stat = %X",inb_p(padapter
->regStatSel
)); 775 if(InitFailover(padapter
, pdev
) ) 776 OpDone(padapter
, DID_ERROR
<<16); 777 goto timerExpiryDone
; 779 case RECON_PHASE_UPDATE
: 780 padapter
->survivor
= (pdev
->spigot
) >>1; 781 DEB(printk("\npci2220i: FAILURE 3"))); 782 if(InitFailover(padapter
, pdev
) ) 783 OpDone(padapter
, DID_ERROR
<<16); 784 goto timerExpiryDone
; 786 case RECON_PHASE_END
: 787 padapter
->survivor
= (pdev
->spigot
) >>1; 788 DEB(printk("\npci2220i: FAILURE 4")); 789 if(InitFailover(padapter
, pdev
) ) 790 OpDone(padapter
, DID_ERROR
<<16); 791 goto timerExpiryDone
; 794 goto timerExpiryDone
; 798 while( padapter
->cmd
) 800 outb_p(0x08, padapter
->regDmaCmdStat
);// cancel interrupt from DMA engine 803 if( padapter
->cmd
== WRITE_CMD
) 805 DEB(printk("in RAID write operation")); 806 if(inb_p(padapter
->regStatSel
) &1) 808 SelectSpigot(padapter
,0x81);// Masking the interrupt during spigot select 809 temp
=inb_p(padapter
->regStatCmd
); 812 temp
= IDE_STATUS_BUSY
; 814 if(inb(padapter
->regStatSel
) &2) 816 SelectSpigot(padapter
,0x82);// Masking the interrupt during spigot select 817 temp1
=inb_p(padapter
->regStatCmd
); 820 temp1
= IDE_STATUS_BUSY
; 822 if( (temp
& IDE_STATUS_BUSY
) || (temp1
& IDE_STATUS_BUSY
) ) 824 if( (temp
& IDE_STATUS_BUSY
) && (temp1
& IDE_STATUS_BUSY
) ) 831 if(temp
& IDE_STATUS_BUSY
) 832 padapter
->survivor
=1; 834 padapter
->survivor
=0; 835 DEB(printk("\npci2220i: FAILURE 5")); 836 if(InitFailover(padapter
, pdev
) ) 838 status
=inb_p(padapter
->regStatCmd
); 841 goto timerExpiryDone
; 847 DEB(printk("in RAID read operation")); 848 padapter
->survivor
= (pdev
->spigot
^3) >>1; 849 DEB(printk("\npci2220i: FAILURE 6")); 850 if(InitFailover(padapter
, pdev
) ) 852 status
=inb_p(padapter
->regStatCmd
); 855 goto timerExpiryDone
; 860 DEB(printk("in I/O operation")); 861 status
=inb_p(padapter
->regStatCmd
); 866 OpDone(padapter
,DecodeError(padapter
, status
)); 869 #if LINUX_VERSION_CODE < LINUXVERSION(2,1,95) 871 * Restore the original flags which will enable interrupts 872 * if and only if they were enabled on entry. 874 restore_flags(flags
); 875 #else/* version >= v2.1.95 */ 877 * Release the I/O spinlock and restore the original flags 878 * which will enable interrupts if and only if they were 881 spin_unlock_irqrestore(&io_request_lock
, flags
); 882 #endif/* version >= v2.1.95 */ 884 /**************************************************************** 885 * Name: SetReconstruct :LOCAL 887 * Description: Set the reconstruct up. 889 * Parameters: pdev - Pointer to device structure. 890 * index - Mirror index number. 892 * Returns: Number of sectors on new disk required. 894 ****************************************************************/ 895 static LONG
SetReconstruct(POUR_DEVICE pdev
,int index
) 897 pdev
->DiskMirror
[index
].status
= UCBF_MIRRORED
;// setup the flags 898 pdev
->DiskMirror
[index
^1].status
= UCBF_MIRRORED
| UCBF_REBUILD
; 899 pdev
->DiskMirror
[index
^1].reconstructPoint
=0;// start the reconstruct 900 pdev
->reconCount
=1990;// mark target drive early 901 pdev
->hotRecon
=1>> index
; 902 return pdev
->DiskMirror
[index
].reconstructPoint
; 904 /**************************************************************** 905 * Name: ReconTimerExpiry :LOCAL 907 * Description: Reconstruct timer expiry routine. 909 * Parameters: data - Pointer adapter data structure. 913 ****************************************************************/ 914 static voidReconTimerExpiry(unsigned long data
) 916 PADAPTER2220I padapter
; 923 #if LINUX_VERSION_CODE < LINUXVERSION(2,1,95) 925 #else/* version >= v2.1.95 */ 927 #endif/* version >= v2.1.95 */ 929 #if LINUX_VERSION_CODE < LINUXVERSION(2,1,95) 930 /* Disable interrupts, if they aren't already disabled. */ 933 #else/* version >= v2.1.95 */ 935 * Disable interrupts, if they aren't already disabled and acquire 938 spin_lock_irqsave(&io_request_lock
, flags
); 939 #endif/* version >= v2.1.95 */ 941 padapter
= (PADAPTER2220I
)data
; 942 if( padapter
->SCpnt
) 943 goto reconTimerExpiry
; 945 pdev
= padapter
->device
; 946 pid
= (PIDENTIFY_DATA
)padapter
->kBuffer
; 947 padapter
->reconTimer
.data
=0; 948 padapter
->pdev
= pdev
; 949 if( padapter
->reconIsStarting
) 951 padapter
->reconIsStarting
= FALSE
; 952 padapter
->reconOn
= FALSE
; 953 pdev
->hotRecon
= FALSE
; 955 if( (pdev
->DiskMirror
[0].signature
== SIGNATURE
) && (pdev
->DiskMirror
[1].signature
== SIGNATURE
) && 956 (pdev
->DiskMirror
[0].pairIdentifier
== (pdev
->DiskMirror
[1].pairIdentifier
^1)) ) 958 if( (pdev
->DiskMirror
[0].status
& UCBF_MATCHED
) && (pdev
->DiskMirror
[1].status
& UCBF_MATCHED
) ) 960 goto reconTimerExpiry
; 963 if( pdev
->DiskMirror
[0].status
& UCBF_SURVIVOR
)// is first drive survivor? 964 testsize
=SetReconstruct(pdev
,0); 966 if( pdev
->DiskMirror
[1].status
& UCBF_SURVIVOR
)// is second drive survivor? 967 testsize
=SetReconstruct(pdev
,1); 969 if( (pdev
->DiskMirror
[0].status
& UCBF_REBUILD
) || (pdev
->DiskMirror
[1].status
& UCBF_REBUILD
) ) 971 if( pdev
->DiskMirror
[0].status
& UCBF_REBUILD
) 974 pdev
->mirrorRecon
=0; 979 pdev
->mirrorRecon
=1; 984 if( !pdev
->hotRecon
) 985 goto reconTimerExpiry
; 987 zc
= ((inb_p(padapter
->regStatSel
) >>3) |inb_p(padapter
->regStatSel
)) &0x83;// mute the alarm 988 outb_p(zc
| pdev
->hotRecon
|0x40, padapter
->regFail
); 992 if(HardReset(padapter
, pdev
, pdev
->hotRecon
) ) 994 DEB(printk("\npci2220i: sub 1")); 998 pdev
->lastsectorlba
[pdev
->mirrorRecon
] =InlineIdentify(padapter
, pdev
->hotRecon
,0); 1000 if( pdev
->lastsectorlba
[pdev
->mirrorRecon
] < testsize
) 1002 DEB(printk("\npci2220i: sub 2 %ld %ld", pdev
->lastsectorlba
[pdev
->mirrorRecon
], testsize
)); 1006 // test LBA and multiper sector transfer compatability 1007 if(!pid
->SupportLBA
|| (pid
->NumSectorsPerInt
< SECTORSXFER
) || !pid
->Valid_64_70
) 1009 DEB(printk("\npci2220i: sub 3")); 1013 // test PIO/bus matering mode compatability 1014 if( (pid
->MinPIOCycleWithoutFlow
>240) && !pid
->SupportIORDYDisable
&& !padapter
->timingPIO
) 1016 DEB(printk("\npci2220i: sub 4")); 1020 if( pid
->MinPIOCycleWithoutFlow
<=120)// setup timing mode of drive 1024 if( pid
->MinPIOCylceWithFlow
<=150) 1028 if( pid
->MinPIOCylceWithFlow
<=180) 1032 if( pid
->MinPIOCylceWithFlow
<=240) 1036 DEB(printk("\npci2220i: sub 5")); 1043 if( padapter
->timingMode
> minmode
)// set minimum timing mode 1044 padapter
->timingMode
= minmode
; 1045 if( padapter
->timingMode
>=2) 1046 padapter
->timingAddress
= ModeArray
[padapter
->timingMode
-2]; 1048 padapter
->timingPIO
= TRUE
; 1050 padapter
->reconOn
= TRUE
; 1054 if( !padapter
->reconOn
) 1056 pdev
->hotRecon
= FALSE
; 1057 padapter
->survivor
= pdev
->mirrorRecon
^1; 1058 padapter
->reconPhase
= RECON_PHASE_FAILOVER
; 1059 DEB(printk("\npci2220i: FAILURE 7")); 1060 InitFailover(padapter
, pdev
); 1061 goto reconTimerExpiry
; 1066 if(WriteSignature(padapter
, pdev
, pdev
->spigot
, pdev
->mirrorRecon
^1) ) 1067 goto reconTimerExpiry
; 1068 padapter
->reconPhase
= RECON_PHASE_MARKING
; 1069 goto reconTimerExpiry
; 1072 //********************************** 1073 // reconstruct copy starts here 1074 //********************************** 1075 if( pdev
->reconCount
++ >2000) 1077 pdev
->reconCount
=0; 1078 if(WriteSignature(padapter
, pdev
, pdev
->hotRecon
, pdev
->mirrorRecon
) ) 1080 padapter
->survivor
= pdev
->mirrorRecon
^1; 1081 padapter
->reconPhase
= RECON_PHASE_FAILOVER
; 1082 DEB(printk("\npci2220i: FAILURE 8")); 1083 InitFailover(padapter
, pdev
); 1084 goto reconTimerExpiry
; 1086 padapter
->reconPhase
= RECON_PHASE_UPDATE
; 1087 goto reconTimerExpiry
; 1090 zl
= pdev
->DiskMirror
[pdev
->mirrorRecon
].reconstructPoint
; 1091 padapter
->reconSize
= pdev
->DiskMirror
[pdev
->mirrorRecon
^1].reconstructPoint
- zl
; 1092 if( padapter
->reconSize
> MAX_BUS_MASTER_BLOCKS
) 1093 padapter
->reconSize
= MAX_BUS_MASTER_BLOCKS
; 1095 if( padapter
->reconSize
) 1097 SelectSpigot(padapter
,3);// select the spigots 1098 outb_p(pdev
->byte6
| ((UCHAR
*)(&zl
))[3], padapter
->regLba24
);// select the drive 1099 SelectSpigot(padapter
, pdev
->spigot
); 1100 if(WaitReady(padapter
) ) 1101 goto reconTimerExpiry
; 1103 SelectSpigot(padapter
, pdev
->hotRecon
); 1104 if(WaitReady(padapter
) ) 1106 padapter
->survivor
= pdev
->mirrorRecon
^1; 1107 padapter
->reconPhase
= RECON_PHASE_FAILOVER
; 1108 DEB(printk("\npci2220i: FAILURE 9")); 1109 InitFailover(padapter
, pdev
); 1110 goto reconTimerExpiry
; 1113 SelectSpigot(padapter
,3); 1114 outb_p(padapter
->reconSize
&0xFF, padapter
->regSectCount
); 1115 outb_p(((UCHAR
*)(&zl
))[0], padapter
->regLba0
); 1116 outb_p(((UCHAR
*)(&zl
))[1], padapter
->regLba8
); 1117 outb_p(((UCHAR
*)(&zl
))[2], padapter
->regLba16
); 1118 padapter
->expectingIRQ
= TRUE
; 1119 padapter
->reconPhase
= RECON_PHASE_READY
; 1120 SelectSpigot(padapter
, pdev
->hotRecon
); 1121 WriteCommand(padapter
, WRITE_CMD
); 1122 StartTimer(padapter
); 1123 SelectSpigot(padapter
, pdev
->spigot
); 1124 WriteCommand(padapter
, READ_CMD
); 1125 goto reconTimerExpiry
; 1128 pdev
->DiskMirror
[pdev
->mirrorRecon
].status
= UCBF_MIRRORED
| UCBF_MATCHED
; 1129 pdev
->DiskMirror
[pdev
->mirrorRecon
^1].status
= UCBF_MIRRORED
| UCBF_MATCHED
; 1130 if(WriteSignature(padapter
, pdev
, pdev
->spigot
, pdev
->mirrorRecon
^1) ) 1131 goto reconTimerExpiry
; 1132 padapter
->reconPhase
= RECON_PHASE_LAST
; 1135 #if LINUX_VERSION_CODE < LINUXVERSION(2,1,95) 1137 * Restore the original flags which will enable interrupts 1138 * if and only if they were enabled on entry. 1140 restore_flags(flags
); 1141 #else/* version >= v2.1.95 */ 1143 * Release the I/O spinlock and restore the original flags 1144 * which will enable interrupts if and only if they were 1147 spin_unlock_irqrestore(&io_request_lock
, flags
); 1148 #endif/* version >= v2.1.95 */ 1150 /**************************************************************** 1151 * Name: Irq_Handler :LOCAL 1153 * Description: Interrupt handler. 1155 * Parameters: irq - Hardware IRQ number. 1159 * Returns: TRUE if drive is not ready in time. 1161 ****************************************************************/ 1162 static voidIrq_Handler(int irq
,void*dev_id
,struct pt_regs
*regs
) 1164 struct Scsi_Host
*shost
= NULL
;// Pointer to host data block 1165 PADAPTER2220I padapter
;// Pointer to adapter control structure 1172 #if LINUX_VERSION_CODE < LINUXVERSION(2,1,95) 1174 #else/* version >= v2.1.95 */ 1175 unsigned long flags
; 1176 #endif/* version >= v2.1.95 */ 1178 #if LINUX_VERSION_CODE < LINUXVERSION(2,1,95) 1179 /* Disable interrupts, if they aren't already disabled. */ 1182 #else/* version >= v2.1.95 */ 1184 * Disable interrupts, if they aren't already disabled and acquire 1187 spin_lock_irqsave(&io_request_lock
, flags
); 1188 #endif/* version >= v2.1.95 */ 1190 // DEB (printk ("\npci2220i recieved interrupt\n")); 1192 for( z
=0; z
< NumAdapters
; z
++ )// scan for interrupt to process 1194 if( PsiHost
[z
]->irq
== (UCHAR
)(irq
&0xFF) ) 1196 if(inw_p(HOSTDATA(PsiHost
[z
])->regIrqControl
) &0x8000) 1206 DEB(printk("\npci2220i: not my interrupt")); 1210 padapter
=HOSTDATA(shost
); 1211 pdev
= padapter
->pdev
; 1212 SCpnt
= padapter
->SCpnt
; 1214 if( !padapter
->expectingIRQ
|| !(SCpnt
|| padapter
->reconPhase
) ) 1216 DEB(printk("\npci2220i Unsolicited interrupt\n")); 1220 padapter
->expectingIRQ
=0; 1221 outb_p(0x08, padapter
->regDmaCmdStat
);// cancel interrupt from DMA engine 1223 if( padapter
->failinprog
) 1225 DEB(printk("\npci2220i interrupt failover complete")); 1226 padapter
->failinprog
= FALSE
; 1227 status
=inb_p(padapter
->regStatCmd
);// read the device status 1228 if( status
& (IDE_STATUS_ERROR
| IDE_STATUS_WRITE_FAULT
) ) 1230 DEB(printk("\npci2220i: interrupt failover error from drive %X", status
)); 1235 DEB(printk("\npci2220i: restarting failed opertation.")); 1236 pdev
->spigot
= (padapter
->survivor
) ?2:1; 1237 del_timer(&padapter
->timer
); 1238 if( padapter
->reconPhase
) 1239 OpDone(padapter
, DID_OK
<<16); 1241 Pci2220i_QueueCommand(SCpnt
, SCpnt
->scsi_done
); 1246 if( padapter
->reconPhase
) 1248 switch( padapter
->reconPhase
) 1250 case RECON_PHASE_MARKING
: 1251 case RECON_PHASE_LAST
: 1252 status
=inb_p(padapter
->regStatCmd
);// read the device status 1253 del_timer(&padapter
->timer
); 1254 if( padapter
->reconPhase
== RECON_PHASE_LAST
) 1256 if( status
& (IDE_STATUS_ERROR
| IDE_STATUS_WRITE_FAULT
) ) 1258 padapter
->survivor
= (pdev
->spigot
^3) >>1; 1259 DEB(printk("\npci2220i: FAILURE 10")); 1260 if(InitFailover(padapter
, pdev
) ) 1261 OpDone(padapter
,DecodeError(padapter
, status
)); 1264 if(WriteSignature(padapter
, pdev
, pdev
->hotRecon
, pdev
->mirrorRecon
) ) 1266 padapter
->survivor
= (pdev
->spigot
) >>1; 1267 DEB(printk("\npci2220i: FAILURE 11")); 1268 if(InitFailover(padapter
, pdev
) ) 1269 OpDone(padapter
,DecodeError(padapter
, status
)); 1272 padapter
->reconPhase
= RECON_PHASE_END
; 1275 OpDone(padapter
, DID_OK
<<16); 1278 case RECON_PHASE_READY
: 1279 status
=inb_p(padapter
->regStatCmd
);// read the device status 1280 if( status
& (IDE_STATUS_ERROR
| IDE_STATUS_WRITE_FAULT
) ) 1282 del_timer(&padapter
->timer
); 1283 OpDone(padapter
,DecodeError(padapter
, status
)); 1286 SelectSpigot(padapter
, pdev
->hotRecon
); 1287 if(WaitDrq(padapter
) ) 1289 del_timer(&padapter
->timer
); 1290 padapter
->survivor
= (pdev
->spigot
) >>1; 1291 DEB(printk("\npci2220i: FAILURE 12")); 1292 if(InitFailover(padapter
, pdev
) ) 1293 OpDone(padapter
,DecodeError(padapter
, status
)); 1296 SelectSpigot(padapter
, pdev
->spigot
|0x40); 1297 padapter
->reconPhase
= RECON_PHASE_COPY
; 1298 padapter
->expectingIRQ
= TRUE
; 1299 if( padapter
->timingPIO
) 1301 insw(padapter
->regData
, padapter
->kBuffer
, padapter
->reconSize
* (BYTES_PER_SECTOR
/2)); 1305 outl(padapter
->timingAddress
, padapter
->regDmaAddrLoc
); 1306 outl(virt_to_bus(padapter
->kBuffer
), padapter
->regDmaAddrPci
); 1307 outl(padapter
->reconSize
* BYTES_PER_SECTOR
, padapter
->regDmaCount
); 1308 outb_p(8, padapter
->regDmaDesc
);// read operation 1309 outb_p(1, padapter
->regDmaMode
);// no interrupt 1310 outb_p(0x03, padapter
->regDmaCmdStat
);// kick the DMA engine in gear 1314 case RECON_PHASE_COPY
: 1315 pdev
->DiskMirror
[pdev
->mirrorRecon
].reconstructPoint
+= padapter
->reconSize
; 1317 case RECON_PHASE_UPDATE
: 1318 SelectSpigot(padapter
, pdev
->hotRecon
|0x80); 1319 status
=inb_p(padapter
->regStatCmd
);// read the device status 1320 del_timer(&padapter
->timer
); 1321 if( status
& (IDE_STATUS_ERROR
| IDE_STATUS_WRITE_FAULT
) ) 1323 padapter
->survivor
= (pdev
->spigot
) >>1; 1324 DEB(printk("\npci2220i: FAILURE 13")); 1325 if(InitFailover(padapter
, pdev
) ) 1326 OpDone(padapter
,DecodeError(padapter
, status
)); 1329 OpDone(padapter
, DID_OK
<<16); 1332 case RECON_PHASE_END
: 1333 status
=inb_p(padapter
->regStatCmd
);// read the device status 1334 del_timer(&padapter
->timer
); 1335 if( status
& (IDE_STATUS_ERROR
| IDE_STATUS_WRITE_FAULT
) ) 1337 padapter
->survivor
= (pdev
->spigot
) >>1; 1338 DEB(printk("\npci2220i: FAILURE 14")); 1339 if(InitFailover(padapter
, pdev
) ) 1340 OpDone(padapter
,DecodeError(padapter
, status
)); 1343 padapter
->reconOn
= FALSE
; 1345 OpDone(padapter
, DID_OK
<<16); 1353 switch( padapter
->cmd
)// decide how to handle the interrupt 1356 if( padapter
->sectorCount
) 1358 status
=inb_p(padapter
->regStatCmd
);// read the device status 1359 if( status
& (IDE_STATUS_ERROR
| IDE_STATUS_WRITE_FAULT
) ) 1363 padapter
->survivor
= (pdev
->spigot
^3) >>1; 1364 del_timer(&padapter
->timer
); 1365 DEB(printk("\npci2220i: FAILURE 15")); 1366 if( !InitFailover(padapter
, pdev
) ) 1371 if( padapter
->timingPIO
) 1373 zl
= (padapter
->sectorCount
> MAX_BUS_MASTER_BLOCKS
) ? MAX_BUS_MASTER_BLOCKS
: padapter
->sectorCount
; 1374 insw(padapter
->regData
, padapter
->buffer
, zl
* (BYTES_PER_SECTOR
/2)); 1375 padapter
->sectorCount
-= zl
; 1376 padapter
->buffer
+= zl
* BYTES_PER_SECTOR
; 1377 if( !padapter
->sectorCount
) 1384 BusMaster(padapter
,1,1); 1385 padapter
->expectingIRQ
= TRUE
; 1392 SelectSpigot(padapter
, pdev
->spigot
|0x80); 1393 status
=inb_p(padapter
->regStatCmd
);// read the device status 1396 SelectSpigot(padapter
, (pdev
->spigot
^3) |0x80); 1397 status1
=inb_p(padapter
->regStatCmd
);// read the device status 1402 if( status
& (IDE_STATUS_ERROR
| IDE_STATUS_WRITE_FAULT
) ) 1404 if( pdev
->raid
&& !(status1
& (IDE_STATUS_ERROR
| IDE_STATUS_WRITE_FAULT
)) ) 1406 padapter
->survivor
= (pdev
->spigot
^3) >>1; 1407 del_timer(&padapter
->timer
); 1408 SelectSpigot(padapter
, pdev
->spigot
|0x80); 1409 DEB(printk("\npci2220i: FAILURE 16 status = %X error = %X", status
,inb_p(padapter
->regError
))); 1410 if( !InitFailover(padapter
, pdev
) ) 1417 if( status1
& (IDE_STATUS_ERROR
| IDE_STATUS_WRITE_FAULT
) ) 1419 padapter
->survivor
= pdev
->spigot
>>1; 1420 del_timer(&padapter
->timer
); 1421 DEB(printk("\npci2220i: FAILURE 17 status = %X error = %X", status1
,inb_p(padapter
->regError
))); 1422 if( !InitFailover(padapter
, pdev
) ) 1427 if( padapter
->sectorCount
) 1429 status
=WriteDataBoth(padapter
); 1432 padapter
->survivor
= (status
^3) >>1; 1433 del_timer(&padapter
->timer
); 1434 DEB(printk("\npci2220i: FAILURE 18")); 1435 if( !InitFailover(padapter
, pdev
) ) 1437 SelectSpigot(padapter
, status
|0x80); 1438 status
=inb_p(padapter
->regStatCmd
);// read the device status 1441 padapter
->expectingIRQ
= TRUE
; 1447 if( padapter
->sectorCount
) 1449 SelectSpigot(padapter
, pdev
->spigot
); 1450 status
=WriteData(padapter
); 1453 padapter
->expectingIRQ
= TRUE
; 1459 case IDE_COMMAND_IDENTIFY
: 1461 PINQUIRYDATA pinquiryData
= SCpnt
->request_buffer
; 1462 PIDENTIFY_DATA pid
= (PIDENTIFY_DATA
)padapter
->kBuffer
; 1464 status
=inb_p(padapter
->regStatCmd
); 1465 if( status
& IDE_STATUS_DRQ
) 1467 insw(padapter
->regData
, pid
,sizeof(IDENTIFY_DATA
) >>1); 1469 memset(pinquiryData
,0, SCpnt
->request_bufflen
);// Zero INQUIRY data structure. 1470 pinquiryData
->DeviceType
=0; 1471 pinquiryData
->Versions
=2; 1472 pinquiryData
->AdditionalLength
=35-4; 1474 // Fill in vendor identification fields. 1475 for( z
=0; z
<20; z
+=2) 1477 pinquiryData
->VendorId
[z
] = ((UCHAR
*)pid
->ModelNumber
)[z
+1]; 1478 pinquiryData
->VendorId
[z
+1] = ((UCHAR
*)pid
->ModelNumber
)[z
]; 1481 // Initialize unused portion of product id. 1482 for( z
=0; z
<4; z
++ ) 1483 pinquiryData
->ProductId
[12+ z
] =' '; 1485 // Move firmware revision from IDENTIFY data to 1486 // product revision in INQUIRY data. 1487 for( z
=0; z
<4; z
+=2) 1489 pinquiryData
->ProductRevisionLevel
[z
] = ((UCHAR
*)pid
->FirmwareRevision
)[z
+1]; 1490 pinquiryData
->ProductRevisionLevel
[z
+1] = ((UCHAR
*)pid
->FirmwareRevision
)[z
]; 1492 if( pdev
== padapter
->device
) 1493 *((USHORT
*)(&pinquiryData
->VendorSpecific
)) = DEVICE_DALE_1
; 1505 del_timer(&padapter
->timer
); 1508 DEB(printk("\npci2220i Interupt hanlder return error")); 1509 zl
=DecodeError(padapter
, status
); 1514 OpDone(padapter
, zl
); 1516 #if LINUX_VERSION_CODE < LINUXVERSION(2,1,95) 1518 * Restore the original flags which will enable interrupts 1519 * if and only if they were enabled on entry. 1521 restore_flags(flags
); 1522 #else/* version >= v2.1.95 */ 1524 * Release the I/O spinlock and restore the original flags 1525 * which will enable interrupts if and only if they were 1528 spin_unlock_irqrestore(&io_request_lock
, flags
); 1529 #endif/* version >= v2.1.95 */ 1531 /**************************************************************** 1532 * Name: Pci2220i_QueueCommand 1534 * Description: Process a queued command from the SCSI manager. 1536 * Parameters: SCpnt - Pointer to SCSI command structure. 1537 * done - Pointer to done function to call. 1539 * Returns: Status code. 1541 ****************************************************************/ 1542 intPci2220i_QueueCommand(Scsi_Cmnd
*SCpnt
,void(*done
)(Scsi_Cmnd
*)) 1544 UCHAR
*cdb
= (UCHAR
*)SCpnt
->cmnd
;// Pointer to SCSI CDB 1545 PADAPTER2220I padapter
=HOSTDATA(SCpnt
->host
);// Pointer to adapter control structure 1546 POUR_DEVICE pdev
= &padapter
->device
[SCpnt
->target
];// Pointer to device information 1547 UCHAR rc
;// command return code 1551 SCpnt
->scsi_done
= done
; 1552 padapter
->buffer
= SCpnt
->request_buffer
; 1553 padapter
->SCpnt
= SCpnt
;// Save this command data 1556 printk("pci2220i_queuecommand: %02X: done can't be NULL\n", *cdb
); 1560 if( padapter
->reconPhase
) 1562 if( padapter
->reconTimer
.data
) 1564 del_timer(&padapter
->reconTimer
); 1565 padapter
->reconTimer
.data
=0; 1568 if( !pdev
->device
|| SCpnt
->lun
) 1570 OpDone(padapter
, DID_BAD_TARGET
<<16); 1577 case SCSIOP_INQUIRY
:// inquiry CDB 1579 if( cdb
[2] == SC_MY_RAID
) 1583 case MY_SCSI_REBUILD
: 1584 padapter
->reconOn
= padapter
->reconIsStarting
= TRUE
; 1585 OpDone(padapter
, DID_OK
<<16); 1587 case MY_SCSI_ALARMMUTE
: 1588 MuteAlarm(padapter
); 1589 OpDone(padapter
, DID_OK
<<16); 1591 case MY_SCSI_DEMOFAIL
: 1592 padapter
->demoFail
= TRUE
; 1593 OpDone(padapter
, DID_OK
<<16); 1596 z
= cdb
[5];// get index 1597 pdr
= (PDEVICE_RAID1
)SCpnt
->request_buffer
; 1598 if( padapter
->raidData
[z
] ) 1600 memcpy(&pdr
->DiskRaid1
, padapter
->raidData
[z
],sizeof(DISK_MIRROR
)); 1601 pdr
->TotalSectors
= padapter
->device
[0].blocks
; 1604 memset(pdr
,0,sizeof(DEVICE_RAID1
)); 1605 OpDone(padapter
, DID_OK
<<16); 1610 padapter
->cmd
= IDE_COMMAND_IDENTIFY
; 1614 case SCSIOP_TEST_UNIT_READY
:// test unit ready CDB 1615 OpDone(padapter
, DID_OK
<<16); 1617 case SCSIOP_READ_CAPACITY
:// read capctiy CDB 1619 PREAD_CAPACITY_DATA pdata
= (PREAD_CAPACITY_DATA
)SCpnt
->request_buffer
; 1621 pdata
->blksiz
=0x20000; 1622 XANY2SCSI((UCHAR
*)&pdata
->blks
, pdev
->blocks
); 1623 OpDone(padapter
, DID_OK
<<16); 1626 case SCSIOP_VERIFY
:// verify CDB 1627 padapter
->startSector
=XSCSI2LONG(&cdb
[2]); 1628 padapter
->sectorCount
= (UCHAR
)((USHORT
)cdb
[8] | ((USHORT
)cdb
[7] <<8)); 1629 padapter
->cmd
= IDE_COMMAND_VERIFY
; 1631 case SCSIOP_READ
:// read10 CDB 1632 padapter
->startSector
=XSCSI2LONG(&cdb
[2]); 1633 padapter
->sectorCount
= (USHORT
)cdb
[8] | ((USHORT
)cdb
[7] <<8); 1634 padapter
->cmd
= READ_CMD
; 1636 case SCSIOP_READ6
:// read6 CDB 1637 padapter
->startSector
=SCSI2LONG(&cdb
[1]); 1638 padapter
->sectorCount
= cdb
[4]; 1639 padapter
->cmd
= READ_CMD
; 1641 case SCSIOP_WRITE
:// write10 CDB 1642 padapter
->startSector
=XSCSI2LONG(&cdb
[2]); 1643 padapter
->sectorCount
= (USHORT
)cdb
[8] | ((USHORT
)cdb
[7] <<8); 1644 padapter
->cmd
= WRITE_CMD
; 1646 case SCSIOP_WRITE6
:// write6 CDB 1647 padapter
->startSector
=SCSI2LONG(&cdb
[1]); 1648 padapter
->sectorCount
= cdb
[4]; 1649 padapter
->cmd
= WRITE_CMD
; 1652 DEB(printk("pci2220i_queuecommand: Unsupported command %02X\n", *cdb
)); 1653 OpDone(padapter
, DID_ERROR
<<16); 1657 if( padapter
->reconPhase
) 1660 padapter
->pdev
= pdev
; 1662 while( padapter
->demoFail
) 1664 padapter
->demoFail
= FALSE
; 1666 (pdev
->DiskMirror
[0].status
& UCBF_SURVIVOR
) || 1667 (pdev
->DiskMirror
[1].status
& UCBF_SURVIVOR
) ) 1671 if( pdev
->DiskMirror
[0].status
& UCBF_REBUILD
) 1672 padapter
->survivor
=1; 1674 padapter
->survivor
=0; 1675 DEB(printk("\npci2220i: FAILURE 19")); 1676 if(InitFailover(padapter
, pdev
) ) 1681 StartTimer(padapter
); 1682 if( pdev
->raid
&& (padapter
->cmd
== WRITE_CMD
) ) 1684 rc
=IdeCmdBoth(padapter
); 1686 rc
=WriteDataBoth(padapter
); 1689 del_timer(&padapter
->timer
); 1690 padapter
->expectingIRQ
=0; 1691 padapter
->survivor
= (rc
^3) >>1; 1692 DEB(printk("\npci2220i: FAILURE 20")); 1693 if(InitFailover(padapter
, pdev
) ) 1695 OpDone(padapter
, DID_ERROR
<<16); 1702 rc
=IdeCmd(padapter
, pdev
); 1703 if( (padapter
->cmd
== WRITE_CMD
) && !rc
) 1704 rc
=WriteData(padapter
); 1707 del_timer(&padapter
->timer
); 1708 padapter
->expectingIRQ
=0; 1711 padapter
->survivor
= (pdev
->spigot
^3) >>1; 1712 DEB(printk("\npci2220i: FAILURE 21")); 1713 if( !InitFailover(padapter
, pdev
) ) 1716 OpDone(padapter
, DID_ERROR
<<16); 1723 static voidinternal_done(Scsi_Cmnd
*SCpnt
) 1725 SCpnt
->SCp
.Status
++; 1727 /**************************************************************** 1728 * Name: Pci2220i_Command 1730 * Description: Process a command from the SCSI manager. 1732 * Parameters: SCpnt - Pointer to SCSI command structure. 1734 * Returns: Status code. 1736 ****************************************************************/ 1737 intPci2220i_Command(Scsi_Cmnd
*SCpnt
) 1739 Pci2220i_QueueCommand(SCpnt
, internal_done
); 1740 SCpnt
->SCp
.Status
=0; 1741 while(!SCpnt
->SCp
.Status
) 1743 return SCpnt
->result
; 1745 /**************************************************************** 1748 * Description: Read information from controller Flash memory. 1750 * Parameters: padapter - Pointer to host interface data structure. 1751 * pdata - Pointer to data structures. 1752 * base - base address in Flash. 1753 * length - lenght of data space in bytes. 1757 ****************************************************************/ 1758 VOID
ReadFlash(PADAPTER2220I padapter
, VOID
*pdata
, ULONG base
, ULONG length
) 1763 UCHAR
*pd
= (UCHAR
*)pdata
; 1765 oldremap
=inl(padapter
->regRemap
);// save values to restore later 1766 olddesc
=inb_p(padapter
->regDesc
); 1768 outl(base
|1, padapter
->regRemap
);// remap to Flash space as specified 1769 outb_p(0x40, padapter
->regDesc
);// describe remap region as 8 bit 1770 for( z
=0; z
< length
; z
++)// get "length" data count 1771 *pd
++ =inb_p(padapter
->regBase
+ z
);// read in the data 1773 outl(oldremap
, padapter
->regRemap
);// restore remap register values 1774 outb_p(olddesc
, padapter
->regDesc
); 1776 /**************************************************************** 1777 * Name: Pci2220i_Detect 1779 * Description: Detect and initialize our boards. 1781 * Parameters: tpnt - Pointer to SCSI host template structure. 1783 * Returns: Number of adapters installed. 1785 ****************************************************************/ 1786 intPci2220i_Detect(Scsi_Host_Template
*tpnt
) 1790 struct Scsi_Host
*pshost
; 1791 PADAPTER2220I padapter
; 1795 USHORT raidon
= FALSE
; 1797 UCHAR spigot1
= FALSE
; 1798 UCHAR spigot2
= FALSE
; 1799 #if LINUX_VERSION_CODE > LINUXVERSION(2,1,92) 1800 struct pci_dev
*pdev
= NULL
; 1802 UCHAR pci_bus
, pci_device_fn
; 1805 #if LINUX_VERSION_CODE > LINUXVERSION(2,1,92) 1806 if( !pci_present() ) 1808 if( !pcibios_present() ) 1811 printk("pci2220i: PCI BIOS not present\n"); 1815 #if LINUX_VERSION_CODE > LINUXVERSION(2,1,92) 1816 while( (pdev
=pci_find_device(VENDOR_PSI
, DEVICE_DALE_1
, pdev
)) != NULL
) 1818 while( !pcibios_find_device(VENDOR_PSI
, DEVICE_DALE_1
, found
, &pci_bus
, &pci_device_fn
) ) 1821 pshost
=scsi_register(tpnt
,sizeof(ADAPTER2220I
)); 1822 padapter
=HOSTDATA(pshost
); 1823 memset(padapter
,0,sizeof(ADAPTER2220I
)); 1825 zs
= pdev
->resource
[1].start
; 1826 padapter
->basePort
= zs
; 1827 padapter
->regRemap
= zs
+ RTR_LOCAL_REMAP
;// 32 bit local space remap 1828 padapter
->regDesc
= zs
+ RTR_REGIONS
;// 32 bit local region descriptor 1829 padapter
->regRange
= zs
+ RTR_LOCAL_RANGE
;// 32 bit local range 1830 padapter
->regIrqControl
= zs
+ RTR_INT_CONTROL_STATUS
;// 16 bit interupt control and status 1831 padapter
->regScratchPad
= zs
+ RTR_MAILBOX
;// 16 byte scratchpad I/O base address 1833 zs
= pdev
->resource
[2].start
; 1834 padapter
->regBase
= zs
; 1835 padapter
->regData
= zs
+ REG_DATA
;// data register I/O address 1836 padapter
->regError
= zs
+ REG_ERROR
;// error register I/O address 1837 padapter
->regSectCount
= zs
+ REG_SECTOR_COUNT
;// sector count register I/O address 1838 padapter
->regLba0
= zs
+ REG_LBA_0
;// least significant byte of LBA 1839 padapter
->regLba8
= zs
+ REG_LBA_8
;// next least significant byte of LBA 1840 padapter
->regLba16
= zs
+ REG_LBA_16
;// next most significan byte of LBA 1841 padapter
->regLba24
= zs
+ REG_LBA_24
;// head and most 4 significant bits of LBA 1842 padapter
->regStatCmd
= zs
+ REG_STAT_CMD
;// status on read and command on write register 1843 padapter
->regStatSel
= zs
+ REG_STAT_SEL
;// board status on read and spigot select on write register 1844 padapter
->regFail
= zs
+ REG_FAIL
; 1845 padapter
->regAltStat
= zs
+ REG_ALT_STAT
; 1847 padapter
->regDmaDesc
= zs
+ RTL_DMA1_DESC_PTR
;// address of the DMA discriptor register for direction of transfer 1848 padapter
->regDmaCmdStat
= zs
+ RTL_DMA_COMMAND_STATUS
+1;// Byte #1 of DMA command status register 1849 padapter
->regDmaAddrPci
= zs
+ RTL_DMA1_PCI_ADDR
;// 32 bit register for PCI address of DMA 1850 padapter
->regDmaAddrLoc
= zs
+ RTL_DMA1_LOCAL_ADDR
;// 32 bit register for local bus address of DMA 1851 padapter
->regDmaCount
= zs
+ RTL_DMA1_COUNT
;// 32 bit register for DMA transfer count 1852 padapter
->regDmaMode
= zs
+ RTL_DMA1_MODE
+1;// 32 bit register for DMA mode control 1854 if( !inb_p(padapter
->regScratchPad
+ DALE_NUM_DRIVES
) )// if no devices on this board 1857 #if LINUX_VERSION_CODE > LINUXVERSION(2,1,92) 1858 pshost
->irq
= pdev
->irq
; 1860 pcibios_read_config_byte(pci_bus
, pci_device_fn
, PCI_INTERRUPT_LINE
, &pshost
->irq
); 1863 for( z
=0; z
< installed
; z
++ )// scan for shared interrupts 1865 if( PsiHost
[z
]->irq
== pshost
->irq
)// if shared then, don't posses 1868 if( setirq
)// if not shared, posses 1870 if(request_irq(pshost
->irq
, Irq_Handler
, SA_SHIRQ
,"pci2220i", padapter
) <0) 1872 if(request_irq(pshost
->irq
, Irq_Handler
, SA_INTERRUPT
| SA_SHIRQ
,"pci2220i", padapter
) <0) 1874 printk("Unable to allocate IRQ for PCI-2220I controller.\n"); 1878 padapter
->irqOwned
= pshost
->irq
;// set IRQ as owned 1880 padapter
->kBuffer
=kmalloc(SECTORSXFER
* BYTES_PER_SECTOR
, GFP_DMA
| GFP_ATOMIC
); 1881 if( !padapter
->kBuffer
) 1883 printk("Unable to allocate DMA buffer for PCI-2220I controller.\n"); 1884 #if LINUX_VERSION_CODE < LINUXVERSION(1,3,70) 1885 free_irq(pshost
->irq
); 1886 #else/* version >= v1.3.70 */ 1887 free_irq(pshost
->irq
, padapter
); 1888 #endif/* version >= v1.3.70 */ 1891 PsiHost
[installed
] = pshost
;// save SCSI_HOST pointer 1893 pshost
->io_port
= padapter
->basePort
; 1894 pshost
->n_io_port
=0xFF; 1895 pshost
->unique_id
= padapter
->regBase
; 1898 outb_p(0x01, padapter
->regRange
);// fix our range register because other drivers want to tromp on it 1900 padapter
->timingMode
=inb_p(padapter
->regScratchPad
+ DALE_TIMING_MODE
); 1901 if( padapter
->timingMode
>=2) 1902 padapter
->timingAddress
= ModeArray
[padapter
->timingMode
-2]; 1904 padapter
->timingPIO
= TRUE
; 1906 ReadFlash(padapter
, &DaleSetup
, DALE_FLASH_SETUP
,sizeof(SETUP
)); 1907 for( z
=0; z
<inb_p(padapter
->regScratchPad
+ DALE_NUM_DRIVES
); ++z
) 1909 unit
=inb_p(padapter
->regScratchPad
+ DALE_CHANNEL_DEVICE_0
+ z
) &0x0F; 1910 padapter
->device
[z
].device
=inb_p(padapter
->regScratchPad
+ DALE_SCRATH_DEVICE_0
+ unit
); 1911 padapter
->device
[z
].byte6
= (UCHAR
)(((unit
&1) <<4) |0xE0); 1912 padapter
->device
[z
].spigot
= (UCHAR
)(1<< (unit
>>1)); 1913 padapter
->device
[z
].sectors
= DaleSetup
.setupDevice
[unit
].sectors
; 1914 padapter
->device
[z
].heads
= DaleSetup
.setupDevice
[unit
].heads
; 1915 padapter
->device
[z
].cylinders
= DaleSetup
.setupDevice
[unit
].cylinders
; 1916 padapter
->device
[z
].blocks
= DaleSetup
.setupDevice
[unit
].blocks
; 1920 ReadFlash(padapter
, &DiskMirror
, DALE_FLASH_RAID
,sizeof(DiskMirror
)); 1921 DiskMirror
[0].status
=inb_p(padapter
->regScratchPad
+ DALE_RAID_0_STATUS
); 1922 DiskMirror
[1].status
=inb_p(padapter
->regScratchPad
+ DALE_RAID_1_STATUS
); 1923 if( (DiskMirror
[0].signature
== SIGNATURE
) && (DiskMirror
[1].signature
== SIGNATURE
) && 1924 (DiskMirror
[0].pairIdentifier
== (DiskMirror
[1].pairIdentifier
^1)) ) 1929 memcpy(padapter
->device
[z
].DiskMirror
, DiskMirror
,sizeof(DiskMirror
)); 1930 padapter
->raidData
[0] = &padapter
->device
[z
].DiskMirror
[0]; 1931 padapter
->raidData
[2] = &padapter
->device
[z
].DiskMirror
[1]; 1935 padapter
->device
[z
].lastsectorlba
[0] =InlineIdentify(padapter
,1,0); 1936 padapter
->device
[z
].lastsectorlba
[1] =InlineIdentify(padapter
,2,0); 1938 if( !(DiskMirror
[1].status
& UCBF_SURVIVOR
) && padapter
->device
[z
].lastsectorlba
[0] ) 1940 if( !(DiskMirror
[0].status
& UCBF_SURVIVOR
) && padapter
->device
[z
].lastsectorlba
[1] ) 1942 if( DiskMirror
[0].status
& UCBF_SURVIVOR
& DiskMirror
[1].status
& UCBF_SURVIVOR
) 1945 if( spigot1
&& (DiskMirror
[0].status
& UCBF_REBUILD
) ) 1946 InlineReadSignature(padapter
, &padapter
->device
[z
],0); 1947 if( spigot2
&& (DiskMirror
[1].status
& UCBF_REBUILD
) ) 1948 InlineReadSignature(padapter
, &padapter
->device
[z
],1); 1950 if( spigot1
&& spigot2
) 1952 padapter
->device
[z
].raid
=1; 1953 if( DiskMirror
[0].status
& UCBF_REBUILD
) 1954 padapter
->device
[z
].spigot
=2; 1956 padapter
->device
[z
].spigot
=1; 1957 if( (DiskMirror
[0].status
& UCBF_REBUILD
) || (DiskMirror
[1].status
& UCBF_REBUILD
) ) 1959 padapter
->reconOn
= padapter
->reconIsStarting
= TRUE
; 1966 if( DiskMirror
[0].status
& UCBF_REBUILD
) 1968 DiskMirror
[0].status
= UCBF_MIRRORED
| UCBF_SURVIVOR
; 1969 padapter
->device
[z
].spigot
=1; 1973 if( DiskMirror
[1].status
& UCBF_REBUILD
) 1975 DiskMirror
[1].status
= UCBF_MIRRORED
| UCBF_SURVIVOR
; 1976 padapter
->device
[z
].spigot
=2; 1978 if( DaleSetup
.rebootRebuil
) 1979 padapter
->reconOn
= padapter
->reconIsStarting
= TRUE
; 1987 init_timer(&padapter
->timer
); 1988 padapter
->timer
.function
= TimerExpiry
; 1989 padapter
->timer
.data
= (unsigned long)padapter
; 1990 init_timer(&padapter
->reconTimer
); 1991 padapter
->reconTimer
.function
= ReconTimerExpiry
; 1992 padapter
->reconTimer
.data
= (unsigned long)padapter
; 1993 printk("\nPCI-2220I EIDE CONTROLLER: at I/O = %X/%X IRQ = %d\n", padapter
->basePort
, padapter
->regBase
, pshost
->irq
); 1994 printk("Version %s, Compiled %s %s\n\n", PCI2220I_VERSION
, __DATE__
, __TIME__
); 1996 if( ++installed
< MAXADAPTER
) 2000 scsi_unregister(pshost
); 2004 NumAdapters
= installed
; 2007 /**************************************************************** 2008 * Name: Pci2220i_Abort 2010 * Description: Process the Abort command from the SCSI manager. 2012 * Parameters: SCpnt - Pointer to SCSI command structure. 2014 * Returns: Allways snooze. 2016 ****************************************************************/ 2017 intPci2220i_Abort(Scsi_Cmnd
*SCpnt
) 2019 return SCSI_ABORT_SNOOZE
; 2021 /**************************************************************** 2022 * Name: Pci2220i_Reset 2024 * Description: Process the Reset command from the SCSI manager. 2026 * Parameters: SCpnt - Pointer to SCSI command structure. 2027 * flags - Flags about the reset command 2029 * Returns: No active command at this time, so this means 2030 * that each time we got some kind of response the 2031 * last time through. Tell the mid-level code to 2032 * request sense information in order to decide what 2035 ****************************************************************/ 2036 intPci2220i_Reset(Scsi_Cmnd
*SCpnt
,unsigned int reset_flags
) 2038 return SCSI_RESET_PUNT
; 2040 /**************************************************************** 2041 * Name: Pci2220i_Release 2043 * Description: Release resources allocated for a single each adapter. 2045 * Parameters: pshost - Pointer to SCSI command structure. 2049 ****************************************************************/ 2050 intPci2220i_Release(struct Scsi_Host
*pshost
) 2052 PADAPTER2220I padapter
=HOSTDATA(pshost
); 2054 if( padapter
->reconOn
) 2056 padapter
->reconOn
= FALSE
;// shut down the hot reconstruct 2057 if( padapter
->reconPhase
) 2059 if( padapter
->reconTimer
.data
)// is the timer running? 2061 del_timer(&padapter
->reconTimer
); 2062 padapter
->reconTimer
.data
=0; 2066 // save RAID status on the board 2067 outb_p(DiskMirror
[0].status
, padapter
->regScratchPad
+ DALE_RAID_0_STATUS
); 2068 outb_p(DiskMirror
[1].status
, padapter
->regScratchPad
+ DALE_RAID_1_STATUS
); 2070 if( padapter
->irqOwned
) 2071 #if LINUX_VERSION_CODE < LINUXVERSION(1,3,70) 2072 free_irq(pshost
->irq
); 2073 #else/* version >= v1.3.70 */ 2074 free_irq(pshost
->irq
, padapter
); 2075 #endif/* version >= v1.3.70 */ 2076 release_region(pshost
->io_port
, pshost
->n_io_port
); 2077 kfree(padapter
->kBuffer
); 2078 scsi_unregister(pshost
); 2084 /**************************************************************** 2085 * Name: Pci2220i_BiosParam 2087 * Description: Process the biosparam request from the SCSI manager to 2088 * return C/H/S data. 2090 * Parameters: disk - Pointer to SCSI disk structure. 2091 * dev - Major/minor number from kernel. 2092 * geom - Pointer to integer array to place geometry data. 2096 ****************************************************************/ 2097 intPci2220i_BiosParam(Scsi_Disk
*disk
, kdev_t dev
,int geom
[]) 2101 pdev
= &(HOSTDATA(disk
->device
->host
)->device
[disk
->device
->id
]); 2103 geom
[0] = pdev
->heads
; 2104 geom
[1] = pdev
->sectors
; 2105 geom
[2] = pdev
->cylinders
; 2111 /* Eventually this will go into an include file, but this will be later */ 2112 Scsi_Host_Template driver_template
= PCI2220I
; 2114 #include"scsi_module.c"