📄 pci2220i.c
字号:
} else { DEB (printk ("\npci2220i: restarting failed opertation.")); pdev->spigot = (padapter->survivor) ? pdev->spigots[1] : pdev->spigots[0]; del_timer (&padapter->timer); if ( padapter->reconPhase ) OpDone (padapter, DID_OK << 16); else Pci2220i_QueueCommand (SCpnt, SCpnt->scsi_done); goto irq_return; } } if ( padapter->reconPhase ) { switch ( padapter->reconPhase ) { case RECON_PHASE_MARKING: case RECON_PHASE_LAST: status = inb_p (padapter->regStatCmd); // read the device status del_timer (&padapter->timer); if ( padapter->reconPhase == RECON_PHASE_LAST ) { if ( status & (IDE_STATUS_ERROR | IDE_STATUS_WRITE_FAULT) ) { padapter->survivor = ( pdev->spigot == pdev->spigots[0] ) ? 1 : 0; DEB (printk ("\npci2220i: FAILURE 10")); if ( InitFailover (padapter, pdev) ) OpDone (padapter, DecodeError (padapter, status)); goto irq_return; } if ( WriteSignature (padapter, pdev, pdev->spigots[pdev->mirrorRecon], pdev->mirrorRecon) ) { padapter->survivor = ( pdev->spigot == pdev->spigots[0] ) ? 0 : 1; DEB (printk ("\npci2220i: FAILURE 11")); if ( InitFailover (padapter, pdev) ) OpDone (padapter, DecodeError (padapter, status)); goto irq_return; } padapter->reconPhase = RECON_PHASE_END; goto irq_return; } OpDone (padapter, DID_OK << 16); goto irq_return; case RECON_PHASE_READY: status = inb_p (padapter->regStatCmd); // read the device status if ( status & (IDE_STATUS_ERROR | IDE_STATUS_WRITE_FAULT) ) { del_timer (&padapter->timer); OpDone (padapter, DecodeError (padapter, status)); goto irq_return; } SelectSpigot (padapter, pdev->spigots[pdev->mirrorRecon]); if ( WaitDrq (padapter) ) { del_timer (&padapter->timer); padapter->survivor = ( pdev->spigot == pdev->spigots[0] ) ? 0 : 1; DEB (printk ("\npci2220i: FAILURE 12")); if ( InitFailover (padapter, pdev) ) OpDone (padapter, DecodeError (padapter, status)); goto irq_return; } SelectSpigot (padapter, pdev->spigot | SEL_COPY | padapter->bigD); padapter->reconPhase = RECON_PHASE_COPY; padapter->expectingIRQ = TRUE; if ( padapter->timingPIO ) { insw (padapter->regData, padapter->kBuffer, padapter->reconSize * (BYTES_PER_SECTOR / 2)); } else { if ( (padapter->timingMode > 3) ) { if ( padapter->bigD ) outl (BIGD_DATA_MODE3, padapter->regDmaAddrLoc); else outl (DALE_DATA_MODE3, padapter->regDmaAddrLoc); } else outl (padapter->timingAddress, padapter->regDmaAddrLoc); outl (padapter->kBufferDma, padapter->regDmaAddrPci); outl (padapter->reconSize * BYTES_PER_SECTOR, padapter->regDmaCount); outb_p (8, padapter->regDmaDesc); // read operation if ( padapter->bigD ) outb_p (8, padapter->regDmaMode); // no interrupt else outb_p (1, padapter->regDmaMode); // no interrupt outb_p (0x03, padapter->regDmaCmdStat); // kick the DMA engine in gear } goto irq_return; case RECON_PHASE_COPY: pdev->DiskMirror[pdev->mirrorRecon].reconstructPoint += padapter->reconSize; case RECON_PHASE_UPDATE: SelectSpigot (padapter, pdev->spigots[pdev->mirrorRecon] | SEL_IRQ_OFF); status = inb_p (padapter->regStatCmd); // read the device status del_timer (&padapter->timer); if ( status & (IDE_STATUS_ERROR | IDE_STATUS_WRITE_FAULT) ) { padapter->survivor = ( pdev->spigot == pdev->spigots[0] ) ? 0 : 1; DEB (printk ("\npci2220i: FAILURE 13")); DEB (printk ("\n status register = %X error = %X", status, inb_p (padapter->regError))); if ( InitFailover (padapter, pdev) ) OpDone (padapter, DecodeError (padapter, status)); goto irq_return; } OpDone (padapter, DID_OK << 16); goto irq_return; case RECON_PHASE_END: status = inb_p (padapter->regStatCmd); // read the device status del_timer (&padapter->timer); if ( status & (IDE_STATUS_ERROR | IDE_STATUS_WRITE_FAULT) ) { padapter->survivor = ( pdev->spigot == pdev->spigots[0] ) ? 0 : 1; DEB (printk ("\npci2220i: FAILURE 14")); if ( InitFailover (padapter, pdev) ) OpDone (padapter, DecodeError (padapter, status)); goto irq_return; } pdev->reconOn = 0; if ( padapter->bigD ) { for ( z = 0; z < padapter->numberOfDrives; z++ ) { if ( padapter->device[z].DiskMirror[0].status & UCBF_SURVIVOR ) { Alarm (padapter, padapter->device[z].deviceID[0] ^ 2); MuteAlarm (padapter); } if ( padapter->device[z].DiskMirror[1].status & UCBF_SURVIVOR ) { Alarm (padapter, padapter->device[z].deviceID[1] ^ 2); MuteAlarm (padapter); } } } OpDone (padapter, DID_OK << 16); goto irq_return; default: goto irq_return; } } switch ( padapter->cmd ) // decide how to handle the interrupt { case READ_CMD: if ( padapter->sectorCount ) { status = inb_p (padapter->regStatCmd); // read the device status if ( status & (IDE_STATUS_ERROR | IDE_STATUS_WRITE_FAULT) ) { if ( pdev->raid ) { padapter->survivor = ( pdev->spigot == pdev->spigots[0] ) ? 1 : 0; del_timer (&padapter->timer); DEB (printk ("\npci2220i: FAILURE 15")); if ( !InitFailover (padapter, pdev) ) goto irq_return; } break; } if ( padapter->timingPIO ) { insw (padapter->regData, padapter->kBuffer, padapter->readCount / 2); padapter->sectorCount -= padapter->readCount / BYTES_PER_SECTOR; WalkScatGath (padapter, TRUE, padapter->readCount); if ( !padapter->sectorCount ) { status = 0; break; } } else { if ( padapter->readCount ) WalkScatGath (padapter, TRUE, padapter->readCount); BusMaster (padapter, 1, 1); } padapter->expectingIRQ = TRUE; goto irq_return; } if ( padapter->readCount && !padapter->timingPIO ) WalkScatGath (padapter, TRUE, padapter->readCount); status = 0; break; case WRITE_CMD: if ( pdev->raid ) { SelectSpigot (padapter, pdev->spigots[0] | SEL_IRQ_OFF); status = inb_p (padapter->regStatCmd); // read the device status SelectSpigot (padapter, pdev->spigots[1] | SEL_IRQ_OFF); status1 = inb_p (padapter->regStatCmd); // read the device status } else SelectSpigot (padapter, pdev->spigot | SEL_IRQ_OFF); status = inb_p (padapter->regStatCmd); // read the device status status1 = 0; if ( status & (IDE_STATUS_ERROR | IDE_STATUS_WRITE_FAULT) ) { if ( pdev->raid && !(status1 & (IDE_STATUS_ERROR | IDE_STATUS_WRITE_FAULT)) ) { padapter->survivor = 1; del_timer (&padapter->timer); SelectSpigot (padapter, pdev->spigot | SEL_IRQ_OFF); DEB (printk ("\npci2220i: FAILURE 16 status = %X error = %X", status, inb_p (padapter->regError))); if ( !InitFailover (padapter, pdev) ) goto irq_return; } break; } if ( pdev->raid ) { if ( status1 & (IDE_STATUS_ERROR | IDE_STATUS_WRITE_FAULT) ) { padapter->survivor = 0; del_timer (&padapter->timer); DEB (printk ("\npci2220i: FAILURE 17 status = %X error = %X", status1, inb_p (padapter->regError))); if ( !InitFailover (padapter, pdev) ) goto irq_return; status = status1; break; } if ( padapter->sectorCount ) { status = WriteDataBoth (padapter, pdev); if ( status ) { padapter->survivor = status >> 1; del_timer (&padapter->timer); DEB (printk ("\npci2220i: FAILURE 18")); if ( !InitFailover (padapter, pdev) ) goto irq_return; SelectSpigot (padapter, pdev->spigots[status] | SEL_IRQ_OFF); status = inb_p (padapter->regStatCmd); // read the device status break; } padapter->expectingIRQ = TRUE; goto irq_return; } status = 0; break; } if ( padapter->sectorCount ) { SelectSpigot (padapter, pdev->spigot | padapter->bigD); status = WriteData (padapter); if ( status ) break; padapter->expectingIRQ = TRUE; goto irq_return; } status = 0; break; case IDE_COMMAND_IDENTIFY: { PINQUIRYDATA pinquiryData = SCpnt->request_buffer; PIDENTIFY_DATA pid = (PIDENTIFY_DATA)padapter->kBuffer; status = inb_p (padapter->regStatCmd); if ( status & IDE_STATUS_DRQ ) { insw (padapter->regData, pid, sizeof (IDENTIFY_DATA) >> 1); memset (pinquiryData, 0, SCpnt->request_bufflen); // Zero INQUIRY data structure. pinquiryData->DeviceType = 0; pinquiryData->Versions = 2; pinquiryData->AdditionalLength = 35 - 4; // Fill in vendor identification fields. for ( z = 0; z < 20; z += 2 ) { pinquiryData->VendorId[z] = ((UCHAR *)pid->ModelNumber)[z + 1]; pinquiryData->VendorId[z + 1] = ((UCHAR *)pid->ModelNumber)[z]; } // Initialize unused portion of product id. for ( z = 0; z < 4; z++ ) pinquiryData->ProductId[12 + z] = ' '; // Move firmware revision from IDENTIFY data to // product revision in INQUIRY data. for ( z = 0; z < 4; z += 2 ) { pinquiryData->ProductRevisionLevel[z] = ((UCHAR *)pid->FirmwareRevision)[z + 1]; pinquiryData->ProductRevisionLevel[z + 1] = ((UCHAR *)pid->FirmwareRevision)[z]; } if ( pdev == padapter->device ) *((USHORT *)(&pinquiryData->VendorSpecific)) = DEVICE_DALE_1; status = 0; } break; } default: status = 0; break; } del_timer (&padapter->timer); if ( status ) { DEB (printk ("\npci2220i Interupt hanlder return error")); zl = DecodeError (padapter, status); } else zl = DID_OK << 16; OpDone (padapter, zl);irq_return:; /* * 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: Pci2220i_QueueCommand * * Description: Process a queued command from the SCSI manager. * * Parameters: SCpnt - Pointer to SCSI command structure. * done - Pointer to done function to call. * * Returns: Status code. * ****************************************************************/int Pci2220i_QueueCommand (Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) { UCHAR *cdb = (UCHAR *)SCpnt->cmnd; // Pointer to SCSI CDB PADAPTER2220I padapter = HOSTDATA(SCpnt->host); // Pointer to adapter control structure POUR_DEVICE pdev = &padapter->device[SCpnt->target];// Pointer to device information UCHAR rc; // command return code int z; PDEVICE_RAID1 pdr; SCpnt->scsi_done = done; padapter->SCpnt = SCpnt; // Save this command data padapter->readCount = 0; if ( SCpnt->use_sg ) { padapter->currentSgBuffer = ((struct scatterlist *)SCpnt->request_buffer)[0].address; padapter->currentSgCount = ((struct scatterlist *)SCpnt->request_buffer)[0].length; } else { padapter->currentSgBuffer = SCpnt->request_buffer; padapter->currentSgCount = SCpnt->request_bufflen; } padapter->nextSg = 1; if ( !done ) { printk("pci2220i_queuecommand: %02X: done can't be NULL\n", *cdb); return 0; } if ( padapter->atapi ) { UCHAR zlo, zhi; DEB (printk ("\nPCI2242I: ID %d, LUN %d opcode %X ", SCpnt->target, SCpnt->lun, *cdb)); padapter->pdev = pdev; if ( !pdev->byte6 || SCpnt->lun ) { OpDone (padapter, DID_BAD_TARGET << 16); return 0; } padapter->atapiSpecial = FALSE; padapter->reqSense = FALSE; memset (padapter->atapiCdb, 0, 16); SelectSpigot (padapter, pdev->spigot); // select the spigot AtapiDevice (padapter, pdev->byte6); // select the drive if ( AtapiWaitReady (padapter, 100) ) { OpDone (padapter, DID_NO_CONNECT << 16); return 0; } switch ( cdb[0] ) { case SCSIOP_MODE_SENSE: case SCSIOP_MODE_SELECT: Scsi2Atapi (padapter, SCpnt); z = SCpnt->request_bufflen + 4; break; case SCSIOP_READ6: case SCSIOP_WRITE6: Scsi2Atapi (padapter, SCpnt); z = SCpnt->request_bufflen; break; default: memcpy (padapter->atapiCdb, cdb, SCpnt->cmd_len); z = SCpnt->request_bufflen; break; } if ( z > ATAPI_TRANSFER ) z = ATAPI_TRANSFER; zlo = (UCHAR)(z & 0xFF); zhi = (UCHAR)(z >> 8); AtapiCountLo (padapter, zlo); AtapiCountHi (padapter, zhi); outb_p (0, padapter->regError); WriteCommand (padapter, IDE_COMMAND_ATAPI_PACKET); if ( pdev->cmdDrqInt ) return 0; if ( AtapiWaitDrq (padapter, 500) ) { OpDone (padapter, DID_ERROR << 16); return 0; } A
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -