本文整理汇总了C++中scsi_get_resid函数的典型用法代码示例。如果您正苦于以下问题:C++ scsi_get_resid函数的具体用法?C++ scsi_get_resid怎么用?C++ scsi_get_resid使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了scsi_get_resid函数的9个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: sas_scsi_task_done
static void sas_scsi_task_done(struct sas_task *task)
{
struct task_status_struct *ts = &task->task_status;
struct scsi_cmnd *sc = task->uldd_task;
int hs = 0, stat = 0;
if (unlikely(task->task_state_flags & SAS_TASK_STATE_ABORTED)) {
/* Aborted tasks will be completed by the error handler */
SAS_DPRINTK("task done but aborted\n");
return;
}
if (unlikely(!sc)) {
SAS_DPRINTK("task_done called with non existing SCSI cmnd!\n");
list_del_init(&task->list);
sas_free_task(task);
return;
}
if (ts->resp == SAS_TASK_UNDELIVERED) {
/* transport error */
hs = DID_NO_CONNECT;
} else { /* ts->resp == SAS_TASK_COMPLETE */
/* task delivered, what happened afterwards? */
switch (ts->stat) {
case SAS_DEV_NO_RESPONSE:
case SAS_INTERRUPTED:
case SAS_PHY_DOWN:
case SAS_NAK_R_ERR:
case SAS_OPEN_TO:
hs = DID_NO_CONNECT;
break;
case SAS_DATA_UNDERRUN:
scsi_set_resid(sc, ts->residual);
if (scsi_bufflen(sc) - scsi_get_resid(sc) < sc->underflow)
hs = DID_ERROR;
break;
case SAS_DATA_OVERRUN:
hs = DID_ERROR;
break;
case SAS_QUEUE_FULL:
hs = DID_SOFT_ERROR; /* retry */
break;
case SAS_DEVICE_UNKNOWN:
hs = DID_BAD_TARGET;
break;
case SAS_SG_ERR:
hs = DID_PARITY;
break;
case SAS_OPEN_REJECT:
if (ts->open_rej_reason == SAS_OREJ_RSVD_RETRY)
hs = DID_SOFT_ERROR; /* retry */
else
hs = DID_ERROR;
break;
case SAS_PROTO_RESPONSE:
SAS_DPRINTK("LLDD:%s sent SAS_PROTO_RESP for an SSP "
"task; please report this\n",
task->dev->port->ha->sas_ha_name);
break;
case SAS_ABORTED_TASK:
hs = DID_ABORT;
break;
case SAM_STAT_CHECK_CONDITION:
memcpy(sc->sense_buffer, ts->buf,
min(SCSI_SENSE_BUFFERSIZE, ts->buf_valid_size));
stat = SAM_STAT_CHECK_CONDITION;
break;
default:
stat = ts->stat;
break;
}
}
ASSIGN_SAS_TASK(sc, NULL);
sc->result = (hs << 16) | stat;
list_del_init(&task->list);
sas_free_task(task);
sc->scsi_done(sc);
}
示例2: last_sector_hacks
/* There are so many devices that report the capacity incorrectly,
* this routine was written to counteract some of the resulting
* problems.
*/
static void last_sector_hacks(struct us_data *us, struct scsi_cmnd *srb)
{
struct gendisk *disk;
struct scsi_disk *sdkp;
u32 sector;
/* To Report "Medium Error: Record Not Found */
static unsigned char record_not_found[18] = {
[0] = 0x70, /* current error */
[2] = MEDIUM_ERROR, /* = 0x03 */
[7] = 0x0a, /* additional length */
[12] = 0x14 /* Record Not Found */
};
/* If last-sector problems can't occur, whether because the
* capacity was already decremented or because the device is
* known to report the correct capacity, then we don't need
* to do anything.
*/
if (!us->use_last_sector_hacks)
return;
/* Was this command a READ(10) or a WRITE(10)? */
if (srb->cmnd[0] != READ_10 && srb->cmnd[0] != WRITE_10)
goto done;
/* Did this command access the last sector? */
sector = (srb->cmnd[2] << 24) | (srb->cmnd[3] << 16) |
(srb->cmnd[4] << 8) | (srb->cmnd[5]);
disk = srb->request->rq_disk;
if (!disk)
goto done;
sdkp = scsi_disk(disk);
if (!sdkp)
goto done;
if (sector + 1 != sdkp->capacity)
goto done;
if (srb->result == SAM_STAT_GOOD && scsi_get_resid(srb) == 0) {
/* The command succeeded. We know this device doesn't
* have the last-sector bug, so stop checking it.
*/
us->use_last_sector_hacks = 0;
} else {
/* The command failed. Allow up to 3 retries in case this
* is some normal sort of failure. After that, assume the
* capacity is wrong and we're trying to access the sector
* beyond the end. Replace the result code and sense data
* with values that will cause the SCSI core to fail the
* command immediately, instead of going into an infinite
* (or even just a very long) retry loop.
*/
if (++us->last_sector_retries < 3)
return;
srb->result = SAM_STAT_CHECK_CONDITION;
memcpy(srb->sense_buffer, record_not_found,
sizeof(record_not_found));
}
done:
/* Don't reset the retry counter for TEST UNIT READY commands,
* because they get issued after device resets which might be
* caused by a failed last-sector access.
*/
if (srb->cmnd[0] != TEST_UNIT_READY)
us->last_sector_retries = 0;
}
示例3: usb_stor_invoke_transport
/* Invoke the transport and basic error-handling/recovery methods
*
* This is used by the protocol layers to actually send the message to
* the device and receive the response.
*/
void usb_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us)
{
int need_auto_sense;
int result;
/* send the command to the transport layer */
scsi_set_resid(srb, 0);
result = us->transport(srb, us);
/* if the command gets aborted by the higher layers, we need to
* short-circuit all other processing
*/
if (test_bit(US_FLIDX_TIMED_OUT, &us->dflags)) {
US_DEBUGP("-- command was aborted\n");
srb->result = DID_ABORT << 16;
goto Handle_Errors;
}
/* if there is a transport error, reset and don't auto-sense */
if (result == USB_STOR_TRANSPORT_ERROR) {
US_DEBUGP("-- transport indicates error, resetting\n");
srb->result = DID_ERROR << 16;
goto Handle_Errors;
}
/* if the transport provided its own sense data, don't auto-sense */
if (result == USB_STOR_TRANSPORT_NO_SENSE) {
srb->result = SAM_STAT_CHECK_CONDITION;
last_sector_hacks(us, srb);
return;
}
srb->result = SAM_STAT_GOOD;
/* Determine if we need to auto-sense
*
* I normally don't use a flag like this, but it's almost impossible
* to understand what's going on here if I don't.
*/
need_auto_sense = 0;
/*
* If we're running the CB transport, which is incapable
* of determining status on its own, we will auto-sense
* unless the operation involved a data-in transfer. Devices
* can signal most data-in errors by stalling the bulk-in pipe.
*/
if ((us->protocol == USB_PR_CB || us->protocol == USB_PR_DPCM_USB) &&
srb->sc_data_direction != DMA_FROM_DEVICE) {
US_DEBUGP("-- CB transport device requiring auto-sense\n");
need_auto_sense = 1;
}
/*
* If we have a failure, we're going to do a REQUEST_SENSE
* automatically. Note that we differentiate between a command
* "failure" and an "error" in the transport mechanism.
*/
if (result == USB_STOR_TRANSPORT_FAILED) {
US_DEBUGP("-- transport indicates command failure\n");
need_auto_sense = 1;
}
/*
* Determine if this device is SAT by seeing if the
* command executed successfully. Otherwise we'll have
* to wait for at least one CHECK_CONDITION to determine
* SANE_SENSE support
*/
if (unlikely((srb->cmnd[0] == ATA_16 || srb->cmnd[0] == ATA_12) &&
result == USB_STOR_TRANSPORT_GOOD &&
!(us->fflags & US_FL_SANE_SENSE) &&
!(us->fflags & US_FL_BAD_SENSE) &&
!(srb->cmnd[2] & 0x20))) {
US_DEBUGP("-- SAT supported, increasing auto-sense\n");
us->fflags |= US_FL_SANE_SENSE;
}
/*
* A short transfer on a command where we don't expect it
* is unusual, but it doesn't mean we need to auto-sense.
*/
if ((scsi_get_resid(srb) > 0) &&
!((srb->cmnd[0] == REQUEST_SENSE) ||
(srb->cmnd[0] == INQUIRY) ||
(srb->cmnd[0] == MODE_SENSE) ||
(srb->cmnd[0] == LOG_SENSE) ||
(srb->cmnd[0] == MODE_SENSE_10))) {
US_DEBUGP("-- unexpectedly short transfer\n");
}
/* Now, if we need to do the auto-sense, let's do it */
if (need_auto_sense) {
int temp_result;
struct scsi_eh_save ses;
//.........这里部分代码省略.........
示例4: nsp_inc_resid
static inline void nsp_inc_resid(struct scsi_cmnd *SCpnt, int residInc)
{
scsi_set_resid(SCpnt, scsi_get_resid(SCpnt) + residInc);
}
示例5: usb_stor_Bulk_transport
int usb_stor_Bulk_transport(struct 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 = scsi_bufflen(srb);
unsigned int residue;
int result;
int fake_sense = 0;
unsigned int cswlen;
unsigned int cbwlen = US_BULK_CB_WRAP_LEN;
/* Take care of BULK32 devices; set extra byte to 0 */
if (unlikely(us->fflags & US_FL_BULK32)) {
cbwlen = 32;
us->iobuf[31] = 0;
}
/* 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 == DMA_FROM_DEVICE ?
US_BULK_FLAG_IN : 0;
bcb->Tag = ++us->tag;
bcb->Lun = srb->device->lun;
if (us->fflags & 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, cbwlen, 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 */
/* Some USB-IDE converter chips need a 100us delay between the
* command phase and the data phase. Some devices need a little
* more than that, probably because of clock rate inaccuracies. */
if (unlikely(us->fflags & US_FL_GO_SLOW))
udelay(125);
if (transfer_length) {
unsigned int pipe = srb->sc_data_direction == DMA_FROM_DEVICE ?
us->recv_bulk_pipe : us->send_bulk_pipe;
result = usb_stor_bulk_srb(us, pipe, srb);
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;
/*
* Sometimes a device will mistakenly skip the data phase
* and go directly to the status phase without sending a
* zero-length packet. If we get a 13-byte response here,
* check whether it really is a CSW.
*/
if (result == USB_STOR_XFER_SHORT &&
srb->sc_data_direction == DMA_FROM_DEVICE &&
transfer_length - scsi_get_resid(srb) ==
US_BULK_CS_WRAP_LEN) {
struct scatterlist *sg = NULL;
unsigned int offset = 0;
if (usb_stor_access_xfer_buf((unsigned char *) bcs,
US_BULK_CS_WRAP_LEN, srb, &sg,
&offset, FROM_XFER_BUF) ==
US_BULK_CS_WRAP_LEN &&
bcs->Signature ==
cpu_to_le32(US_BULK_CS_SIGN)) {
US_DEBUGP("Device skipped data phase\n");
scsi_set_resid(srb, transfer_length);
goto skipped_data_phase;
}
}
}
/* See flow chart on pg 15 of the Bulk Only Transport spec for
* an explanation of how this code works.
*/
//.........这里部分代码省略.........
示例6: usb_stor_Bulk_transport
//.........这里部分代码省略.........
pipe = us->send_bulk_pipe;
result = usb_stor_bulk_srb(us, pipe, srb);
/* pr_info("Bulk data transfer result 0x%x\n", result); */
if (result == USB_STOR_XFER_ERROR)
return USB_STOR_TRANSPORT_ERROR;
if (result == USB_STOR_XFER_LONG)
fake_sense = 1;
}
/* get CSW for device status */
/* pr_info("Attempting to get CSW...\n"); */
result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, bcs,
US_BULK_CS_WRAP_LEN, &cswlen);
if (result == USB_STOR_XFER_SHORT && cswlen == 0) {
/* pr_info("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 */
/* pr_info("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 */
/* pr_info("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);
/* pr_info("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->Tag == us->tag ||
(us->fflags & US_FL_BULK_IGNORE_TAG)) ||
bcs->Status > US_BULK_STAT_PHASE) {
/* pr_info("Bulk logical error\n"); */
return USB_STOR_TRANSPORT_ERROR;
}
if (!us->bcs_signature) {
us->bcs_signature = bcs->Signature;
/* if (us->bcs_signature != cpu_to_le32(US_BULK_CS_SIGN)) */
/* pr_info("Learnt BCS signature 0x%08X\n",
le32_to_cpu(us->bcs_signature)); */
} else if (bcs->Signature != us->bcs_signature) {
/* pr_info("Signature mismatch: got %08X, expecting %08X\n",
le32_to_cpu(bcs->Signature),
le32_to_cpu(us->bcs_signature)); */
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 */
if (residue && !(us->fflags & US_FL_IGNORE_RESIDUE)) {
/* Heuristically detect devices that generate bogus residues
* by seeing what happens with INQUIRY and READ CAPACITY
* commands.
*/
if (bcs->Status == US_BULK_STAT_OK &&
scsi_get_resid(srb) == 0 &&
((srb->cmnd[0] == INQUIRY &&
transfer_length == 36) ||
(srb->cmnd[0] == READ_CAPACITY &&
transfer_length == 8))) {
us->fflags |= US_FL_IGNORE_RESIDUE;
} else {
residue = min(residue, transfer_length);
scsi_set_resid(srb, max(scsi_get_resid(srb),
(int) residue));
}
}
/* based on the status code, we report good or bad */
switch (bcs->Status) {
case US_BULK_STAT_OK:
if (fake_sense) {
memcpy(srb->sense_buffer, usb_stor_sense_invalidCDB,
sizeof(usb_stor_sense_invalidCDB));
return USB_STOR_TRANSPORT_NO_SENSE;
}
return USB_STOR_TRANSPORT_GOOD;
case US_BULK_STAT_FAIL:
return USB_STOR_TRANSPORT_FAILED;
case US_BULK_STAT_PHASE:
return USB_STOR_TRANSPORT_ERROR;
}
return USB_STOR_TRANSPORT_ERROR;
}
示例7: ENE_stor_invoke_transport
/*
* ENE_stor_invoke_transport()
*/
void ENE_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us)
{
int result = 0;
/* pr_info("transport --- ENE_stor_invoke_transport\n"); */
usb_stor_print_cmd(srb);
/* send the command to the transport layer */
scsi_set_resid(srb, 0);
if (!(us->MS_Status.Ready || us->SM_Status.Ready))
result = ENE_InitMedia(us);
if (us->Power_IsResum == true) {
result = ENE_InitMedia(us);
us->Power_IsResum = false;
}
if (us->MS_Status.Ready)
result = MS_SCSIIrp(us, srb);
if (us->SM_Status.Ready)
result = SM_SCSIIrp(us, srb);
/* if the command gets aborted by the higher layers,
we need to short-circuit all other processing */
if (test_bit(US_FLIDX_TIMED_OUT, &us->dflags)) {
/* pr_info("-- command was aborted\n"); */
srb->result = DID_ABORT << 16;
goto Handle_Errors;
}
/* if there is a transport error, reset and don't auto-sense */
if (result == USB_STOR_TRANSPORT_ERROR) {
/* pr_info("-- transport indicates error, resetting\n"); */
srb->result = DID_ERROR << 16;
goto Handle_Errors;
}
/* if the transport provided its own sense data, don't auto-sense */
if (result == USB_STOR_TRANSPORT_NO_SENSE) {
srb->result = SAM_STAT_CHECK_CONDITION;
return;
}
srb->result = SAM_STAT_GOOD;
if (result == USB_STOR_TRANSPORT_FAILED) {
/* pr_info("-- transport indicates command failure\n"); */
/* need_auto_sense = 1; */
BuildSenseBuffer(srb, us->SrbStatus);
srb->result = SAM_STAT_CHECK_CONDITION;
}
/* Did we transfer less than the minimum amount required? */
if (srb->result == SAM_STAT_GOOD && scsi_bufflen(srb) -
scsi_get_resid(srb) < srb->underflow)
srb->result = (DID_ERROR << 16);
/* v02 | (SUGGEST_RETRY << 24); */
return;
Handle_Errors:
scsi_lock(us_to_host(us));
set_bit(US_FLIDX_RESETTING, &us->dflags);
clear_bit(US_FLIDX_ABORTING, &us->dflags);
scsi_unlock(us_to_host(us));
mutex_unlock(&us->dev_mutex);
result = usb_stor_port_reset(us);
mutex_lock(&us->dev_mutex);
if (result < 0) {
scsi_lock(us_to_host(us));
usb_stor_report_device_reset(us);
scsi_unlock(us_to_host(us));
us->transport_reset(us);
}
clear_bit(US_FLIDX_RESETTING, &us->dflags);
}
示例8: usb_stor_invoke_transport
//.........这里部分代码省略.........
goto Handle_Errors;
}
/* if the transport provided its own sense data, don't auto-sense */
if (result == USB_STOR_TRANSPORT_NO_SENSE) {
srb->result = SAM_STAT_CHECK_CONDITION;
return;
}
srb->result = SAM_STAT_GOOD;
/* Determine if we need to auto-sense */
need_auto_sense = 0;
if ((us->protocol == USB_PR_CB || us->protocol == USB_PR_DPCM_USB) &&
srb->sc_data_direction != DMA_FROM_DEVICE) {
/* pr_info("-- CB transport device requiring auto-sense\n"); */
need_auto_sense = 1;
}
if (result == USB_STOR_TRANSPORT_FAILED) {
/* pr_info("-- transport indicates command failure\n"); */
need_auto_sense = 1;
}
/* Now, if we need to do the auto-sense, let's do it */
if (need_auto_sense) {
int temp_result;
struct scsi_eh_save ses;
pr_info("Issuing auto-REQUEST_SENSE\n");
scsi_eh_prep_cmnd(srb, &ses, NULL, 0, US_SENSE_SIZE);
/* we must do the protocol translation here */
if (us->subclass == USB_SC_RBC ||
us->subclass == USB_SC_SCSI ||
us->subclass == USB_SC_CYP_ATACB) {
srb->cmd_len = 6;
} else {
srb->cmd_len = 12;
}
/* issue the auto-sense command */
scsi_set_resid(srb, 0);
temp_result = us->transport(us->srb, us);
/* let's clean up right away */
scsi_eh_restore_cmnd(srb, &ses);
if (test_bit(US_FLIDX_TIMED_OUT, &us->dflags)) {
/* pr_info("-- auto-sense aborted\n"); */
srb->result = DID_ABORT << 16;
goto Handle_Errors;
}
if (temp_result != USB_STOR_TRANSPORT_GOOD) {
/* pr_info("-- auto-sense failure\n"); */
srb->result = DID_ERROR << 16;
if (!(us->fflags & US_FL_SCM_MULT_TARG))
goto Handle_Errors;
return;
}
/* set the result so the higher layers expect this data */
srb->result = SAM_STAT_CHECK_CONDITION;
if (result == USB_STOR_TRANSPORT_GOOD &&
(srb->sense_buffer[2] & 0xaf) == 0 &&
srb->sense_buffer[12] == 0 &&
srb->sense_buffer[13] == 0) {
srb->result = SAM_STAT_GOOD;
srb->sense_buffer[0] = 0x0;
}
}
/* Did we transfer less than the minimum amount required? */
if (srb->result == SAM_STAT_GOOD && scsi_bufflen(srb) -
scsi_get_resid(srb) < srb->underflow)
srb->result = (DID_ERROR << 16);
/* v02 | (SUGGEST_RETRY << 24); */
return;
Handle_Errors:
scsi_lock(us_to_host(us));
set_bit(US_FLIDX_RESETTING, &us->dflags);
clear_bit(US_FLIDX_ABORTING, &us->dflags);
scsi_unlock(us_to_host(us));
mutex_unlock(&us->dev_mutex);
result = usb_stor_port_reset(us);
mutex_lock(&us->dev_mutex);
if (result < 0) {
scsi_lock(us_to_host(us));
usb_stor_report_device_reset(us);
scsi_unlock(us_to_host(us));
us->transport_reset(us);
}
clear_bit(US_FLIDX_RESETTING, &us->dflags);
}
示例9: usb_stor_invoke_transport
/* Invoke the transport and basic error-handling/recovery methods
*
* This is used by the protocol layers to actually send the message to
* the device and receive the response.
*/
void usb_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us)
{
int need_auto_sense;
int result;
/* send the command to the transport layer */
scsi_set_resid(srb, 0);
result = us->transport(srb, us);
/* if the command gets aborted by the higher layers, we need to
* short-circuit all other processing
*/
if (test_bit(US_FLIDX_TIMED_OUT, &us->dflags)) {
US_DEBUGP("-- command was aborted\n");
srb->result = DID_ABORT << 16;
goto Handle_Errors;
}
/* if there is a transport error, reset and don't auto-sense */
if (result == USB_STOR_TRANSPORT_ERROR) {
US_DEBUGP("-- transport indicates error, resetting\n");
srb->result = DID_ERROR << 16;
goto Handle_Errors;
}
/* if the transport provided its own sense data, don't auto-sense */
if (result == USB_STOR_TRANSPORT_NO_SENSE) {
srb->result = SAM_STAT_CHECK_CONDITION;
last_sector_hacks(us, srb);
return;
}
srb->result = SAM_STAT_GOOD;
/* Determine if we need to auto-sense
*
* I normally don't use a flag like this, but it's almost impossible
* to understand what's going on here if I don't.
*/
need_auto_sense = 0;
/*
* If we're running the CB transport, which is incapable
* of determining status on its own, we will auto-sense
* unless the operation involved a data-in transfer. Devices
* can signal most data-in errors by stalling the bulk-in pipe.
*/
if ((us->protocol == US_PR_CB || us->protocol == US_PR_DPCM_USB) &&
srb->sc_data_direction != DMA_FROM_DEVICE) {
US_DEBUGP("-- CB transport device requiring auto-sense\n");
need_auto_sense = 1;
}
/*
* If we have a failure, we're going to do a REQUEST_SENSE
* automatically. Note that we differentiate between a command
* "failure" and an "error" in the transport mechanism.
*/
if (result == USB_STOR_TRANSPORT_FAILED) {
US_DEBUGP("-- transport indicates command failure\n");
need_auto_sense = 1;
}
/*
* A short transfer on a command where we don't expect it
* is unusual, but it doesn't mean we need to auto-sense.
*/
if ((scsi_get_resid(srb) > 0) &&
!((srb->cmnd[0] == REQUEST_SENSE) ||
(srb->cmnd[0] == INQUIRY) ||
(srb->cmnd[0] == MODE_SENSE) ||
(srb->cmnd[0] == LOG_SENSE) ||
(srb->cmnd[0] == MODE_SENSE_10))) {
US_DEBUGP("-- unexpectedly short transfer\n");
}
/* Now, if we need to do the auto-sense, let's do it */
if (need_auto_sense) {
int temp_result;
struct scsi_eh_save ses;
US_DEBUGP("Issuing auto-REQUEST_SENSE\n");
scsi_eh_prep_cmnd(srb, &ses, NULL, 0, US_SENSE_SIZE);
/* FIXME: we must do the protocol translation here */
if (us->subclass == US_SC_RBC || us->subclass == US_SC_SCSI ||
us->subclass == US_SC_CYP_ATACB)
srb->cmd_len = 6;
else
srb->cmd_len = 12;
/* issue the auto-sense command */
scsi_set_resid(srb, 0);
temp_result = us->transport(us->srb, us);
//.........这里部分代码省略.........