📄 pci2220i.c
字号:
memcpy (buff, padapter->kBuffer, padapter->currentSgCount); break; default: if ( padapter->readCount ) WalkScatGath (padapter, TRUE, padapter->readCount); break; } }/**************************************************************** * Name: Scsi2Atapi * * Description: Convert SCSI packet command to Atapi packet command. * * Parameters: padapter - Pointer adapter data structure. * SCpnt - Pointer to SCSI command structure. * * Returns: Nothing. * ****************************************************************/static void Scsi2Atapi (PADAPTER2220I padapter, Scsi_Cmnd *SCpnt) { UCHAR *cdb = SCpnt->cmnd; UCHAR *buff = padapter->currentSgBuffer; switch (cdb[0]) { case SCSIOP_READ6: padapter->atapiCdb[0] = SCSIOP_READ; padapter->atapiCdb[1] = cdb[1] & 0xE0; padapter->atapiCdb[3] = cdb[1] & 0x1F; padapter->atapiCdb[4] = cdb[2]; padapter->atapiCdb[5] = cdb[3]; padapter->atapiCdb[8] = cdb[4]; padapter->atapiCdb[9] = cdb[5]; break; case SCSIOP_WRITE6: padapter->atapiCdb[0] = SCSIOP_WRITE; padapter->atapiCdb[1] = cdb[1] & 0xE0; padapter->atapiCdb[3] = cdb[1] & 0x1F; padapter->atapiCdb[4] = cdb[2]; padapter->atapiCdb[5] = cdb[3]; padapter->atapiCdb[8] = cdb[4]; padapter->atapiCdb[9] = cdb[5]; break; case SCSIOP_MODE_SENSE: padapter->atapiCdb[0] = SCSIOP_MODE_SENSE10; padapter->atapiCdb[2] = cdb[2]; padapter->atapiCdb[8] = cdb[4] + 4; break; case SCSIOP_MODE_SELECT: padapter->atapiSpecial = TRUE; padapter->atapiCdb[0] = SCSIOP_MODE_SELECT10; padapter->atapiCdb[1] = cdb[1] | 0x10; memcpy (padapter->kBuffer, buff, 4); padapter->kBuffer[4] = padapter->kBuffer[5] = 0; padapter->kBuffer[6] = padapter->kBuffer[7] = 0; memcpy (&padapter->kBuffer[8], &buff[4], cdb[4] - 4); padapter->atapiCdb[8] = cdb[4] + 4; break; } }/**************************************************************** * Name: AtapiSendCdb * * Description: Send the CDB packet to the device. * * Parameters: padapter - Pointer adapter data structure. * pdev - Pointer to device. * cdb - Pointer to 16 byte SCSI cdb. * * Returns: Nothing. * ****************************************************************/static void AtapiSendCdb (PADAPTER2220I padapter, POUR_DEVICE pdev, CHAR *cdb) { 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])); outsw (padapter->regData, cdb, pdev->packet); }/**************************************************************** * Name: AtapiRequestSense * * Description: Send the CDB packet to the device. * * Parameters: padapter - Pointer adapter data structure. * pdev - Pointer to device. * SCpnt - Pointer to SCSI command structure. * pass - If true then this is the second pass to send cdb. * * Returns: TRUE on error. * ****************************************************************/static int AtapiRequestSense (PADAPTER2220I padapter, POUR_DEVICE pdev, Scsi_Cmnd *SCpnt, UCHAR pass) { UCHAR cdb[16] = {SCSIOP_REQUEST_SENSE,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0}; DEB (printk ("\nPCI2242I: AUTO REQUEST SENSE")); cdb[4] = (UCHAR)(sizeof (SCpnt->sense_buffer)); if ( !pass ) { padapter->reqSense = TRUE; AtapiCountLo (padapter, cdb[4]); AtapiCountHi (padapter, 0); outb_p (0, padapter->regError); WriteCommand (padapter, IDE_COMMAND_ATAPI_PACKET); if ( pdev->cmdDrqInt ) return FALSE; if ( AtapiWaitDrq (padapter, 500) ) return TRUE; } AtapiSendCdb (padapter, pdev, cdb); return FALSE; }/**************************************************************** * Name: InlineReadSignature :LOCAL * * Description: Do an inline read RAID sigature. * * Parameters: padapter - Pointer adapter data structure. * pdev - Pointer to device. * index - index of data to read. * * Returns: Zero if no error or status register contents on error. * ****************************************************************/static UCHAR InlineReadSignature (PADAPTER2220I padapter, POUR_DEVICE pdev, int index) { UCHAR status; ULONG zl = pdev->lastsectorlba[index]; SelectSpigot (padapter, pdev->spigots[index] | SEL_IRQ_OFF); // select the spigot without interrupts outb_p (pdev->byte6 | ((UCHAR *)&zl)[3], padapter->regLba24); status = WaitReady (padapter); if ( !status ) { outb_p (((UCHAR *)&zl)[2], padapter->regLba16); outb_p (((UCHAR *)&zl)[1], padapter->regLba8); outb_p (((UCHAR *)&zl)[0], padapter->regLba0); outb_p (1, padapter->regSectCount); WriteCommand (padapter, IDE_COMMAND_READ); status = WaitDrq (padapter); if ( !status ) { insw (padapter->regData, padapter->kBuffer, BYTES_PER_SECTOR / 2); ((ULONG *)(&pdev->DiskMirror[index]))[0] = ((ULONG *)(&padapter->kBuffer[DISK_MIRROR_POSITION]))[0]; ((ULONG *)(&pdev->DiskMirror[index]))[1] = ((ULONG *)(&padapter->kBuffer[DISK_MIRROR_POSITION]))[1]; // some drives assert DRQ before IRQ so let's make sure we clear the IRQ WaitReady (padapter); return 0; } } return status; }/**************************************************************** * Name: DecodeError :LOCAL * * Description: Decode and process device errors. * * Parameters: padapter - Pointer to adapter data. * status - Status register code. * * Returns: The driver status code. * ****************************************************************/static ULONG DecodeError (PADAPTER2220I padapter, UCHAR status) { UCHAR error; padapter->expectingIRQ = 0; if ( status & IDE_STATUS_WRITE_FAULT ) { return DID_PARITY << 16; } if ( status & IDE_STATUS_BUSY ) return DID_BUS_BUSY << 16; error = inb_p (padapter->regError); DEB(printk ("\npci2220i error register: %x", error)); switch ( error ) { case IDE_ERROR_AMNF: case IDE_ERROR_TKONF: case IDE_ERROR_ABRT: case IDE_ERROR_IDFN: case IDE_ERROR_UNC: case IDE_ERROR_BBK: default: return DID_ERROR << 16; } return DID_ERROR << 16; }/**************************************************************** * Name: StartTimer :LOCAL * * Description: Start the timer. * * Parameters: ipadapter - Pointer adapter data structure. * * Returns: Nothing. * ****************************************************************/static void StartTimer (PADAPTER2220I padapter) { padapter->timer.expires = jiffies + TIMEOUT_DATA; add_timer (&padapter->timer); }/**************************************************************** * Name: WriteSignature :LOCAL * * Description: Start the timer. * * Parameters: padapter - Pointer adapter data structure. * pdev - Pointer to our device. * spigot - Selected spigot. * index - index of mirror signature on device. * * Returns: TRUE on any error. * ****************************************************************/static int WriteSignature (PADAPTER2220I padapter, POUR_DEVICE pdev, UCHAR spigot, int index) { ULONG zl; SelectSpigot (padapter, spigot); zl = pdev->lastsectorlba[index]; outb_p (pdev->byte6 | ((UCHAR *)&zl)[3], padapter->regLba24); outb_p (((UCHAR *)&zl)[2], padapter->regLba16); outb_p (((UCHAR *)&zl)[1], padapter->regLba8); outb_p (((UCHAR *)&zl)[0], padapter->regLba0); outb_p (1, padapter->regSectCount); WriteCommand (padapter, IDE_COMMAND_WRITE); if ( WaitDrq (padapter) ) return TRUE; StartTimer (padapter); padapter->expectingIRQ = TRUE; ((ULONG *)(&padapter->kBuffer[DISK_MIRROR_POSITION]))[0] = ((ULONG *)(&pdev->DiskMirror[index]))[0]; ((ULONG *)(&padapter->kBuffer[DISK_MIRROR_POSITION]))[1] = ((ULONG *)(&pdev->DiskMirror[index]))[1]; outsw (padapter->regData, padapter->kBuffer, BYTES_PER_SECTOR / 2); return FALSE; }/******************************************************************************************************* * Name: InitFailover * * Description: This is the beginning of the failover routine * * Parameters: SCpnt - Pointer to SCSI command structure. * padapter - Pointer adapter data structure. * pdev - Pointer to our device. * * Returns: TRUE on error. * ******************************************************************************************************/static int InitFailover (PADAPTER2220I padapter, POUR_DEVICE pdev) { UCHAR spigot; DEB (printk ("\npci2220i: Initialize failover process - survivor = %d", pdev->deviceID[padapter->survivor])); pdev->raid = FALSE; //initializes system for non raid mode pdev->reconOn = FALSE; spigot = pdev->spigots[padapter->survivor]; if ( pdev->DiskMirror[padapter->survivor].status & UCBF_REBUILD ) { DEB (printk ("\n failed, is survivor")); return (TRUE); } if ( HardReset (padapter, pdev, spigot) ) { DEB (printk ("\n failed, reset")); return TRUE; } Alarm (padapter, pdev->deviceID[padapter->survivor ^ 1]); pdev->DiskMirror[padapter->survivor].status = UCBF_MIRRORED | UCBF_SURVIVOR; //clear present status if ( WriteSignature (padapter, pdev, spigot, padapter->survivor) ) { DEB (printk ("\n failed, write signature")); return TRUE; } padapter->failinprog = TRUE; return FALSE; }/**************************************************************** * Name: TimerExpiry :LOCAL * * Description: Timer expiry routine. * * Parameters: data - Pointer adapter data structure. * * Returns: Nothing. * ****************************************************************/static void TimerExpiry (unsigned long data) { PADAPTER2220I padapter = (PADAPTER2220I)data; POUR_DEVICE pdev = padapter->pdev; UCHAR status = IDE_STATUS_BUSY; UCHAR temp, temp1; 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: Timeout expired ")); if ( padapter->failinprog ) { DEB (printk ("in failover process")); OpDone (padapter, DecodeError (padapter, inb_p (padapter->regStatCmd))); goto timerExpiryDone; } while ( padapter->reconPhase ) { DEB (printk ("in recon phase %X", padapter->reconPhase)); switch ( padapter->reconPhase ) { case RECON_PHASE_MARKING: case RECON_PHASE_LAST: padapter->survivor = ( pdev->spigot == pdev->spigots[0] ) ? 1 : 0; DEB (printk ("\npci2220i: FAILURE 1")); if ( InitFailover (padapter, pdev) ) OpDone (padapter, DID_ERROR << 16); goto timerExpiryDone; case RECON_PHASE_READY: OpDone (padapter, DID_ERROR << 16); goto timerExpiryDone; case RECON_PHASE_COPY: padapter->survivor = ( pdev->spigot == pdev->spigots[0] ) ? 0 : 1; DEB (printk ("\npci2220i: FAILURE 2")); DEB (printk ("\n spig/stat = %X", inb_p (padapter->regStatSel)); if ( InitFailover (padapter, pdev) ) OpDone (padapter, DID_ERROR << 16); goto timerExpiryDone; case RECON_PHASE_UPDATE: padapter->survivor = ( pdev->spigot == pdev->spigots[0] ) ? 0 : 1; DEB (printk ("\npci2220i: FAILURE 3"))); if ( InitFailover (padapter, pdev) ) OpDone (padapter, DID_ERROR << 16); goto timerExpiryDone; case RECON_PHASE_END: padapter->survivor = ( pdev->spigot == pdev->spigots[0] ) ? 0 : 1; DEB (printk ("\npci2220i: FAILURE 4")); if ( InitFailover (padapter, pdev) ) OpDone (padapter, DID_ERROR << 16); goto timerExpiryDone; default: goto timerExpiryDone; } } while ( padapter->cmd ) { outb_p (0x08, padapter->regDmaCmdStat); // cancel interrupt from DMA engine if ( pdev->raid ) { if ( padapter->cmd == WRITE_CMD ) { DEB (printk ("in RAID write operation")); temp = ( pdev->spigot & (SEL_1 | SEL_2) ) ? SEL_1 : SEL_3; if ( inb_p (padapter->regStatSel) & temp ) { DEB (printk ("\npci2220i: Determined A OK")); SelectSpigot (padapter, temp | SEL_IRQ_OFF); // Masking the interrupt during spigot select temp = inb_p (padapter->regStatCmd); } else temp = IDE_STATUS_BUSY; temp1 = ( pdev->spigot & (SEL_1 | SEL_2) ) ? SEL_2 : SEL_4; if ( inb (padapter->regStatSel) & temp1 ) { DEB (printk ("\npci2220i: Determined B OK")); SelectSpigot (padapter, temp1 | SEL_IRQ_OFF); // Masking the interrupt during spigot select temp1 = inb_p (padapter->regStatCmd); } else temp1 = IDE_STATUS_BUSY; if ( (temp & IDE_STATUS_BUSY) || (temp1 & IDE_STATUS_BUSY) ) { DEB (printk ("\npci2220i: Status A: %X B: %X", temp & 0xFF, temp1 & 0xFF)); if ( (temp & IDE_STATUS_BUSY) && (temp1 & IDE_STATUS_BUSY) ) { status = temp; break; } else { if ( temp & IDE_STATUS_BUSY ) padapter->survivor = 1; else padapter->survivor = 0; if ( InitFailover (padapter, pdev) ) { status = inb_p (padapter->regStatCmd); break; } goto timerExpiryDone; } } } else { DEB (printk ("in RAID read operation")); padapter->survivor = ( pdev->spigot == pdev->spigots[0] ) ? 0 : 1; DEB (printk ("\npci2220i: FAILURE 6")); if ( InitFailover (padapter, pdev) ) { status = inb_p (padapter->regStatCmd); break; } goto timerExpiryDone; } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -