⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 isd200.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
static 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 */static 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 */		msleep(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 */			msleep(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 long endTime;	struct isd200_info *info = (struct isd200_info *)us->extra;	unsigned char *regs = info->RegsBuf;	int recheckAsMaster = 0;	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(1) {#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, 8 );		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) {				US_DEBUGP("   Identified ATAPI device as slave.  Rechecking again as master\n");				recheckAsMaster = 1;				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 */static 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, 0);		if (retStatus == ISD200_GOOD)			retStatus = isd200_try_enum( us, ATA_ADDRESS_DEVHEAD_SLAVE, 0);		if (retStatus == ISD200_GOOD) {			retStatus = isd200_srst(us);			if (retStatus == ISD200_GOOD)				/* ata or atapi? */				retStatus = isd200_try_enum( us, ATA_ADDRESS_DEVHEAD_STD, 1);		}		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);}/* *	We are the last non IDE user of the legacy IDE ident structures *	and we thus want to keep a private copy of this function so the *	driver can be used without the obsolete drivers/ide layer */static void isd200_fix_driveid (struct hd_driveid *id){#ifndef __LITTLE_ENDIAN# ifdef __BIG_ENDIAN	int i;	u16 *stringcast;	id->config         = __le16_to_cpu(id->config);	id->cyls           = __le16_to_cpu(id->cyls);	id->reserved2      = __le16_to_cpu(id->reserved2);	id->heads          = __le16_to_cpu(id->heads);	id->track_bytes    = __le16_to_cpu(id->track_bytes);	id->sector_bytes   = __le16_to_cpu(id->sector_bytes);	id->sectors        = __le16_to_cpu(id->sectors);	id->vendor0        = __le16_to_cpu(id->vendor0);	id->vendor1        = __le16_to_cpu(id->vendor1);	id->vendor2        = __le16_to_cpu(id->vendor2);	stringcast = (u16 *)&id->serial_no[0];	for (i = 0; i < (20/2); i++)		stringcast[i] = __le16_to_cpu(stringcast[i]);	id->buf_type       = __le16_to_cpu(id->buf_type);	id->buf_size       = __le16_to_cpu(id->buf_size);	id->ecc_bytes      = __le16_to_cpu(id->ecc_bytes);	stringcast = (u16 *)&id->fw_rev[0];	for (i = 0; i < (8/2); i++)		stringcast[i] = __le16_to_cpu(stringcast[i]);	stringcast = (u16 *)&id->model[0];	for (i = 0; i < (40/2); i++)		stringcast[i] = __le16_to_cpu(stringcast[i]);	id->dword_io       = __le16_to_cpu(id->dword_io);	id->reserved50     = __le16_to_cpu(id->reserved50);	id->field_valid    = __le16_to_cpu(id->field_valid);	id->cur_cyls       = __le16_to_cpu(id->cur_cyls);	id->cur_heads      = __le16_to_cpu(id->cur_heads);	id->cur_sectors    = __le16_to_cpu(id->cur_sectors);	id->cur_capacity0  = __le16_to_cpu(id->cur_capacity0);	id->cur_capacity1  = __le16_to_cpu(id->cur_capacity1);	id->lba_capacity   = __le32_to_cpu(id->lba_capacity);	id->dma_1word      = __le16_to_cpu(id->dma_1word);	id->dma_mword      = __le16_to_cpu(id->dma_mword);	id->eide_pio_modes = __le16_to_cpu(id->eide_pio_modes);	id->eide_dma_min   = __le16_to_cpu(id->eide_dma_min);	id->eide_dma_time  = __le16_to_cpu(id->eide_dma_time);	id->eide_pio       = __le16_to_cpu(id->eide_pio);	id->eide_pio_iordy = __le16_to_cpu(id->eide_pio_iordy);	for (i = 0; i < 2; ++i)		id->words69_70[i] = __le16_to_cpu(id->words69_70[i]);	for (i = 0; i < 4; ++i)		id->words71_74[i] = __le16_to_cpu(id->words71_74[i]);	id->queue_depth    = __le16_to_cpu(id->queue_depth);	for (i = 0; i < 4; ++i)		id->words76_79[i] = __le16_to_cpu(id->words76_79[i]);	id->major_rev_num  = __le16_to_cpu(id->major_rev_num);	id->minor_rev_num  = __le16_to_cpu(id->minor_rev_num);	id->command_set_1  = __le16_to_cpu(id->command_set_1);	id->command_set_2  = __le16_to_cpu(id->command_set_2);	id->cfsse          = __le16_to_cpu(id->cfsse);	id->cfs_enable_1   = __le16_to_cpu(id->cfs_enable_1);	id->cfs_enable_2   = __le16_to_cpu(id->cfs_enable_2);	id->csf_default    = __le16_to_cpu(id->csf_default);	id->dma_ultra      = __le16_to_cpu(id->dma_ultra);	id->trseuc         = __le16_to_cpu(id->trseuc);	id->trsEuc         = __le16_to_cpu(id->trsEuc);	id->CurAPMvalues   = __le16_to_cpu(id->CurAPMvalues);	id->mprc           = __le16_to_cpu(id->mprc);	id->hw_config      = __le16_to_cpu(id->hw_config);	id->acoustic       = __le16_to_cpu(id->acoustic);	id->msrqs          = __le16_to_cpu(id->msrqs);	id->sxfert         = __le16_to_cpu(id->sxfert);	id->sal            = __le16_to_cpu(id->sal);	id->spg            = __le32_to_cpu(id->spg);	id->lba_capacity_2 = __le64_to_cpu(id->lba_capacity_2);	for (i = 0; i < 22; i++)		id->words104_125[i]   = __le16_to_cpu(id->words104_125[i]);	id->last_lun       = __le16_to_cpu(id->last_lun);	id->word127        = __le16_to_cpu(id->word127);	id->dlf            = __le16_to_cpu(id->dlf);	id->csfo           = __le16_to_cpu(id->csfo);	for (i = 0; i < 26; i++)		id->words130_155[i] = __le16_to_cpu(id->words130_155[i]);	id->word156        = __le16_to_cpu(id->word156);	for (i = 0; i < 3; i++)		id->words157_159[i] = __le16_to_cpu(id->words157_159[i]);	id->cfa_power      = __le16_to_cpu(id->cfa_power);	for (i = 0; i < 14; i++)		id->words161_175[i] = __le16_to_cpu(id->words161_175[i]);	for (i = 0; i < 31; i++)		id->words176_205[i] = __le16_to_cpu(id->words176_205[i]);	for (i = 0; i < 48; i++)		id->words206_254[i] = __le16_to_cpu(id->words206_254[i]);	id->integrity_word  = __le16_to_cpu(id->integrity_word);# else#  error "Please fix <asm/byteorder.h>"# endif#endif}/************************************************************************** * isd200_get_inquiry_data * * Get inquiry data * * RETURNS: *    ISD status code */static int isd200_get_inquiry_data( struct us_data *us ){	struct isd200_info *info = (struct isd200_info *)us->extra;	int retStatus = ISD200_GOOD;	struct hd_driveid *id = info->id;	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 Command Identify */			transferStatus = isd200_action( us, ACTION_IDENTIFY,							id, 							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;				__be16 *src;				__u16 *dest;				isd200_fix_driveid(id);				US_DEBUGP("   Identify Data Structure:\n");				US_DEBUGP("      config = 0x%x\n", id->config);				US_DEBUGP("      cyls = 0x%x\n", id->cyls);				US_DEBUGP("      heads = 0x%x\n", id->heads);				US_DEBUGP("      track_bytes = 0x%x\n", id->track_bytes);				US_DEBUGP("      sector_bytes = 0x%x\n", id->sector_bytes);				US_DEBUGP("      sectors = 0x%x\n", id->sectors);				US_DEBUGP("      serial_no[0] = 0x%x\n", id->serial_no[0]);				US_DEBUGP("      buf_type = 0x%x\n", id->buf_type);				US_DEBUGP("      buf_size = 0x%x\n", id->buf_size);				US_DEBUGP("      ecc_bytes = 0x%x\n", id->ecc_bytes);				US_DEBUGP("      fw_rev[0] = 0x%x\n", id->fw_rev[0]);				US_DEBUGP("      model[0] = 0x%x\n", id->model[0]);				US_DEBUGP("      max_multsect = 0x%x\n", id->max_multsect);				US_DEBUGP("      dword_io = 0x%x\n", id->dword_io);				US_DEBUGP("      capability = 0x%x\n", id->capability);				US_DEBUGP("      tPIO = 0x%x\n", id->tPIO);				US_DEBUGP("      tDMA = 0x%x\n", id->tDMA);				US_DEBUGP("      field_valid = 0x%x\n", id->field_valid);				US_DEBUGP("      cur_cyls = 0x%x\n", id->cur_cyls);				US_DEBUGP("      cur_heads = 0x%x\n", id->cur_heads);				US_DEBUGP("      cur_sectors = 0x%x\n", id->cur_sectors);				US_DEBUGP("      cur_capacity = 0x%x\n", (id->cur_capacity1 << 16) + id->cur_capacity0 );				US_DEBUGP("      multsect = 0x%x\n", id->multsect);				US_DEBUGP("      lba_capacity = 0x%x\n", id->lba_capacity);				US_DEBUGP("      command_set_1 = 0x%x\n", id->command_set_1);				US_DEBUGP("      command_set_2 = 0x%x\n", id->command_set_2);				memset(&info->InquiryData, 0, sizeof(info->InquiryData));				/* Standard IDE interface only supports disks */				info->InquiryData.DeviceType = DIRECT_ACCESS_DEVICE;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -