📄 pci2220i.c
字号:
else { DEB (printk ("in I/O operation")); status = inb_p (padapter->regStatCmd); } break; } OpDone (padapter, DecodeError (padapter, status));timerExpiryDone:; /* * Release the I/O spinlock and restore the original flags * which will enable interrupts if and only if they were * enabled on entry. */ spin_unlock_irqrestore (&io_request_lock, flags); }/**************************************************************** * Name: SetReconstruct :LOCAL * * Description: Set the reconstruct up. * * Parameters: pdev - Pointer to device structure. * index - Mirror index number. * * Returns: Number of sectors on new disk required. * ****************************************************************/static LONG SetReconstruct (POUR_DEVICE pdev, int index) { pdev->DiskMirror[index].status = UCBF_MIRRORED; // setup the flags pdev->DiskMirror[index ^ 1].status = UCBF_MIRRORED | UCBF_REBUILD; pdev->DiskMirror[index ^ 1].reconstructPoint = 0; // start the reconstruct pdev->reconCount = 1990; // mark target drive early return pdev->DiskMirror[index].reconstructPoint; }/**************************************************************** * Name: ReconTimerExpiry :LOCAL * * Description: Reconstruct timer expiry routine. * * Parameters: data - Pointer adapter data structure. * * Returns: Nothing. * ****************************************************************/static void ReconTimerExpiry (unsigned long data) { PADAPTER2220I padapter; POUR_DEVICE pdev; ULONG testsize = 0; PIDENTIFY_DATA pid; USHORT minmode; ULONG zl; UCHAR zc; USHORT z; unsigned long flags; /* * Disable interrupts, if they aren't already disabled and acquire * the I/O spinlock. */ spin_lock_irqsave (&io_request_lock, flags); padapter = (PADAPTER2220I)data; if ( padapter->SCpnt ) goto reconTimerExpiry; padapter->reconTimer.data = 0; for ( z = padapter->devInReconIndex + 1; z < BIGD_MAXDRIVES; z++ ) { if ( padapter->device[z].reconOn ) break; } if ( z < BIGD_MAXDRIVES ) pdev = &padapter->device[z]; else { for ( z = 0; z < BIGD_MAXDRIVES; z++ ) { if ( padapter->device[z].reconOn ) break; } if ( z < BIGD_MAXDRIVES ) pdev = &padapter->device[z]; else { padapter->reconOn = FALSE; goto reconTimerExpiry; } } padapter->devInReconIndex = z; pid = (PIDENTIFY_DATA)padapter->kBuffer; padapter->pdev = pdev; if ( pdev->reconIsStarting ) { pdev->reconIsStarting = FALSE; pdev->reconOn = FALSE; while ( (pdev->DiskMirror[0].signature == SIGNATURE) && (pdev->DiskMirror[1].signature == SIGNATURE) && (pdev->DiskMirror[0].pairIdentifier == (pdev->DiskMirror[1].pairIdentifier ^ 1)) ) { if ( (pdev->DiskMirror[0].status & UCBF_MATCHED) && (pdev->DiskMirror[1].status & UCBF_MATCHED) ) break;; if ( pdev->DiskMirror[0].status & UCBF_SURVIVOR ) // is first drive survivor? testsize = SetReconstruct (pdev, 0); else if ( pdev->DiskMirror[1].status & UCBF_SURVIVOR ) // is second drive survivor? testsize = SetReconstruct (pdev, 1); if ( (pdev->DiskMirror[0].status & UCBF_REBUILD) || (pdev->DiskMirror[1].status & UCBF_REBUILD) ) { if ( pdev->DiskMirror[0].status & UCBF_REBUILD ) pdev->mirrorRecon = 0; else pdev->mirrorRecon = 1; pdev->reconOn = TRUE; } break; } if ( !pdev->reconOn ) goto reconTimerExpiry; if ( padapter->bigD ) { padapter->failRegister = 0; outb_p (~padapter->failRegister, padapter->regFail); } else { zc = ((inb_p (padapter->regStatSel) >> 3) | inb_p (padapter->regStatSel)) & 0x83; // mute the alarm outb_p (0xFF, padapter->regFail); } while ( 1 ) { DEB (printk ("\npci2220i: hard reset issue")); if ( HardReset (padapter, pdev, pdev->spigots[pdev->mirrorRecon]) ) { DEB (printk ("\npci2220i: sub 1")); break; } pdev->lastsectorlba[pdev->mirrorRecon] = InlineIdentify (padapter, pdev->spigots[pdev->mirrorRecon], pdev->deviceID[pdev->mirrorRecon] & 1); if ( pdev->lastsectorlba[pdev->mirrorRecon] < testsize ) { DEB (printk ("\npci2220i: sub 2 %ld %ld", pdev->lastsectorlba[pdev->mirrorRecon], testsize)); break; } // test LBA and multiper sector transfer compatability if (!pid->SupportLBA || (pid->NumSectorsPerInt < SECTORSXFER) || !pid->Valid_64_70 ) { DEB (printk ("\npci2220i: sub 3")); break; } // test PIO/bus matering mode compatability if ( (pid->MinPIOCycleWithoutFlow > 240) && !pid->SupportIORDYDisable && !padapter->timingPIO ) { DEB (printk ("\npci2220i: sub 4")); break; } if ( pid->MinPIOCycleWithoutFlow <= 120 ) // setup timing mode of drive minmode = 5; else { if ( pid->MinPIOCylceWithFlow <= 150 ) minmode = 4; else { if ( pid->MinPIOCylceWithFlow <= 180 ) minmode = 3; else { if ( pid->MinPIOCylceWithFlow <= 240 ) minmode = 2; else { DEB (printk ("\npci2220i: sub 5")); break; } } } } if ( padapter->timingMode > minmode ) // set minimum timing mode padapter->timingMode = minmode; if ( padapter->timingMode >= 2 ) padapter->timingAddress = ModeArray[padapter->timingMode - 2]; else padapter->timingPIO = TRUE; padapter->reconOn = TRUE; break; } if ( !pdev->reconOn ) { padapter->survivor = pdev->mirrorRecon ^ 1; padapter->reconPhase = RECON_PHASE_FAILOVER; DEB (printk ("\npci2220i: FAILURE 7")); InitFailover (padapter, pdev); goto reconTimerExpiry; } pdev->raid = TRUE; if ( WriteSignature (padapter, pdev, pdev->spigot, pdev->mirrorRecon ^ 1) ) goto reconTimerExpiry; padapter->reconPhase = RECON_PHASE_MARKING; goto reconTimerExpiry; } //********************************** // reconstruct copy starts here //********************************** if ( pdev->reconCount++ > 2000 ) { pdev->reconCount = 0; if ( WriteSignature (padapter, pdev, pdev->spigots[pdev->mirrorRecon], pdev->mirrorRecon) ) { padapter->survivor = pdev->mirrorRecon ^ 1; padapter->reconPhase = RECON_PHASE_FAILOVER; DEB (printk ("\npci2220i: FAILURE 8")); InitFailover (padapter, pdev); goto reconTimerExpiry; } padapter->reconPhase = RECON_PHASE_UPDATE; goto reconTimerExpiry; } zl = pdev->DiskMirror[pdev->mirrorRecon].reconstructPoint; padapter->reconSize = pdev->DiskMirror[pdev->mirrorRecon ^ 1].reconstructPoint - zl; if ( padapter->reconSize > MAX_BUS_MASTER_BLOCKS ) padapter->reconSize = MAX_BUS_MASTER_BLOCKS; if ( padapter->reconSize ) { SelectSpigot (padapter, pdev->spigots[0] | pdev->spigots[1]); // select the spigots outb_p (pdev->byte6 | ((UCHAR *)(&zl))[3], padapter->regLba24); // select the drive SelectSpigot (padapter, pdev->spigot); if ( WaitReady (padapter) ) goto reconTimerExpiry; SelectSpigot (padapter, pdev->spigots[pdev->mirrorRecon]); if ( WaitReady (padapter) ) { padapter->survivor = pdev->mirrorRecon ^ 1; padapter->reconPhase = RECON_PHASE_FAILOVER; DEB (printk ("\npci2220i: FAILURE 9")); InitFailover (padapter, pdev); goto reconTimerExpiry; } SelectSpigot (padapter, pdev->spigots[0] | pdev->spigots[1]); outb_p (padapter->reconSize & 0xFF, padapter->regSectCount); outb_p (((UCHAR *)(&zl))[0], padapter->regLba0); outb_p (((UCHAR *)(&zl))[1], padapter->regLba8); outb_p (((UCHAR *)(&zl))[2], padapter->regLba16); padapter->expectingIRQ = TRUE; padapter->reconPhase = RECON_PHASE_READY; SelectSpigot (padapter, pdev->spigots[pdev->mirrorRecon]); WriteCommand (padapter, WRITE_CMD); StartTimer (padapter); SelectSpigot (padapter, pdev->spigot); WriteCommand (padapter, READ_CMD); goto reconTimerExpiry; } pdev->DiskMirror[pdev->mirrorRecon].status = UCBF_MIRRORED | UCBF_MATCHED; pdev->DiskMirror[pdev->mirrorRecon ^ 1].status = UCBF_MIRRORED | UCBF_MATCHED; if ( WriteSignature (padapter, pdev, pdev->spigot, pdev->mirrorRecon ^ 1) ) goto reconTimerExpiry; padapter->reconPhase = RECON_PHASE_LAST;reconTimerExpiry:; /* * Release the I/O spinlock and restore the original flags * which will enable interrupts if and only if they were * enabled on entry. */ spin_unlock_irqrestore (&io_request_lock, flags); }/**************************************************************** * Name: Irq_Handler :LOCAL * * Description: Interrupt handler. * * Parameters: irq - Hardware IRQ number. * dev_id - * regs - * * Returns: TRUE if drive is not ready in time. * ****************************************************************/static void Irq_Handler (int irq, void *dev_id, struct pt_regs *regs) { struct Scsi_Host *shost = NULL; // Pointer to host data block PADAPTER2220I padapter; // Pointer to adapter control structure POUR_DEVICE pdev; Scsi_Cmnd *SCpnt; UCHAR status; UCHAR status1; ATAPI_STATUS statusa; ATAPI_REASON reasona; ATAPI_ERROR errora; int z; ULONG zl; unsigned long flags; /* * Disable interrupts, if they aren't already disabled and acquire * the I/O spinlock. */ spin_lock_irqsave (&io_request_lock, flags);// DEB (printk ("\npci2220i received interrupt\n")); for ( z = 0; z < NumAdapters; z++ ) // scan for interrupt to process { if ( PsiHost[z]->irq == (UCHAR)(irq & 0xFF) ) { if ( inw_p (HOSTDATA(PsiHost[z])->regIrqControl) & 0x8000 ) { shost = PsiHost[z]; break; } } } if ( !shost ) { DEB (printk ("\npci2220i: not my interrupt")); goto irq_return; } padapter = HOSTDATA(shost); pdev = padapter->pdev; SCpnt = padapter->SCpnt; outb_p (0x08, padapter->regDmaCmdStat); // cancel interrupt from DMA engine if ( padapter->atapi && SCpnt ) { *(char *)&statusa = inb_p (padapter->regStatCmd); // read the device status *(char *)&reasona = inb_p (padapter->regSectCount); // read the device interrupt reason if ( !statusa.bsy ) { if ( statusa.drq ) // test for transfer phase { if ( !reasona.cod ) // test for data phase { z = (ULONG)inb_p (padapter->regLba8) | (ULONG)(inb_p (padapter->regLba16) << 8); if ( padapter->reqSense ) insw (padapter->regData, SCpnt->sense_buffer, z / 2); else AtapiBusMaster (padapter, reasona.io, z); goto irq_return; } if ( reasona.cod && !reasona.io ) // test for command packet phase { if ( padapter->reqSense ) AtapiRequestSense (padapter, pdev, SCpnt, TRUE); else AtapiSendCdb (padapter, pdev, padapter->atapiCdb); goto irq_return; } } else { if ( reasona.io && statusa.drdy ) // test for status phase { Atapi2Scsi (padapter, SCpnt); if ( statusa.check ) { *(UCHAR *)&errora = inb_p (padapter->regError); // read the device error if ( errora.senseKey ) { if ( padapter->reqSense || AtapiRequestSense (padapter, pdev, SCpnt, FALSE) ) OpDone (padapter, DID_ERROR << 16); } else { if ( errora.ili || errora.abort ) OpDone (padapter, DID_ERROR << 16); else OpDone (padapter, DID_OK << 16); } } else if ( padapter->reqSense ) { DEB (printk ("PCI2242I: Sense codes - %X %X %X ", ((UCHAR *)SCpnt->sense_buffer)[0], ((UCHAR *)SCpnt->sense_buffer)[12], ((UCHAR *)SCpnt->sense_buffer)[13])); OpDone (padapter, (DRIVER_SENSE << 24) | (DID_OK << 16) | 2); } else OpDone (padapter, DID_OK << 16); } } } goto irq_return; } if ( !padapter->expectingIRQ || !(SCpnt || padapter->reconPhase) ) { DEB(printk ("\npci2220i Unsolicited interrupt\n")); STOP_HERE (); goto irq_return; } padapter->expectingIRQ = 0; if ( padapter->failinprog ) { DEB (printk ("\npci2220i interrupt failover complete")); padapter->failinprog = FALSE; status = inb_p (padapter->regStatCmd); // read the device status if ( status & (IDE_STATUS_ERROR | IDE_STATUS_WRITE_FAULT) ) { DEB (printk ("\npci2220i: interrupt failover error from drive %X", status)); padapter->cmd = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -