📄 isd200.c
字号:
{ US_DEBUGP(" Event Notification: 0x%x\n", info->ConfigData.EventNotification); US_DEBUGP(" External Clock: 0x%x\n", info->ConfigData.ExternalClock); US_DEBUGP(" ATA Init Timeout: 0x%x\n", info->ConfigData.ATAInitTimeout); US_DEBUGP(" ATAPI Command Block Size: 0x%x\n", (info->ConfigData.ATAConfig & ATACFG_BLOCKSIZE) >> 6); US_DEBUGP(" Master/Slave Selection: 0x%x\n", info->ConfigData.ATAConfig & ATACFG_MASTER); US_DEBUGP(" ATAPI Reset: 0x%x\n", info->ConfigData.ATAConfig & ATACFG_ATAPI_RESET); US_DEBUGP(" ATA Timing: 0x%x\n", info->ConfigData.ATAConfig & ATACFG_TIMING); US_DEBUGP(" ATA Major Command: 0x%x\n", info->ConfigData.ATAMajorCommand); US_DEBUGP(" ATA Minor Command: 0x%x\n", info->ConfigData.ATAMinorCommand); US_DEBUGP(" Init Status: 0x%x\n", info->ConfigData.ATAExtraConfig & ATACFGE_INIT_STATUS); US_DEBUGP(" Config Descriptor 2: 0x%x\n", info->ConfigData.ATAExtraConfig & ATACFGE_CONF_DESC2); US_DEBUGP(" Skip Device Boot: 0x%x\n", info->ConfigData.ATAExtraConfig & ATACFGE_SKIP_BOOT); US_DEBUGP(" ATA 3 State Supsend: 0x%x\n", info->ConfigData.ATAExtraConfig & ATACFGE_STATE_SUSPEND); US_DEBUGP(" Descriptor Override: 0x%x\n", info->ConfigData.ATAExtraConfig & ATACFGE_DESC_OVERRIDE); US_DEBUGP(" Last LUN Identifier: 0x%x\n", info->ConfigData.ATAExtraConfig & ATACFGE_LAST_LUN); US_DEBUGP(" SRST Enable: 0x%x\n", info->ConfigData.ATAExtraConfig & CFG_CAPABILITY_SRST);}#endif/************************************************************************** * isd200_write_config * * Write the ISD200 Configuraton data * * RETURNS: * ISD status code */ int isd200_write_config( struct us_data *us ) { struct isd200_info *info = (struct isd200_info *)us->extra; int retStatus = ISD200_GOOD; int result;#ifdef CONFIG_USB_STORAGE_DEBUG US_DEBUGP("Entering isd200_write_config\n"); US_DEBUGP(" Writing the following ISD200 Config Data:\n"); isd200_log_config(info);#endif /* let's send the command via the control pipe */ result = usb_stor_control_msg( us, usb_sndctrlpipe(us->pusb_dev,0), 0x01, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT, 0x0000, 0x0002, (void *) &info->ConfigData, sizeof(info->ConfigData)); if (result >= 0) { US_DEBUGP(" ISD200 Config Data was written successfully\n"); } else { US_DEBUGP(" Request to write ISD200 Config Data failed!\n"); /* STALL must be cleared when they are detected */ if (result == -EPIPE) { US_DEBUGP("-- Stall on control pipe. Clearing\n"); result = usb_stor_clear_halt(us, usb_sndctrlpipe(us->pusb_dev, 0)); US_DEBUGP("-- usb_stor_clear_halt() returns %d\n", result); } retStatus = ISD200_ERROR; } US_DEBUGP("Leaving isd200_write_config %08X\n", retStatus); return retStatus;}/************************************************************************** * isd200_read_config * * Reads the ISD200 Configuraton data * * RETURNS: * ISD status code */ int isd200_read_config( struct us_data *us ) { struct isd200_info *info = (struct isd200_info *)us->extra; int retStatus = ISD200_GOOD; int result; US_DEBUGP("Entering isd200_read_config\n"); /* read the configuration information from ISD200. Use this to */ /* determine what the special ATA CDB bytes are. */ result = usb_stor_control_msg( us, usb_rcvctrlpipe(us->pusb_dev,0), 0x02, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, 0x0000, 0x0002, (void *) &info->ConfigData, sizeof(info->ConfigData)); if (result >= 0) { US_DEBUGP(" Retrieved the following ISD200 Config Data:\n");#ifdef CONFIG_USB_STORAGE_DEBUG isd200_log_config(info);#endif } else { US_DEBUGP(" Request to get ISD200 Config Data failed!\n"); /* STALL must be cleared when they are detected */ if (result == -EPIPE) { US_DEBUGP("-- Stall on control pipe. Clearing\n"); result = usb_stor_clear_halt(us, usb_sndctrlpipe(us->pusb_dev, 0)); US_DEBUGP("-- usb_stor_clear_halt() returns %d\n", result); } retStatus = ISD200_ERROR; } US_DEBUGP("Leaving isd200_read_config %08X\n", retStatus); return retStatus;}/************************************************************************** * isd200_atapi_soft_reset * * Perform an Atapi Soft Reset on the device * * RETURNS: * NT status code */ int isd200_atapi_soft_reset( struct us_data *us ) { int retStatus = ISD200_GOOD; int transferStatus; US_DEBUGP("Entering isd200_atapi_soft_reset\n"); transferStatus = isd200_action( us, ACTION_SOFT_RESET, NULL, 0 ); if (transferStatus != ISD200_TRANSPORT_GOOD) { US_DEBUGP(" Error issuing Atapi Soft Reset\n"); retStatus = ISD200_ERROR; } US_DEBUGP("Leaving isd200_atapi_soft_reset %08X\n", retStatus); return retStatus;}/************************************************************************** * isd200_srst * * Perform an SRST on the device * * RETURNS: * ISD status code */ int isd200_srst( struct us_data *us ) { int retStatus = ISD200_GOOD; int transferStatus; US_DEBUGP("Entering isd200_SRST\n"); transferStatus = isd200_action( us, ACTION_RESET, NULL, 0 ); /* check to see if this request failed */ if (transferStatus != ISD200_TRANSPORT_GOOD) { US_DEBUGP(" Error issuing SRST\n"); retStatus = ISD200_ERROR; } else { /* delay 10ms to give the drive a chance to see it */ wait_ms(10); transferStatus = isd200_action( us, ACTION_REENABLE, NULL, 0 ); if (transferStatus != ISD200_TRANSPORT_GOOD) { US_DEBUGP(" Error taking drive out of reset\n"); retStatus = ISD200_ERROR; } else { /* delay 50ms to give the drive a chance to recover after SRST */ wait_ms(50); } } US_DEBUGP("Leaving isd200_srst %08X\n", retStatus); return retStatus;}/************************************************************************** * isd200_try_enum * * Helper function for isd200_manual_enum(). Does ENUM and READ_STATUS * and tries to analyze the status registers * * RETURNS: * ISD status code */ static int isd200_try_enum(struct us_data *us, unsigned char master_slave, int detect ){ int status = ISD200_GOOD; unsigned char regs[8]; unsigned long endTime; struct isd200_info *info = (struct isd200_info *)us->extra; int recheckAsMaster = FALSE; if ( detect ) endTime = jiffies + ISD200_ENUM_DETECT_TIMEOUT * HZ; else endTime = jiffies + ISD200_ENUM_BSY_TIMEOUT * HZ; /* loop until we detect !BSY or timeout */ while(TRUE) {#ifdef CONFIG_USB_STORAGE_DEBUG char* mstr = master_slave == ATA_ADDRESS_DEVHEAD_STD ? "Master" : "Slave";#endif status = isd200_action( us, ACTION_ENUM, NULL, master_slave ); if ( status != ISD200_GOOD ) break; status = isd200_action( us, ACTION_READ_STATUS, regs, sizeof(regs) ); if ( status != ISD200_GOOD ) break; if (!detect) { if (regs[IDE_STATUS_OFFSET] & BUSY_STAT ) { US_DEBUGP(" %s status is still BSY, try again...\n",mstr); } else { US_DEBUGP(" %s status !BSY, continue with next operation\n",mstr); break; } } /* check for BUSY_STAT and */ /* WRERR_STAT (workaround ATA Zip drive) and */ /* ERR_STAT (workaround for Archos CD-ROM) */ else if (regs[IDE_STATUS_OFFSET] & (BUSY_STAT | WRERR_STAT | ERR_STAT )) { US_DEBUGP(" Status indicates it is not ready, try again...\n"); } /* check for DRDY, ATA devices set DRDY after SRST */ else if (regs[IDE_STATUS_OFFSET] & READY_STAT) { US_DEBUGP(" Identified ATA device\n"); info->DeviceFlags |= DF_ATA_DEVICE; info->DeviceHead = master_slave; break; } /* check Cylinder High/Low to determine if it is an ATAPI device */ else if ((regs[IDE_HCYL_OFFSET] == 0xEB) && (regs[IDE_LCYL_OFFSET] == 0x14)) { /* It seems that the RICOH MP6200A CD/RW drive will report itself okay as a slave when it is really a master. So this check again as a master device just to make sure it doesn't report itself okay as a master also */ if ((master_slave & ATA_ADDRESS_DEVHEAD_SLAVE) && (recheckAsMaster == FALSE)) { US_DEBUGP(" Identified ATAPI device as slave. Rechecking again as master\n"); recheckAsMaster = TRUE; master_slave = ATA_ADDRESS_DEVHEAD_STD; } else { US_DEBUGP(" Identified ATAPI device\n"); info->DeviceHead = master_slave; status = isd200_atapi_soft_reset(us); break; } } else { US_DEBUGP(" Not ATA, not ATAPI. Weird.\n"); break; } /* check for timeout on this request */ if (time_after_eq(jiffies, endTime)) { if (!detect) US_DEBUGP(" BSY check timeout, just continue with next operation...\n"); else US_DEBUGP(" Device detect timeout!\n"); break; } } return status;}/************************************************************************** * isd200_manual_enum * * Determines if the drive attached is an ATA or ATAPI and if it is a * master or slave. * * RETURNS: * ISD status code */ int isd200_manual_enum(struct us_data *us){ struct isd200_info *info = (struct isd200_info *)us->extra; int retStatus = ISD200_GOOD; US_DEBUGP("Entering isd200_manual_enum\n"); retStatus = isd200_read_config(us); if (retStatus == ISD200_GOOD) { int isslave; /* master or slave? */ retStatus = isd200_try_enum( us, ATA_ADDRESS_DEVHEAD_STD, FALSE ); if (retStatus == ISD200_GOOD) retStatus = isd200_try_enum( us, ATA_ADDRESS_DEVHEAD_SLAVE, FALSE ); if (retStatus == ISD200_GOOD) { retStatus = isd200_srst(us); if (retStatus == ISD200_GOOD) /* ata or atapi? */ retStatus = isd200_try_enum( us, ATA_ADDRESS_DEVHEAD_STD, TRUE ); } isslave = (info->DeviceHead & ATA_ADDRESS_DEVHEAD_SLAVE) ? 1 : 0; if (!(info->ConfigData.ATAConfig & ATACFG_MASTER)) { US_DEBUGP(" Setting Master/Slave selection to %d\n", isslave); info->ConfigData.ATAConfig &= 0x3f; info->ConfigData.ATAConfig |= (isslave<<6); retStatus = isd200_write_config(us); } } US_DEBUGP("Leaving isd200_manual_enum %08X\n", retStatus); return(retStatus);}/************************************************************************** * isd200_get_inquiry_data * * Get inquiry data * * RETURNS: * ISD status code */int isd200_get_inquiry_data( struct us_data *us ){ struct isd200_info *info = (struct isd200_info *)us->extra; int retStatus = ISD200_GOOD; US_DEBUGP("Entering isd200_get_inquiry_data\n"); /* set default to Master */ info->DeviceHead = ATA_ADDRESS_DEVHEAD_STD; /* attempt to manually enumerate this device */ retStatus = isd200_manual_enum(us); if (retStatus == ISD200_GOOD) { int transferStatus; /* check for an ATA device */ if (info->DeviceFlags & DF_ATA_DEVICE) { /* this must be an ATA device */ /* perform an ATA Commmand Identify */ transferStatus = isd200_action( us, ACTION_IDENTIFY, &info->drive, sizeof(struct hd_driveid) ); if (transferStatus != ISD200_TRANSPORT_GOOD) { /* Error issuing ATA Command Identify */ US_DEBUGP(" Error issuing ATA Command Identify\n"); retStatus = ISD200_ERROR; } else { /* ATA Command Identify successful */ int i; __u16 *src, *dest; ide_fix_driveid(&info->drive); US_DEBUGP(" Identify Data Structure:\n"); US_DEBUGP(" config = 0x%x\n", info->drive.config); US_DEBUGP(" cyls = 0x%x\n", info->drive.cyls); US_DEBUGP(" heads = 0x%x\n", info->drive.heads); US_DEBUGP(" track_bytes = 0x%x\n", info->drive.track_bytes); US_DEBUGP(" sector_bytes = 0x%x\n", info->drive.sector_bytes); US_DEBUGP(" sectors = 0x%x\n", info->drive.sectors); US_DEBUGP(" serial_no[0] = 0x%x\n", info->drive.serial_no[0]); US_DEBUGP(" buf_type = 0x%x\n", info->drive.buf_type); US_DEBUGP(" buf_size = 0x%x\n", info->drive.buf_size); US_DEBUGP(" ecc_bytes = 0x%x\n", info->drive.ecc_bytes); US_DEBUGP(" fw_rev[0] = 0x%x\n", info->drive.fw_rev[0]); US_DEBUGP(" model[0] = 0x%x\n", info->drive.model[0]); US_DEBUGP(" max_multsect = 0x%x\n", info->drive.max_multsect); US_DEBUGP(" dword_io = 0x%x\n", info->drive.dword_io); US_DEBUGP(" capability = 0x%x\n", info->drive.capability); US_DEBUGP(" tPIO = 0x%x\n", info->drive.tPIO); US_DEBUGP(" tDMA = 0x%x\n", info->drive.tDMA); US_DEBUGP(" field_valid = 0x%x\n", info->drive.field_valid); US_DEBUGP(" cur_cyls = 0x%x\n", info->drive.cur_cyls); US_DEBUGP(" cur_heads = 0x%x\n", info->drive.cur_heads); US_DEBUGP(" cur_sectors = 0x%x\n", info->drive.cur_sectors); US_DEBUGP(" cur_capacity = 0x%x\n", (info->drive.cur_capacity1 << 16) + info->drive.cur_capacity0 ); US_DEBUGP(" multsect = 0x%x\n", info->drive.multsect); US_DEBUGP(" lba_capacity = 0x%x\n", info->drive.lba_capacity); US_DEBUGP(" command_set_1 = 0x%x\n", info->drive.command_set_1); US_DEBUGP(" command_set_2 = 0x%x\n", info->drive.command_set_2); memset(&info->InquiryData, 0, sizeof(info->InquiryData)); /* Standard IDE interface only supports disks */ info->InquiryData.DeviceType = DIRECT_ACCESS_DEVICE; /* Fix-up the return data from an INQUIRY command to show
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -