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

📄 transport.c

📁 优龙2410linux2.6.8内核源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
		/* if we stalled the data transfer it means command failed */		if (result == USB_STOR_XFER_STALLED)			return USB_STOR_TRANSPORT_FAILED;		if (result > USB_STOR_XFER_STALLED)			return USB_STOR_TRANSPORT_ERROR;	}	/* STATUS STAGE */	result = usb_stor_intr_transfer(us, us->iobuf, 2);	US_DEBUGP("Got interrupt data (0x%x, 0x%x)\n", 			us->iobuf[0], us->iobuf[1]);	if (result != USB_STOR_XFER_GOOD)		return USB_STOR_TRANSPORT_ERROR;	/* UFI gives us ASC and ASCQ, like a request sense	 *	 * REQUEST_SENSE and INQUIRY don't affect the sense data on UFI	 * devices, so we ignore the information for those commands.  Note	 * that this means we could be ignoring a real error on these	 * commands, but that can't be helped.	 */	if (us->subclass == US_SC_UFI) {		if (srb->cmnd[0] == REQUEST_SENSE ||		    srb->cmnd[0] == INQUIRY)			return USB_STOR_TRANSPORT_GOOD;		if (us->iobuf[0])			goto Failed;		return USB_STOR_TRANSPORT_GOOD;	}	/* If not UFI, we interpret the data as a result code 	 * The first byte should always be a 0x0.	 *	 * Some bogus devices don't follow that rule.  They stuff the ASC	 * into the first byte -- so if it's non-zero, call it a failure.	 */	if (us->iobuf[0]) {		US_DEBUGP("CBI IRQ data showed reserved bType 0x%x\n",				us->iobuf[0]);		goto Failed;	}	/* The second byte & 0x0F should be 0x0 for good, otherwise error */	switch (us->iobuf[1] & 0x0F) {		case 0x00: 			return USB_STOR_TRANSPORT_GOOD;		case 0x01: 			goto Failed;	}	return USB_STOR_TRANSPORT_ERROR;	/* the CBI spec requires that the bulk pipe must be cleared	 * following any data-in/out command failure (section 2.4.3.1.3)	 */  Failed:	if (pipe)		usb_stor_clear_halt(us, pipe);	return USB_STOR_TRANSPORT_FAILED;}/* * Control/Bulk transport */int usb_stor_CB_transport(Scsi_Cmnd *srb, struct us_data *us){	unsigned int transfer_length = srb->request_bufflen;	int result;	/* COMMAND STAGE */	/* let's send the command via the control pipe */	result = usb_stor_ctrl_transfer(us, us->send_ctrl_pipe,				      US_CBI_ADSC, 				      USB_TYPE_CLASS | USB_RECIP_INTERFACE, 0, 				      us->ifnum, srb->cmnd, srb->cmd_len);	/* check the return code for the command */	US_DEBUGP("Call to usb_stor_ctrl_transfer() returned %d\n", result);	/* if we stalled the command, it means command failed */	if (result == USB_STOR_XFER_STALLED) {		return USB_STOR_TRANSPORT_FAILED;	}	/* Uh oh... serious problem here */	if (result != USB_STOR_XFER_GOOD) {		return USB_STOR_TRANSPORT_ERROR;	}	/* DATA STAGE */	/* transfer the data payload for this command, if one exists*/	if (transfer_length) {		unsigned int pipe = srb->sc_data_direction == SCSI_DATA_READ ? 				us->recv_bulk_pipe : us->send_bulk_pipe;		result = usb_stor_bulk_transfer_sg(us, pipe,					srb->request_buffer, transfer_length,					srb->use_sg, &srb->resid);		US_DEBUGP("CB data stage result is 0x%x\n", result);		/* if we stalled the data transfer it means command failed */		if (result == USB_STOR_XFER_STALLED)			return USB_STOR_TRANSPORT_FAILED;		if (result > USB_STOR_XFER_STALLED)			return USB_STOR_TRANSPORT_ERROR;	}	/* STATUS STAGE */	/* NOTE: CB does not have a status stage.  Silly, I know.  So	 * we have to catch this at a higher level.	 */	return USB_STOR_TRANSPORT_GOOD;}/* * Bulk only transport *//* Determine what the maximum LUN supported is */int usb_stor_Bulk_max_lun(struct us_data *us){	int result;	/* issue the command */	result = usb_stor_control_msg(us, us->recv_ctrl_pipe,				 US_BULK_GET_MAX_LUN, 				 USB_DIR_IN | USB_TYPE_CLASS | 				 USB_RECIP_INTERFACE,				 0, us->ifnum, us->iobuf, 1, HZ);	US_DEBUGP("GetMaxLUN command result is %d, data is %d\n", 		  result, us->iobuf[0]);	/* if we have a successful request, return the result */	if (result == 1)		return us->iobuf[0];	/* 	 * Some devices (i.e. Iomega Zip100) need this -- apparently	 * the bulk pipes get STALLed when the GetMaxLUN request is	 * processed.   This is, in theory, harmless to all other devices	 * (regardless of if they stall or not).	 */	if (result == -EPIPE) {		usb_stor_clear_halt(us, us->recv_bulk_pipe);		usb_stor_clear_halt(us, us->send_bulk_pipe);		/* return the default -- no LUNs */		return 0;	}	/* An answer or a STALL are the only valid responses.  If we get	 * something else, return an indication of error */	return -1;}int usb_stor_Bulk_transport(Scsi_Cmnd *srb, struct us_data *us){	struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;	struct bulk_cs_wrap *bcs = (struct bulk_cs_wrap *) us->iobuf;	unsigned int transfer_length = srb->request_bufflen;	unsigned int residue;	int result;	int fake_sense = 0;	unsigned int cswlen;	/* set up the command wrapper */	bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);	bcb->DataTransferLength = cpu_to_le32(transfer_length);	bcb->Flags = srb->sc_data_direction == SCSI_DATA_READ ? 1 << 7 : 0;	bcb->Tag = srb->serial_number;	bcb->Lun = srb->device->lun;	if (us->flags & US_FL_SCM_MULT_TARG)		bcb->Lun |= srb->device->id << 4;	bcb->Length = srb->cmd_len;	/* copy the command payload */	memset(bcb->CDB, 0, sizeof(bcb->CDB));	memcpy(bcb->CDB, srb->cmnd, bcb->Length);	/* send it to out endpoint */	US_DEBUGP("Bulk Command S 0x%x T 0x%x L %d F %d Trg %d LUN %d CL %d\n",			le32_to_cpu(bcb->Signature), bcb->Tag,			le32_to_cpu(bcb->DataTransferLength), bcb->Flags,			(bcb->Lun >> 4), (bcb->Lun & 0x0F), 			bcb->Length);	result = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe,				bcb, US_BULK_CB_WRAP_LEN, NULL);	US_DEBUGP("Bulk command transfer result=%d\n", result);	if (result != USB_STOR_XFER_GOOD)		return USB_STOR_TRANSPORT_ERROR;	/* DATA STAGE */	/* send/receive data payload, if there is any */	if (transfer_length) {		unsigned int pipe = srb->sc_data_direction == SCSI_DATA_READ ? 				us->recv_bulk_pipe : us->send_bulk_pipe;		result = usb_stor_bulk_transfer_sg(us, pipe,					srb->request_buffer, transfer_length,					srb->use_sg, &srb->resid);		US_DEBUGP("Bulk data transfer result 0x%x\n", result);		if (result == USB_STOR_XFER_ERROR)			return USB_STOR_TRANSPORT_ERROR;		/* If the device tried to send back more data than the		 * amount requested, the spec requires us to transfer		 * the CSW anyway.  Since there's no point retrying the		 * the command, we'll return fake sense data indicating		 * Illegal Request, Invalid Field in CDB.		 */		if (result == USB_STOR_XFER_LONG)			fake_sense = 1;	}	/* See flow chart on pg 15 of the Bulk Only Transport spec for	 * an explanation of how this code works.	 */	/* get CSW for device status */	US_DEBUGP("Attempting to get CSW...\n");	result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe,				bcs, US_BULK_CS_WRAP_LEN, &cswlen);	/* Some broken devices add unnecessary zero-length packets to the	 * end of their data transfers.  Such packets show up as 0-length	 * CSWs.  If we encounter such a thing, try to read the CSW again.	 */	if (result == USB_STOR_XFER_SHORT && cswlen == 0) {		US_DEBUGP("Received 0-length CSW; retrying...\n");		result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe,				bcs, US_BULK_CS_WRAP_LEN, &cswlen);	}	/* did the attempt to read the CSW fail? */	if (result == USB_STOR_XFER_STALLED) {		/* get the status again */		US_DEBUGP("Attempting to get CSW (2nd try)...\n");		result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe,				bcs, US_BULK_CS_WRAP_LEN, NULL);	}	/* if we still have a failure at this point, we're in trouble */	US_DEBUGP("Bulk status result = %d\n", result);	if (result != USB_STOR_XFER_GOOD)		return USB_STOR_TRANSPORT_ERROR;	/* check bulk status */	residue = le32_to_cpu(bcs->Residue);	US_DEBUGP("Bulk Status S 0x%x T 0x%x R %u Stat 0x%x\n",			le32_to_cpu(bcs->Signature), bcs->Tag, 			residue, bcs->Status);	if ((bcs->Signature != cpu_to_le32(US_BULK_CS_SIGN) &&		    bcs->Signature != cpu_to_le32(US_BULK_CS_OLYMPUS_SIGN)) ||			bcs->Tag != srb->serial_number || 			bcs->Status > US_BULK_STAT_PHASE) {		US_DEBUGP("Bulk logical error\n");		return USB_STOR_TRANSPORT_ERROR;	}	/* try to compute the actual residue, based on how much data	 * was really transferred and what the device tells us */	residue = min(residue, transfer_length);	srb->resid = max(srb->resid, (int) residue);	/* based on the status code, we report good or bad */	switch (bcs->Status) {		case US_BULK_STAT_OK:			/* device babbled -- return fake sense data */			if (fake_sense) {				memcpy(srb->sense_buffer, 				       usb_stor_sense_invalidCDB, 				       sizeof(usb_stor_sense_invalidCDB));				return USB_STOR_TRANSPORT_NO_SENSE;			}			/* command good -- note that data could be short */			return USB_STOR_TRANSPORT_GOOD;		case US_BULK_STAT_FAIL:			/* command failed */			return USB_STOR_TRANSPORT_FAILED;		case US_BULK_STAT_PHASE:			/* phase error -- note that a transport reset will be			 * invoked by the invoke_transport() function			 */			return USB_STOR_TRANSPORT_ERROR;	}	/* we should never get here, but if we do, we're in trouble */	return USB_STOR_TRANSPORT_ERROR;}/*********************************************************************** * Reset routines ***********************************************************************//* This is the common part of the device reset code. * * It's handy that every transport mechanism uses the control endpoint for * resets. * * Basically, we send a reset with a 20-second timeout, so we don't get * jammed attempting to do the reset. */static int usb_stor_reset_common(struct us_data *us,		u8 request, u8 requesttype,		u16 value, u16 index, void *data, u16 size){	int result;	int result2;	int rc = FAILED;	/* Let the SCSI layer know we are doing a reset, set the	 * RESETTING bit, and clear the ABORTING bit so that the reset	 * may proceed.	 */	scsi_lock(us->host);	usb_stor_report_device_reset(us);	set_bit(US_FLIDX_RESETTING, &us->flags);	clear_bit(US_FLIDX_ABORTING, &us->flags);	scsi_unlock(us->host);	/* A 20-second timeout may seem rather long, but a LaCie	 * StudioDrive USB2 device takes 16+ seconds to get going	 * following a powerup or USB attach event.	 */	result = usb_stor_control_msg(us, us->send_ctrl_pipe,			request, requesttype, value, index, data, size,			20*HZ);	if (result < 0) {		US_DEBUGP("Soft reset failed: %d\n", result);		goto Done;	} 	/* Give the device some time to recover from the reset, 	 * but don't delay disconnect processing. */ 	wait_event_interruptible_timeout(us->dev_reset_wait, 			test_bit(US_FLIDX_DISCONNECTING, &us->flags), 			HZ*6);	if (test_bit(US_FLIDX_DISCONNECTING, &us->flags)) {		US_DEBUGP("Reset interrupted by disconnect\n");		goto Done;	}	US_DEBUGP("Soft reset: clearing bulk-in endpoint halt\n");	result = usb_stor_clear_halt(us, us->recv_bulk_pipe);	US_DEBUGP("Soft reset: clearing bulk-out endpoint halt\n");	result2 = usb_stor_clear_halt(us, us->send_bulk_pipe);	/* return a result code based on the result of the control message */	if (result < 0 || result2 < 0) {		US_DEBUGP("Soft reset failed\n");		goto Done;	}	US_DEBUGP("Soft reset done\n");	rc = SUCCESS;  Done:	clear_bit(US_FLIDX_RESETTING, &us->flags);	return rc;}/* This issues a CB[I] Reset to the device in question */#define CB_RESET_CMD_SIZE	12int usb_stor_CB_reset(struct us_data *us){	US_DEBUGP("%s called\n", __FUNCTION__);	memset(us->iobuf, 0xFF, CB_RESET_CMD_SIZE);	us->iobuf[0] = SEND_DIAGNOSTIC;	us->iobuf[1] = 4;	return usb_stor_reset_common(us, US_CBI_ADSC, 				 USB_TYPE_CLASS | USB_RECIP_INTERFACE,				 0, us->ifnum, us->iobuf, CB_RESET_CMD_SIZE);}/* This issues a Bulk-only Reset to the device in question, including * clearing the subsequent endpoint halts that may occur. */int usb_stor_Bulk_reset(struct us_data *us){	US_DEBUGP("%s called\n", __FUNCTION__);	return usb_stor_reset_common(us, US_BULK_RESET_REQUEST, 				 USB_TYPE_CLASS | USB_RECIP_INTERFACE,				 0, us->ifnum, NULL, 0);}

⌨️ 快捷键说明

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