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

📄 shuttle_usbat.c

📁 usb 子设备程序 支持sd卡 mouse keyboard 的最单单的驱动程序 gcc编译 支持
💻 C
📖 第 1 页 / 共 4 页
字号:
	rc = usbat_get_status(us, &status); 	if (rc != USB_STOR_XFER_GOOD) 		return USB_STOR_TRANSPORT_ERROR;	/* Check for error bit, or if the command 'fell through' */	if (status == 0xA1 || !(status & 0x01)) {		/* Device is HP 8200 */		US_DEBUGP("usbat_identify_device: Detected HP8200 CDRW\n");		info->devicetype = USBAT_DEV_HP8200;	} else {		/* Device is a CompactFlash reader/writer */		US_DEBUGP("usbat_identify_device: Detected Flash reader/writer\n");		info->devicetype = USBAT_DEV_FLASH;	}	return USB_STOR_TRANSPORT_GOOD;}/* * Set the transport function based on the device type */static int usbat_set_transport(struct us_data *us,			       struct usbat_info *info,			       int devicetype){	if (!info->devicetype)		info->devicetype = devicetype;	if (!info->devicetype)		usbat_identify_device(us, info);	switch (info->devicetype) {	default:		return USB_STOR_TRANSPORT_ERROR;	case  USBAT_DEV_HP8200:		us->transport = usbat_hp8200e_transport;		break;	case USBAT_DEV_FLASH:		us->transport = usbat_flash_transport;		break;	}	return 0;}/* * Read the media capacity */static int usbat_flash_get_sector_count(struct us_data *us,					struct usbat_info *info){	unsigned char registers[3] = {		USBAT_ATA_SECCNT,		USBAT_ATA_DEVICE,		USBAT_ATA_CMD,	};	unsigned char  command[3] = { 0x01, 0xA0, 0xEC };	unsigned char *reply;	unsigned char status;	int rc;	if (!us || !info)		return USB_STOR_TRANSPORT_ERROR;	reply = kmalloc(512, GFP_NOIO);	if (!reply)		return USB_STOR_TRANSPORT_ERROR;	/* ATA command : IDENTIFY DEVICE */	rc = usbat_multiple_write(us, registers, command, 3);	if (rc != USB_STOR_XFER_GOOD) {		US_DEBUGP("usbat_flash_get_sector_count: Gah! identify_device failed\n");		rc = USB_STOR_TRANSPORT_ERROR;		goto leave;	}	/* Read device status */	if (usbat_get_status(us, &status) != USB_STOR_XFER_GOOD) {		rc = USB_STOR_TRANSPORT_ERROR;		goto leave;	}	msleep(100);	/* Read the device identification data */	rc = usbat_read_block(us, reply, 512, 0);	if (rc != USB_STOR_TRANSPORT_GOOD)		goto leave;	info->sectors = ((u32)(reply[117]) << 24) |		((u32)(reply[116]) << 16) |		((u32)(reply[115]) <<  8) |		((u32)(reply[114])      );	rc = USB_STOR_TRANSPORT_GOOD; leave:	kfree(reply);	return rc;}/* * Read data from device */static int usbat_flash_read_data(struct us_data *us,								 struct usbat_info *info,								 u32 sector,								 u32 sectors){	unsigned char registers[7] = {		USBAT_ATA_FEATURES,		USBAT_ATA_SECCNT,		USBAT_ATA_SECNUM,		USBAT_ATA_LBA_ME,		USBAT_ATA_LBA_HI,		USBAT_ATA_DEVICE,		USBAT_ATA_STATUS,	};	unsigned char command[7];	unsigned char *buffer;	unsigned char  thistime;	unsigned int totallen, alloclen;	int len, result;	unsigned int sg_idx = 0, sg_offset = 0;	result = usbat_flash_check_media(us, info);	if (result != USB_STOR_TRANSPORT_GOOD)		return result;	/*	 * we're working in LBA mode.  according to the ATA spec,	 * we can support up to 28-bit addressing.  I don't know if Jumpshot	 * supports beyond 24-bit addressing.  It's kind of hard to test	 * since it requires > 8GB CF card.	 */	if (sector > 0x0FFFFFFF)		return USB_STOR_TRANSPORT_ERROR;	totallen = sectors * info->ssize;	/*	 * Since we don't read more than 64 KB at a time, we have to create	 * a bounce buffer and move the data a piece at a time between the	 * bounce buffer and the actual transfer buffer.	 */	alloclen = min(totallen, 65536u);	buffer = kmalloc(alloclen, GFP_NOIO);	if (buffer == NULL)		return USB_STOR_TRANSPORT_ERROR;	do {		/*		 * loop, never allocate or transfer more than 64k at once		 * (min(128k, 255*info->ssize) is the real limit)		 */		len = min(totallen, alloclen);		thistime = (len / info->ssize) & 0xff; 		/* ATA command 0x20 (READ SECTORS) */		usbat_pack_ata_sector_cmd(command, thistime, sector, 0x20);		/* Write/execute ATA read command */		result = usbat_multiple_write(us, registers, command, 7);		if (result != USB_STOR_TRANSPORT_GOOD)			goto leave;		/* Read the data we just requested */		result = usbat_read_blocks(us, buffer, len, 0);		if (result != USB_STOR_TRANSPORT_GOOD)			goto leave;  	 		US_DEBUGP("usbat_flash_read_data:  %d bytes\n", len);			/* Store the data in the transfer buffer */		usb_stor_access_xfer_buf(buffer, len, us->srb,					 &sg_idx, &sg_offset, TO_XFER_BUF);		sector += thistime;		totallen -= len;	} while (totallen > 0);	kfree(buffer);	return USB_STOR_TRANSPORT_GOOD;leave:	kfree(buffer);	return USB_STOR_TRANSPORT_ERROR;}/* * Write data to device */static int usbat_flash_write_data(struct us_data *us,								  struct usbat_info *info,								  u32 sector,								  u32 sectors){	unsigned char registers[7] = {		USBAT_ATA_FEATURES,		USBAT_ATA_SECCNT,		USBAT_ATA_SECNUM,		USBAT_ATA_LBA_ME,		USBAT_ATA_LBA_HI,		USBAT_ATA_DEVICE,		USBAT_ATA_STATUS,	};	unsigned char command[7];	unsigned char *buffer;	unsigned char  thistime;	unsigned int totallen, alloclen;	int len, result;	unsigned int sg_idx = 0, sg_offset = 0;	result = usbat_flash_check_media(us, info);	if (result != USB_STOR_TRANSPORT_GOOD)		return result;	/*	 * we're working in LBA mode.  according to the ATA spec,	 * we can support up to 28-bit addressing.  I don't know if the device	 * supports beyond 24-bit addressing.  It's kind of hard to test	 * since it requires > 8GB media.	 */	if (sector > 0x0FFFFFFF)		return USB_STOR_TRANSPORT_ERROR;	totallen = sectors * info->ssize;	/*	 * Since we don't write more than 64 KB at a time, we have to create	 * a bounce buffer and move the data a piece at a time between the	 * bounce buffer and the actual transfer buffer.	 */	alloclen = min(totallen, 65536u);	buffer = kmalloc(alloclen, GFP_NOIO);	if (buffer == NULL)		return USB_STOR_TRANSPORT_ERROR;	do {		/*		 * loop, never allocate or transfer more than 64k at once		 * (min(128k, 255*info->ssize) is the real limit)		 */		len = min(totallen, alloclen);		thistime = (len / info->ssize) & 0xff;		/* Get the data from the transfer buffer */		usb_stor_access_xfer_buf(buffer, len, us->srb,					 &sg_idx, &sg_offset, FROM_XFER_BUF);		/* ATA command 0x30 (WRITE SECTORS) */		usbat_pack_ata_sector_cmd(command, thistime, sector, 0x30);		/* Write/execute ATA write command */		result = usbat_multiple_write(us, registers, command, 7);		if (result != USB_STOR_TRANSPORT_GOOD)			goto leave;		/* Write the data */		result = usbat_write_blocks(us, buffer, len, 0);		if (result != USB_STOR_TRANSPORT_GOOD)			goto leave;		sector += thistime;		totallen -= len;	} while (totallen > 0);	kfree(buffer);	return result;leave:	kfree(buffer);	return USB_STOR_TRANSPORT_ERROR;}/* * Squeeze a potentially huge (> 65535 byte) read10 command into * a little ( <= 65535 byte) ATAPI pipe */static int usbat_hp8200e_handle_read10(struct us_data *us,				       unsigned char *registers,				       unsigned char *data,				       struct scsi_cmnd *srb){	int result = USB_STOR_TRANSPORT_GOOD;	unsigned char *buffer;	unsigned int len;	unsigned int sector;	unsigned int sg_segment = 0;	unsigned int sg_offset = 0;	US_DEBUGP("handle_read10: transfersize %d\n",		srb->transfersize);	if (srb->request_bufflen < 0x10000) {		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_FROM_DEVICE,			srb->request_buffer, 			srb->request_bufflen, srb->use_sg, 1);		return result;	}	/*	 * Since we're requesting more data than we can handle in	 * a single read command (max is 64k-1), we will perform	 * multiple reads, but each read must be in multiples of	 * a sector.  Luckily the sector size is in srb->transfersize	 * (see linux/drivers/scsi/sr.c).	 */	if (data[7+0] == GPCMD_READ_CD) {		len = short_pack(data[7+9], data[7+8]);		len <<= 16;		len |= data[7+7];		US_DEBUGP("handle_read10: GPCMD_READ_CD: len %d\n", len);		srb->transfersize = srb->request_bufflen/len;	}	if (!srb->transfersize)  {		srb->transfersize = 2048; /* A guess */		US_DEBUGP("handle_read10: transfersize 0, forcing %d\n",			srb->transfersize);	}	/*	 * Since we only read in one block at a time, we have to create	 * a bounce buffer and move the data a piece at a time between the	 * bounce buffer and the actual transfer buffer.	 */	len = (65535/srb->transfersize) * srb->transfersize;	US_DEBUGP("Max read is %d bytes\n", len);	len = min(len, srb->request_bufflen);	buffer = kmalloc(len, GFP_NOIO);	if (buffer == NULL) /* bloody hell! */		return USB_STOR_TRANSPORT_FAILED;	sector = short_pack(data[7+3], data[7+2]);	sector <<= 16;	sector |= short_pack(data[7+5], data[7+4]);	transferred = 0;	sg_segment = 0; /* for keeping track of where we are in */	sg_offset = 0;  /* the scatter/gather list */	while (transferred != srb->request_bufflen) {		if (len > srb->request_bufflen - transferred)			len = srb->request_bufflen - transferred;		data[3] = len&0xFF; 	  /* (cylL) = expected length (L) */		data[4] = (len>>8)&0xFF;  /* (cylH) = expected length (H) */		/* Fix up the SCSI command sector and num sectors */		data[7+2] = MSB_of(sector>>16); /* SCSI command sector */		data[7+3] = LSB_of(sector>>16);		data[7+4] = MSB_of(sector&0xFFFF);		data[7+5] = LSB_of(sector&0xFFFF);		if (data[7+0] == GPCMD_READ_CD)			data[7+6] = 0;		data[7+7] = MSB_of(len / srb->transfersize); /* SCSI command */		data[7+8] = LSB_of(len / srb->transfersize); /* num sectors */		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_FROM_DEVICE,			buffer,			len, 0, 1);		if (result != USB_STOR_TRANSPORT_GOOD)			break;		/* Store the data in the transfer buffer */		usb_stor_access_xfer_buf(buffer, len, srb,				 &sg_segment, &sg_offset, TO_XFER_BUF);		/* Update the amount transferred and the sector number */		transferred += len;		sector += len / srb->transfersize;	} /* while transferred != srb->request_bufflen */	kfree(buffer);	return result;}static int usbat_select_and_test_registers(struct us_data *us){	int selector;	unsigned char *status = us->iobuf;	/* try device = master, then device = slave. */	for (selector = 0xA0; selector <= 0xB0; selector += 0x10) {		if (usbat_write(us, USBAT_ATA, USBAT_ATA_DEVICE, selector) !=				USB_STOR_XFER_GOOD)			return USB_STOR_TRANSPORT_ERROR;		if (usbat_read(us, USBAT_ATA, USBAT_ATA_STATUS, status) != 				USB_STOR_XFER_GOOD)			return USB_STOR_TRANSPORT_ERROR;		if (usbat_read(us, USBAT_ATA, USBAT_ATA_DEVICE, 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;		if (usbat_read(us, USBAT_ATA, USBAT_ATA_LBA_HI, status) != 				USB_STOR_XFER_GOOD)			return USB_STOR_TRANSPORT_ERROR;		if (usbat_write(us, USBAT_ATA, USBAT_ATA_LBA_ME, 0x55) != 				USB_STOR_XFER_GOOD)			return USB_STOR_TRANSPORT_ERROR;		if (usbat_write(us, USBAT_ATA, USBAT_ATA_LBA_HI, 0xAA) != 				USB_STOR_XFER_GOOD)			return USB_STOR_TRANSPORT_ERROR;

⌨️ 快捷键说明

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