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

📄 shuttle_usbat.c

📁 h内核
💻 C
📖 第 1 页 / 共 2 页
字号:
		us->send_bulk_pipe, data, num_registers*2, NULL);	if (result != USB_STOR_XFER_GOOD)		return USB_STOR_TRANSPORT_ERROR;	return usbat_wait_not_busy(us, 0);}static int usbat_read_user_io(struct us_data *us, unsigned char *data_flags){	int result;	result = usb_stor_ctrl_transfer(us,		us->recv_ctrl_pipe,		0x82,		0xC0,		0,		0,		data_flags,		1);	return result;}static int usbat_write_user_io(struct us_data *us,			       unsigned char enable_flags,			       unsigned char data_flags){	int result;	result = usb_stor_ctrl_transfer(us,		us->send_ctrl_pipe,		0x82,		0x40,		short_pack(enable_flags, data_flags),		0,		NULL,		0);	return result;}/* * Squeeze a potentially huge (> 65535 byte) read10 command into * a little ( <= 65535 byte) ATAPI pipe */static int usbat_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_rw_block_test(us, USBAT_ATA, 			registers, data, 19,			0x10, 0x17, 0xFD, 0x30,			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_rw_block_test(us, USBAT_ATA, 			registers, data, 19,			0x10, 0x17, 0xFD, 0x30,			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 hp_8200e_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, 0x16, selector) != 				USB_STOR_XFER_GOOD)			return USB_STOR_TRANSPORT_ERROR;		if (usbat_read(us, USBAT_ATA, 0x17, status) != 				USB_STOR_XFER_GOOD)			return USB_STOR_TRANSPORT_ERROR;		if (usbat_read(us, USBAT_ATA, 0x16, status) != 				USB_STOR_XFER_GOOD)			return USB_STOR_TRANSPORT_ERROR;		if (usbat_read(us, USBAT_ATA, 0x14, status) != 				USB_STOR_XFER_GOOD)			return USB_STOR_TRANSPORT_ERROR;		if (usbat_read(us, USBAT_ATA, 0x15, status) != 				USB_STOR_XFER_GOOD)			return USB_STOR_TRANSPORT_ERROR;		if (usbat_write(us, USBAT_ATA, 0x14, 0x55) != 				USB_STOR_XFER_GOOD)			return USB_STOR_TRANSPORT_ERROR;		if (usbat_write(us, USBAT_ATA, 0x15, 0xAA) != 				USB_STOR_XFER_GOOD)			return USB_STOR_TRANSPORT_ERROR;		if (usbat_read(us, USBAT_ATA, 0x14, status) != 				USB_STOR_XFER_GOOD)			return USB_STOR_TRANSPORT_ERROR;		if (usbat_read(us, USBAT_ATA, 0x15, status) != 				USB_STOR_XFER_GOOD)			return USB_STOR_TRANSPORT_ERROR;	}	return USB_STOR_TRANSPORT_GOOD;}int init_8200e(struct us_data *us){	int result;	unsigned char *status = us->iobuf;	// Enable peripheral control signals	if (usbat_write_user_io(us,	  USBAT_UIO_OE1 | USBAT_UIO_OE0,	  USBAT_UIO_EPAD | USBAT_UIO_1) != USB_STOR_XFER_GOOD)		return USB_STOR_TRANSPORT_ERROR;	US_DEBUGP("INIT 1\n");	msleep(2000);	if (usbat_read_user_io(us, status) !=			USB_STOR_XFER_GOOD)		return USB_STOR_TRANSPORT_ERROR;	US_DEBUGP("INIT 2\n");	if (usbat_read_user_io(us, status) !=			USB_STOR_XFER_GOOD)		return USB_STOR_TRANSPORT_ERROR;	US_DEBUGP("INIT 3\n");	// Reset peripheral, enable periph control signals	// (bring reset signal up)	if (usbat_write_user_io(us,	  USBAT_UIO_DRVRST | USBAT_UIO_OE1 | USBAT_UIO_OE0,	  USBAT_UIO_EPAD | USBAT_UIO_1) != USB_STOR_XFER_GOOD)		return USB_STOR_TRANSPORT_ERROR;	US_DEBUGP("INIT 4\n");	// Enable periph control signals	// (bring reset signal down)	if (usbat_write_user_io(us,	  USBAT_UIO_OE1 | USBAT_UIO_OE0,	  USBAT_UIO_EPAD | USBAT_UIO_1) != USB_STOR_XFER_GOOD)		return USB_STOR_TRANSPORT_ERROR;	US_DEBUGP("INIT 5\n");	msleep(250);	// Write 0x80 to ISA port 0x3F	if (usbat_write(us, USBAT_ISA, 0x3F, 0x80) !=			USB_STOR_XFER_GOOD)		return USB_STOR_TRANSPORT_ERROR;	US_DEBUGP("INIT 6\n");	// Read ISA port 0x27	if (usbat_read(us, USBAT_ISA, 0x27, status) !=			USB_STOR_XFER_GOOD)		return USB_STOR_TRANSPORT_ERROR;	US_DEBUGP("INIT 7\n");	if (usbat_read_user_io(us, status) !=			USB_STOR_XFER_GOOD)		return USB_STOR_TRANSPORT_ERROR;	US_DEBUGP("INIT 8\n");	if ( (result = hp_8200e_select_and_test_registers(us)) !=			 USB_STOR_TRANSPORT_GOOD)		return result;	US_DEBUGP("INIT 9\n");	if (usbat_read_user_io(us, status) !=			USB_STOR_XFER_GOOD)		return USB_STOR_TRANSPORT_ERROR;	US_DEBUGP("INIT 10\n");	// Enable periph control signals and card detect	if (usbat_write_user_io(us,	  USBAT_UIO_ACKD |USBAT_UIO_OE1 | USBAT_UIO_OE0,	  USBAT_UIO_EPAD | USBAT_UIO_1) != USB_STOR_XFER_GOOD)		return USB_STOR_TRANSPORT_ERROR;	US_DEBUGP("INIT 11\n");	if (usbat_read_user_io(us, status) !=			USB_STOR_XFER_GOOD)		return USB_STOR_TRANSPORT_ERROR;	US_DEBUGP("INIT 12\n");	msleep(1400);	if (usbat_read_user_io(us, status) !=			USB_STOR_XFER_GOOD)		return USB_STOR_TRANSPORT_ERROR;	US_DEBUGP("INIT 13\n");	if ( (result = hp_8200e_select_and_test_registers(us)) !=			 USB_STOR_TRANSPORT_GOOD)		return result;	US_DEBUGP("INIT 14\n");	if (usbat_set_shuttle_features(us, 			0x83, 0x00, 0x88, 0x08, 0x15, 0x14) !=			 USB_STOR_XFER_GOOD)		return USB_STOR_TRANSPORT_ERROR;	US_DEBUGP("INIT 15\n");	return USB_STOR_TRANSPORT_GOOD;}/* * Transport for the HP 8200e */int 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] = 0x11;	registers[1] = 0x12;	registers[2] = 0x13;	registers[3] = 0x14;	registers[4] = 0x15;	registers[5] = 0x16;	registers[6] = 0x17;	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_read(us, USBAT_ATA, 0x17, 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_rw_block_test(us, USBAT_ATA, 			registers, data, 19,			0x10, 0x17, 0xFD, 0x30,			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_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, 			USBAT_ATA,			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, 0x10, srb->cmnd, 12, 0,			srb->cmnd[0]==GPCMD_BLANK ? 75 : 10)) !=				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, 0x14, 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, 0x15, status) !=				    USB_STOR_XFER_GOOD) {				return USB_STOR_TRANSPORT_ERROR;			}			len += ((unsigned int) *status)<<8;		}		else			len = *status;		result = usbat_read_block(us, USBAT_ATA, 0x10, 			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;}

⌨️ 快捷键说明

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