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

📄 shuttle_usbat.c

📁 usb 子设备程序 支持sd卡 mouse keyboard 的最单单的驱动程序 gcc编译 支持
💻 C
📖 第 1 页 / 共 4 页
字号:
		if (usbat_read(us, USBAT_ATA, USBAT_ATA_LBA_ME, status) != 				USB_STOR_XFER_GOOD)			return USB_STOR_TRANSPORT_ERROR;		if (usbat_read(us, USBAT_ATA, USBAT_ATA_LBA_ME, status) != 				USB_STOR_XFER_GOOD)			return USB_STOR_TRANSPORT_ERROR;	}	return USB_STOR_TRANSPORT_GOOD;}/* * Initialize the USBAT processor and the storage device */static int init_usbat(struct us_data *us, int devicetype){	int rc;	struct usbat_info *info;	unsigned char subcountH = USBAT_ATA_LBA_HI;	unsigned char subcountL = USBAT_ATA_LBA_ME;	unsigned char *status = us->iobuf;	us->extra = kzalloc(sizeof(struct usbat_info), GFP_NOIO);	if (!us->extra) {		US_DEBUGP("init_usbat: Gah! Can't allocate storage for usbat info struct!\n");		return 1;	}	info = (struct usbat_info *) (us->extra);	/* Enable peripheral control signals */	rc = usbat_write_user_io(us,				 USBAT_UIO_OE1 | USBAT_UIO_OE0,				 USBAT_UIO_EPAD | USBAT_UIO_1);	if (rc != USB_STOR_XFER_GOOD)		return USB_STOR_TRANSPORT_ERROR;	US_DEBUGP("INIT 1\n");	msleep(2000);	rc = usbat_read_user_io(us, status);	if (rc != USB_STOR_TRANSPORT_GOOD)		return rc;	US_DEBUGP("INIT 2\n");	rc = usbat_read_user_io(us, status);	if (rc != USB_STOR_XFER_GOOD)		return USB_STOR_TRANSPORT_ERROR;	rc = usbat_read_user_io(us, status);	if (rc != USB_STOR_XFER_GOOD)		return USB_STOR_TRANSPORT_ERROR;	US_DEBUGP("INIT 3\n");	rc = usbat_select_and_test_registers(us);	if (rc != USB_STOR_TRANSPORT_GOOD)		return rc;	US_DEBUGP("INIT 4\n");	rc = usbat_read_user_io(us, status);	if (rc != USB_STOR_XFER_GOOD)		return USB_STOR_TRANSPORT_ERROR;	US_DEBUGP("INIT 5\n");	/* Enable peripheral control signals and card detect */	rc = usbat_device_enable_cdt(us);	if (rc != USB_STOR_TRANSPORT_GOOD)		return rc;	US_DEBUGP("INIT 6\n");	rc = usbat_read_user_io(us, status);	if (rc != USB_STOR_XFER_GOOD)		return USB_STOR_TRANSPORT_ERROR;	US_DEBUGP("INIT 7\n");	msleep(1400);	rc = usbat_read_user_io(us, status);	if (rc != USB_STOR_XFER_GOOD)		return USB_STOR_TRANSPORT_ERROR;	US_DEBUGP("INIT 8\n");	rc = usbat_select_and_test_registers(us);	if (rc != USB_STOR_TRANSPORT_GOOD)		return rc;	US_DEBUGP("INIT 9\n");	/* At this point, we need to detect which device we are using */	if (usbat_set_transport(us, info, devicetype))		return USB_STOR_TRANSPORT_ERROR;	US_DEBUGP("INIT 10\n");	if (usbat_get_device_type(us) == USBAT_DEV_FLASH) { 		subcountH = 0x02;		subcountL = 0x00;	}	rc = usbat_set_shuttle_features(us, (USBAT_FEAT_ETEN | USBAT_FEAT_ET2 | USBAT_FEAT_ET1),									0x00, 0x88, 0x08, subcountH, subcountL);	if (rc != USB_STOR_XFER_GOOD)		return USB_STOR_TRANSPORT_ERROR;	US_DEBUGP("INIT 11\n");	return USB_STOR_TRANSPORT_GOOD;}/* * Transport for the HP 8200e */static int usbat_hp8200e_transport(struct scsi_cmnd *srb, struct us_data *us){	int result;	unsigned char *status = us->iobuf;	unsigned char registers[32];	unsigned char data[32];	unsigned int len;	int i;	char string[64];	len = srb->request_bufflen;	/* Send A0 (ATA PACKET COMMAND).	   Note: I guess we're never going to get any of the ATA	   commands... just ATA Packet Commands. 	 */	registers[0] = USBAT_ATA_FEATURES;	registers[1] = USBAT_ATA_SECCNT;	registers[2] = USBAT_ATA_SECNUM;	registers[3] = USBAT_ATA_LBA_ME;	registers[4] = USBAT_ATA_LBA_HI;	registers[5] = USBAT_ATA_DEVICE;	registers[6] = USBAT_ATA_CMD;	data[0] = 0x00;	data[1] = 0x00;	data[2] = 0x00;	data[3] = len&0xFF; 		/* (cylL) = expected length (L) */	data[4] = (len>>8)&0xFF; 	/* (cylH) = expected length (H) */	data[5] = 0xB0; 		/* (device sel) = slave */	data[6] = 0xA0; 		/* (command) = ATA PACKET COMMAND */	for (i=7; i<19; i++) {		registers[i] = 0x10;		data[i] = (i-7 >= srb->cmd_len) ? 0 : srb->cmnd[i-7];	}	result = usbat_get_status(us, status);	US_DEBUGP("Status = %02X\n", *status);	if (result != USB_STOR_XFER_GOOD)		return USB_STOR_TRANSPORT_ERROR;	if (srb->cmnd[0] == TEST_UNIT_READY)		transferred = 0;	if (srb->sc_data_direction == DMA_TO_DEVICE) {		result = usbat_hp8200e_rw_block_test(us, USBAT_ATA, 			registers, data, 19,			USBAT_ATA_DATA, USBAT_ATA_STATUS, 0xFD,			(USBAT_QUAL_FCQ | USBAT_QUAL_ALQ),			DMA_TO_DEVICE,			srb->request_buffer, 			len, srb->use_sg, 10);		if (result == USB_STOR_TRANSPORT_GOOD) {			transferred += len;			US_DEBUGP("Wrote %08X bytes\n", transferred);		}		return result;	} else if (srb->cmnd[0] == READ_10 ||		   srb->cmnd[0] == GPCMD_READ_CD) {		return usbat_hp8200e_handle_read10(us, registers, data, srb);	}	if (len > 0xFFFF) {		US_DEBUGP("Error: len = %08X... what do I do now?\n",			len);		return USB_STOR_TRANSPORT_ERROR;	}	if ( (result = usbat_multiple_write(us, 			registers, data, 7)) != USB_STOR_TRANSPORT_GOOD) {		return result;	}	/*	 * Write the 12-byte command header.	 *	 * If the command is BLANK then set the timer for 75 minutes.	 * Otherwise set it for 10 minutes.	 *	 * NOTE: THE 8200 DOCUMENTATION STATES THAT BLANKING A CDRW	 * AT SPEED 4 IS UNRELIABLE!!!	 */	if ((result = usbat_write_block(us,			USBAT_ATA, srb->cmnd, 12,				(srb->cmnd[0]==GPCMD_BLANK ? 75 : 10), 0) !=			     USB_STOR_TRANSPORT_GOOD)) {		return result;	}	/* If there is response data to be read in then do it here. */	if (len != 0 && (srb->sc_data_direction == DMA_FROM_DEVICE)) {		/* How many bytes to read in? Check cylL register */		if (usbat_read(us, USBAT_ATA, USBAT_ATA_LBA_ME, status) != 		    	USB_STOR_XFER_GOOD) {			return USB_STOR_TRANSPORT_ERROR;		}		if (len > 0xFF) { /* need to read cylH also */			len = *status;			if (usbat_read(us, USBAT_ATA, USBAT_ATA_LBA_HI, status) !=				    USB_STOR_XFER_GOOD) {				return USB_STOR_TRANSPORT_ERROR;			}			len += ((unsigned int) *status)<<8;		}		else			len = *status;		result = usbat_read_block(us, srb->request_buffer, len, srb->use_sg);		/* Debug-print the first 32 bytes of the transfer */		if (!srb->use_sg) {			string[0] = 0;			for (i=0; i<len && i<32; i++) {				sprintf(string+strlen(string), "%02X ",				  ((unsigned char *)srb->request_buffer)[i]);				if ((i%16)==15) {					US_DEBUGP("%s\n", string);					string[0] = 0;				}			}			if (string[0]!=0)				US_DEBUGP("%s\n", string);		}	}	return result;}/* * Transport for USBAT02-based CompactFlash and similar storage devices */static int usbat_flash_transport(struct scsi_cmnd * srb, struct us_data *us){	int rc;	struct usbat_info *info = (struct usbat_info *) (us->extra);	unsigned long block, blocks;	unsigned char *ptr = us->iobuf;	static unsigned char inquiry_response[36] = {		0x00, 0x80, 0x00, 0x01, 0x1F, 0x00, 0x00, 0x00	};	if (srb->cmnd[0] == INQUIRY) {		US_DEBUGP("usbat_flash_transport: INQUIRY. Returning bogus response.\n");		memcpy(ptr, inquiry_response, sizeof(inquiry_response));		fill_inquiry_response(us, ptr, 36);		return USB_STOR_TRANSPORT_GOOD;	}	if (srb->cmnd[0] == READ_CAPACITY) {		rc = usbat_flash_check_media(us, info);		if (rc != USB_STOR_TRANSPORT_GOOD)			return rc;		rc = usbat_flash_get_sector_count(us, info);		if (rc != USB_STOR_TRANSPORT_GOOD)			return rc;		/* hard coded 512 byte sectors as per ATA spec */		info->ssize = 0x200;		US_DEBUGP("usbat_flash_transport: READ_CAPACITY: %ld sectors, %ld bytes per sector\n",			  info->sectors, info->ssize);		/*		 * build the reply		 * note: must return the sector number of the last sector,		 * *not* the total number of sectors		 */		((__be32 *) ptr)[0] = cpu_to_be32(info->sectors - 1);		((__be32 *) ptr)[1] = cpu_to_be32(info->ssize);		usb_stor_set_xfer_buf(ptr, 8, srb);		return USB_STOR_TRANSPORT_GOOD;	}	if (srb->cmnd[0] == MODE_SELECT_10) {		US_DEBUGP("usbat_flash_transport:  Gah! MODE_SELECT_10.\n");		return USB_STOR_TRANSPORT_ERROR;	}	if (srb->cmnd[0] == READ_10) {		block = ((u32)(srb->cmnd[2]) << 24) | ((u32)(srb->cmnd[3]) << 16) |				((u32)(srb->cmnd[4]) <<  8) | ((u32)(srb->cmnd[5]));		blocks = ((u32)(srb->cmnd[7]) << 8) | ((u32)(srb->cmnd[8]));		US_DEBUGP("usbat_flash_transport:  READ_10: read block 0x%04lx  count %ld\n", block, blocks);		return usbat_flash_read_data(us, info, block, blocks);	}	if (srb->cmnd[0] == READ_12) {		/*		 * I don't think we'll ever see a READ_12 but support it anyway		 */		block = ((u32)(srb->cmnd[2]) << 24) | ((u32)(srb->cmnd[3]) << 16) |		        ((u32)(srb->cmnd[4]) <<  8) | ((u32)(srb->cmnd[5]));		blocks = ((u32)(srb->cmnd[6]) << 24) | ((u32)(srb->cmnd[7]) << 16) |		         ((u32)(srb->cmnd[8]) <<  8) | ((u32)(srb->cmnd[9]));		US_DEBUGP("usbat_flash_transport: READ_12: read block 0x%04lx  count %ld\n", block, blocks);		return usbat_flash_read_data(us, info, block, blocks);	}	if (srb->cmnd[0] == WRITE_10) {		block = ((u32)(srb->cmnd[2]) << 24) | ((u32)(srb->cmnd[3]) << 16) |		        ((u32)(srb->cmnd[4]) <<  8) | ((u32)(srb->cmnd[5]));		blocks = ((u32)(srb->cmnd[7]) << 8) | ((u32)(srb->cmnd[8]));		US_DEBUGP("usbat_flash_transport: WRITE_10: write block 0x%04lx  count %ld\n", block, blocks);		return usbat_flash_write_data(us, info, block, blocks);	}	if (srb->cmnd[0] == WRITE_12) {		/*		 * I don't think we'll ever see a WRITE_12 but support it anyway		 */		block = ((u32)(srb->cmnd[2]) << 24) | ((u32)(srb->cmnd[3]) << 16) |		        ((u32)(srb->cmnd[4]) <<  8) | ((u32)(srb->cmnd[5]));		blocks = ((u32)(srb->cmnd[6]) << 24) | ((u32)(srb->cmnd[7]) << 16) |		         ((u32)(srb->cmnd[8]) <<  8) | ((u32)(srb->cmnd[9]));		US_DEBUGP("usbat_flash_transport: WRITE_12: write block 0x%04lx  count %ld\n", block, blocks);		return usbat_flash_write_data(us, info, block, blocks);	}	if (srb->cmnd[0] == TEST_UNIT_READY) {		US_DEBUGP("usbat_flash_transport: TEST_UNIT_READY.\n");		rc = usbat_flash_check_media(us, info);		if (rc != USB_STOR_TRANSPORT_GOOD)			return rc;		return usbat_check_status(us);	}	if (srb->cmnd[0] == REQUEST_SENSE) {		US_DEBUGP("usbat_flash_transport: REQUEST_SENSE.\n");		memset(ptr, 0, 18);		ptr[0] = 0xF0;		ptr[2] = info->sense_key;		ptr[7] = 11;		ptr[12] = info->sense_asc;		ptr[13] = info->sense_ascq;		usb_stor_set_xfer_buf(ptr, 18, srb);		return USB_STOR_TRANSPORT_GOOD;	}	if (srb->cmnd[0] == ALLOW_MEDIUM_REMOVAL) {		/*		 * sure.  whatever.  not like we can stop the user from popping		 * the media out of the device (no locking doors, etc)		 */		return USB_STOR_TRANSPORT_GOOD;	}	US_DEBUGP("usbat_flash_transport: Gah! Unknown command: %d (0x%x)\n",			  srb->cmnd[0], srb->cmnd[0]);	info->sense_key = 0x05;	info->sense_asc = 0x20;	info->sense_ascq = 0x00;	return USB_STOR_TRANSPORT_FAILED;}int init_usbat_cd(struct us_data *us){	return init_usbat(us, USBAT_DEV_HP8200);}int init_usbat_flash(struct us_data *us){	return init_usbat(us, USBAT_DEV_FLASH);}int init_usbat_probe(struct us_data *us){	return init_usbat(us, 0);}/* * Default transport function. Attempts to detect which transport function * should be called, makes it the new default, and calls it. * * This function should never be called. Our usbat_init() function detects the * device type and changes the us->transport ptr to the transport function * relevant to the device. * However, we'll support this impossible(?) case anyway. */int usbat_transport(struct scsi_cmnd *srb, struct us_data *us){	struct usbat_info *info = (struct usbat_info*) (us->extra);	if (usbat_set_transport(us, info, 0))		return USB_STOR_TRANSPORT_ERROR;	return us->transport(srb, us);	}

⌨️ 快捷键说明

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