Merge branch '5.14/scsi-result' into 5.14/scsi-staging

Include Hannes' SCSI command result rework in the staging branch.

[mkp: remove DRIVER_SENSE from mpi3mr]

Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
Martin K. Petersen 2021-06-02 01:33:12 -04:00
commit 1ff28f229b
84 changed files with 914 additions and 1082 deletions

View File

@ -1172,10 +1172,9 @@ Members of interest:
of 0 implies a successfully completed command (and all of 0 implies a successfully completed command (and all
data (if any) has been transferred to or from the SCSI data (if any) has been transferred to or from the SCSI
target device). 'result' is a 32 bit unsigned integer that target device). 'result' is a 32 bit unsigned integer that
can be viewed as 4 related bytes. The SCSI status value is can be viewed as 2 related bytes. The SCSI status value is
in the LSB. See include/scsi/scsi.h status_byte(), in the LSB. See include/scsi/scsi.h status_byte() and
msg_byte(), host_byte() and driver_byte() macros and host_byte() macros and related constants.
related constants.
sense_buffer sense_buffer
- an array (maximum size: SCSI_SENSE_BUFFERSIZE bytes) that - an array (maximum size: SCSI_SENSE_BUFFERSIZE bytes) that
should be written when the SCSI status (LSB of 'result') should be written when the SCSI status (LSB of 'result')

View File

@ -84,7 +84,7 @@ static int bsg_transport_complete_rq(struct request *rq, struct sg_io_v4 *hdr)
*/ */
hdr->device_status = job->result & 0xff; hdr->device_status = job->result & 0xff;
hdr->transport_status = host_byte(job->result); hdr->transport_status = host_byte(job->result);
hdr->driver_status = driver_byte(job->result); hdr->driver_status = 0;
hdr->info = 0; hdr->info = 0;
if (hdr->device_status || hdr->transport_status || hdr->driver_status) if (hdr->device_status || hdr->transport_status || hdr->driver_status)
hdr->info |= SG_INFO_CHECK; hdr->info |= SG_INFO_CHECK;

View File

@ -96,7 +96,9 @@ static int bsg_scsi_complete_rq(struct request *rq, struct sg_io_v4 *hdr)
*/ */
hdr->device_status = sreq->result & 0xff; hdr->device_status = sreq->result & 0xff;
hdr->transport_status = host_byte(sreq->result); hdr->transport_status = host_byte(sreq->result);
hdr->driver_status = driver_byte(sreq->result); hdr->driver_status = 0;
if (scsi_status_is_check_condition(sreq->result))
hdr->driver_status = DRIVER_SENSE;
hdr->info = 0; hdr->info = 0;
if (hdr->device_status || hdr->transport_status || hdr->driver_status) if (hdr->device_status || hdr->transport_status || hdr->driver_status)
hdr->info |= SG_INFO_CHECK; hdr->info |= SG_INFO_CHECK;

View File

@ -254,9 +254,11 @@ static int blk_complete_sghdr_rq(struct request *rq, struct sg_io_hdr *hdr,
*/ */
hdr->status = req->result & 0xff; hdr->status = req->result & 0xff;
hdr->masked_status = status_byte(req->result); hdr->masked_status = status_byte(req->result);
hdr->msg_status = msg_byte(req->result); hdr->msg_status = COMMAND_COMPLETE;
hdr->host_status = host_byte(req->result); hdr->host_status = host_byte(req->result);
hdr->driver_status = driver_byte(req->result); hdr->driver_status = 0;
if (scsi_status_is_check_condition(hdr->status))
hdr->driver_status = DRIVER_SENSE;
hdr->info = 0; hdr->info = 0;
if (hdr->masked_status || hdr->host_status || hdr->driver_status) if (hdr->masked_status || hdr->host_status || hdr->driver_status)
hdr->info |= SG_INFO_CHECK; hdr->info |= SG_INFO_CHECK;
@ -484,9 +486,10 @@ int sg_scsi_ioctl(struct request_queue *q, struct gendisk *disk, fmode_t mode,
break; break;
} }
if (bytes && blk_rq_map_kern(q, rq, buffer, bytes, GFP_NOIO)) { if (bytes) {
err = DRIVER_ERROR << 24; err = blk_rq_map_kern(q, rq, buffer, bytes, GFP_NOIO);
goto error; if (err)
goto error;
} }
blk_execute_rq(disk, rq, 0); blk_execute_rq(disk, rq, 0);

View File

@ -196,9 +196,7 @@ void ata_scsi_set_sense(struct ata_device *dev, struct scsi_cmnd *cmd,
if (!cmd) if (!cmd)
return; return;
cmd->result = (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION; scsi_build_sense(cmd, d_sense, sk, asc, ascq);
scsi_build_sense_buffer(d_sense, cmd->sense_buffer, sk, asc, ascq);
} }
void ata_scsi_set_sense_information(struct ata_device *dev, void ata_scsi_set_sense_information(struct ata_device *dev,
@ -409,13 +407,16 @@ int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg)
cmd_result = scsi_execute(scsidev, scsi_cmd, data_dir, argbuf, argsize, cmd_result = scsi_execute(scsidev, scsi_cmd, data_dir, argbuf, argsize,
sensebuf, &sshdr, (10*HZ), 5, 0, 0, NULL); sensebuf, &sshdr, (10*HZ), 5, 0, 0, NULL);
if (driver_byte(cmd_result) == DRIVER_SENSE) {/* sense data available */ if (cmd_result < 0) {
rc = cmd_result;
goto error;
}
if (scsi_sense_valid(&sshdr)) {/* sense data available */
u8 *desc = sensebuf + 8; u8 *desc = sensebuf + 8;
cmd_result &= ~(0xFF<<24); /* DRIVER_SENSE is not an error */
/* If we set cc then ATA pass-through will cause a /* If we set cc then ATA pass-through will cause a
* check condition even if no error. Filter that. */ * check condition even if no error. Filter that. */
if (cmd_result & SAM_STAT_CHECK_CONDITION) { if (scsi_status_is_check_condition(cmd_result)) {
if (sshdr.sense_key == RECOVERED_ERROR && if (sshdr.sense_key == RECOVERED_ERROR &&
sshdr.asc == 0 && sshdr.ascq == 0x1d) sshdr.asc == 0 && sshdr.ascq == 0x1d)
cmd_result &= ~SAM_STAT_CHECK_CONDITION; cmd_result &= ~SAM_STAT_CHECK_CONDITION;
@ -490,9 +491,12 @@ int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg)
cmd_result = scsi_execute(scsidev, scsi_cmd, DMA_NONE, NULL, 0, cmd_result = scsi_execute(scsidev, scsi_cmd, DMA_NONE, NULL, 0,
sensebuf, &sshdr, (10*HZ), 5, 0, 0, NULL); sensebuf, &sshdr, (10*HZ), 5, 0, 0, NULL);
if (driver_byte(cmd_result) == DRIVER_SENSE) {/* sense data available */ if (cmd_result < 0) {
rc = cmd_result;
goto error;
}
if (scsi_sense_valid(&sshdr)) {/* sense data available */
u8 *desc = sensebuf + 8; u8 *desc = sensebuf + 8;
cmd_result &= ~(0xFF<<24); /* DRIVER_SENSE is not an error */
/* If we set cc then ATA pass-through will cause a /* If we set cc then ATA pass-through will cause a
* check condition even if no error. Filter that. */ * check condition even if no error. Filter that. */
@ -638,7 +642,7 @@ static struct ata_queued_cmd *ata_scsi_qc_new(struct ata_device *dev,
if (cmd->request->rq_flags & RQF_QUIET) if (cmd->request->rq_flags & RQF_QUIET)
qc->flags |= ATA_QCFLAG_QUIET; qc->flags |= ATA_QCFLAG_QUIET;
} else { } else {
cmd->result = (DID_OK << 16) | (QUEUE_FULL << 1); cmd->result = (DID_OK << 16) | SAM_STAT_TASK_SET_FULL;
cmd->scsi_done(cmd); cmd->scsi_done(cmd);
} }
@ -858,8 +862,6 @@ static void ata_gen_passthru_sense(struct ata_queued_cmd *qc)
memset(sb, 0, SCSI_SENSE_BUFFERSIZE); memset(sb, 0, SCSI_SENSE_BUFFERSIZE);
cmd->result = (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION;
/* /*
* Use ata_to_sense_error() to map status register bits * Use ata_to_sense_error() to map status register bits
* onto sense key, asc & ascq. * onto sense key, asc & ascq.
@ -874,8 +876,7 @@ static void ata_gen_passthru_sense(struct ata_queued_cmd *qc)
* ATA PASS-THROUGH INFORMATION AVAILABLE * ATA PASS-THROUGH INFORMATION AVAILABLE
* Always in descriptor format sense. * Always in descriptor format sense.
*/ */
scsi_build_sense_buffer(1, cmd->sense_buffer, scsi_build_sense(cmd, 1, RECOVERED_ERROR, 0, 0x1D);
RECOVERED_ERROR, 0, 0x1D);
} }
if ((cmd->sense_buffer[0] & 0x7f) >= 0x72) { if ((cmd->sense_buffer[0] & 0x7f) >= 0x72) {
@ -957,8 +958,6 @@ static void ata_gen_ata_sense(struct ata_queued_cmd *qc)
memset(sb, 0, SCSI_SENSE_BUFFERSIZE); memset(sb, 0, SCSI_SENSE_BUFFERSIZE);
cmd->result = (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION;
if (ata_dev_disabled(dev)) { if (ata_dev_disabled(dev)) {
/* Device disabled after error recovery */ /* Device disabled after error recovery */
/* LOGICAL UNIT NOT READY, HARD RESET REQUIRED */ /* LOGICAL UNIT NOT READY, HARD RESET REQUIRED */
@ -4196,7 +4195,6 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd)
case REQUEST_SENSE: case REQUEST_SENSE:
ata_scsi_set_sense(dev, cmd, 0, 0, 0); ata_scsi_set_sense(dev, cmd, 0, 0, 0);
cmd->result = (DRIVER_SENSE << 24);
break; break;
/* if we reach this, then writeback caching is disabled, /* if we reach this, then writeback caching is disabled,

View File

@ -2232,7 +2232,7 @@ static int srp_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *scmnd)
* to reduce queue depth temporarily. * to reduce queue depth temporarily.
*/ */
scmnd->result = len == -ENOMEM ? scmnd->result = len == -ENOMEM ?
DID_OK << 16 | QUEUE_FULL << 1 : DID_ERROR << 16; DID_OK << 16 | SAM_STAT_TASK_SET_FULL : DID_ERROR << 16;
goto err_iu; goto err_iu;
} }

View File

@ -856,10 +856,7 @@ void zfcp_scsi_set_prot(struct zfcp_adapter *adapter)
*/ */
void zfcp_scsi_dif_sense_error(struct scsi_cmnd *scmd, int ascq) void zfcp_scsi_dif_sense_error(struct scsi_cmnd *scmd, int ascq)
{ {
scsi_build_sense_buffer(1, scmd->sense_buffer, scsi_build_sense(scmd, 1, ILLEGAL_REQUEST, 0x10, ascq);
ILLEGAL_REQUEST, 0x10, ascq);
set_driver_byte(scmd, DRIVER_SENSE);
scmd->result |= SAM_STAT_CHECK_CONDITION;
set_host_byte(scmd, DID_SOFT_ERROR); set_host_byte(scmd, DID_SOFT_ERROR);
} }

View File

@ -1338,7 +1338,7 @@ static irqreturn_t twa_interrupt(int irq, void *dev_instance)
/* If error, command failed */ /* If error, command failed */
if (error == 1) { if (error == 1) {
/* Ask for a host reset */ /* Ask for a host reset */
cmd->result = (DID_OK << 16) | (CHECK_CONDITION << 1); cmd->result = (DID_OK << 16) | SAM_STAT_CHECK_CONDITION;
} }
/* Report residual bytes for single sgl */ /* Report residual bytes for single sgl */

View File

@ -429,7 +429,7 @@ static int tw_decode_sense(TW_Device_Extension *tw_dev, int request_id, int fill
/* Additional sense code qualifier */ /* Additional sense code qualifier */
tw_dev->srb[request_id]->sense_buffer[13] = tw_sense_table[i][3]; tw_dev->srb[request_id]->sense_buffer[13] = tw_sense_table[i][3];
tw_dev->srb[request_id]->result = (DID_OK << 16) | (CHECK_CONDITION << 1); tw_dev->srb[request_id]->result = (DID_OK << 16) | SAM_STAT_CHECK_CONDITION;
return TW_ISR_DONT_RESULT; /* Special case for isr to not over-write result */ return TW_ISR_DONT_RESULT; /* Special case for isr to not over-write result */
} }
} }
@ -1977,7 +1977,7 @@ static int tw_scsi_queue_lck(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_c
printk(KERN_NOTICE "3w-xxxx: scsi%d: Unknown scsi opcode: 0x%x\n", tw_dev->host->host_no, *command); printk(KERN_NOTICE "3w-xxxx: scsi%d: Unknown scsi opcode: 0x%x\n", tw_dev->host->host_no, *command);
tw_dev->state[request_id] = TW_S_COMPLETED; tw_dev->state[request_id] = TW_S_COMPLETED;
tw_state_request_finish(tw_dev, request_id); tw_state_request_finish(tw_dev, request_id);
scsi_build_sense_buffer(1, SCpnt->sense_buffer, ILLEGAL_REQUEST, 0x20, 0); scsi_build_sense(SCpnt, 1, ILLEGAL_REQUEST, 0x20, 0);
done(SCpnt); done(SCpnt);
retval = 0; retval = 0;
} }
@ -2159,7 +2159,7 @@ static irqreturn_t tw_interrupt(int irq, void *dev_instance)
/* If error, command failed */ /* If error, command failed */
if (error == 1) { if (error == 1) {
/* Ask for a host reset */ /* Ask for a host reset */
tw_dev->srb[request_id]->result = (DID_OK << 16) | (CHECK_CONDITION << 1); tw_dev->srb[request_id]->result = (DID_OK << 16) | SAM_STAT_CHECK_CONDITION;
} }
/* Now complete the io */ /* Now complete the io */

View File

@ -978,10 +978,10 @@ process_script_interrupt(__u32 dsps, __u32 dsp, struct scsi_cmnd *SCp,
if (NCR_700_get_tag_neg_state(SCp->device) == NCR_700_DURING_TAG_NEGOTIATION) if (NCR_700_get_tag_neg_state(SCp->device) == NCR_700_DURING_TAG_NEGOTIATION)
NCR_700_set_tag_neg_state(SCp->device, NCR_700_set_tag_neg_state(SCp->device,
NCR_700_FINISHED_TAG_NEGOTIATION); NCR_700_FINISHED_TAG_NEGOTIATION);
/* check for contingent allegiance conditions */ /* check for contingent allegiance conditions */
if (hostdata->status[0] >> 1 == CHECK_CONDITION || if (hostdata->status[0] == SAM_STAT_CHECK_CONDITION ||
hostdata->status[0] >> 1 == COMMAND_TERMINATED) { hostdata->status[0] == SAM_STAT_COMMAND_TERMINATED) {
struct NCR_700_command_slot *slot = struct NCR_700_command_slot *slot =
(struct NCR_700_command_slot *)SCp->host_scribble; (struct NCR_700_command_slot *)SCp->host_scribble;
if(slot->flags == NCR_700_FLAG_AUTOSENSE) { if(slot->flags == NCR_700_FLAG_AUTOSENSE) {

View File

@ -304,40 +304,12 @@ typedef struct SCCBscam_info {
} SCCBSCAM_INFO; } SCCBSCAM_INFO;
#define SCSI_REQUEST_SENSE 0x03
#define SCSI_READ 0x08
#define SCSI_WRITE 0x0A
#define SCSI_START_STOP_UNIT 0x1B
#define SCSI_READ_EXTENDED 0x28
#define SCSI_WRITE_EXTENDED 0x2A
#define SCSI_WRITE_AND_VERIFY 0x2E
#define SSGOOD 0x00
#define SSCHECK 0x02
#define SSQ_FULL 0x28
#define SMCMD_COMP 0x00
#define SMEXT 0x01
#define SMSAVE_DATA_PTR 0x02
#define SMREST_DATA_PTR 0x03
#define SMDISC 0x04
#define SMABORT 0x06
#define SMREJECT 0x07
#define SMNO_OP 0x08
#define SMPARITY 0x09
#define SMDEV_RESET 0x0C
#define SMABORT_TAG 0x0D
#define SMINIT_RECOVERY 0x0F
#define SMREL_RECOVERY 0x10
#define SMIDENT 0x80 #define SMIDENT 0x80
#define DISC_PRIV 0x40 #define DISC_PRIV 0x40
#define SMSYNC 0x01
#define SMWDTR 0x03
#define SM8BIT 0x00 #define SM8BIT 0x00
#define SM16BIT 0x01 #define SM16BIT 0x01
#define SMIGNORWR 0x23 /* Ignore Wide Residue */
#define SIX_BYTE_CMD 0x06 #define SIX_BYTE_CMD 0x06
#define TWELVE_BYTE_CMD 0x0C #define TWELVE_BYTE_CMD 0x0C
@ -1660,7 +1632,7 @@ static int FlashPoint_AbortCCB(void *pCurrCard, struct sccb *p_Sccb)
p_Sccb->Sccb_scsistat = p_Sccb->Sccb_scsistat =
ABORT_ST; ABORT_ST;
p_Sccb->Sccb_scsimsg = p_Sccb->Sccb_scsimsg =
SMABORT_TAG; ABORT_TASK;
if (((struct sccb_card *) if (((struct sccb_card *)
pCurrCard)->currentSCCB == pCurrCard)->currentSCCB ==
@ -1812,7 +1784,7 @@ static int FlashPoint_HandleInterrupt(void *pcard)
FPT_phaseChkFifo(ioport, thisCard); FPT_phaseChkFifo(ioport, thisCard);
if (RD_HARPOON(ioport + hp_gp_reg_1) == if (RD_HARPOON(ioport + hp_gp_reg_1) ==
SMSAVE_DATA_PTR) { SAVE_POINTERS) {
WR_HARPOON(ioport + hp_gp_reg_1, 0x00); WR_HARPOON(ioport + hp_gp_reg_1, 0x00);
currSCCB->Sccb_XferState |= F_NO_DATA_YET; currSCCB->Sccb_XferState |= F_NO_DATA_YET;
@ -1865,7 +1837,7 @@ static int FlashPoint_HandleInterrupt(void *pcard)
FPT_phaseChkFifo(ioport, thisCard); FPT_phaseChkFifo(ioport, thisCard);
if (RD_HARPOON(ioport + hp_gp_reg_1) == if (RD_HARPOON(ioport + hp_gp_reg_1) ==
SMSAVE_DATA_PTR) { SAVE_POINTERS) {
WR_HARPOON(ioport + hp_gp_reg_1, 0x00); WR_HARPOON(ioport + hp_gp_reg_1, 0x00);
currSCCB->Sccb_XferState |= currSCCB->Sccb_XferState |=
F_NO_DATA_YET; F_NO_DATA_YET;
@ -2258,7 +2230,7 @@ static unsigned char FPT_sfm(u32 port, struct sccb *pCurrSCCB)
WR_HARPOON(port + hp_fiforead, 0); WR_HARPOON(port + hp_fiforead, 0);
WR_HARPOON(port + hp_fifowrite, 0); WR_HARPOON(port + hp_fifowrite, 0);
if (pCurrSCCB != NULL) { if (pCurrSCCB != NULL) {
pCurrSCCB->Sccb_scsimsg = SMPARITY; pCurrSCCB->Sccb_scsimsg = MSG_PARITY_ERROR;
} }
message = 0x00; message = 0x00;
do { do {
@ -2411,7 +2383,7 @@ static void FPT_ssel(u32 port, unsigned char p_card)
WRW_HARPOON((port + ID_MSG_STRT + 2), BRH_OP + ALWAYS + NP); WRW_HARPOON((port + ID_MSG_STRT + 2), BRH_OP + ALWAYS + NP);
currSCCB->Sccb_scsimsg = SMDEV_RESET; currSCCB->Sccb_scsimsg = TARGET_RESET;
WR_HARPOON(port + hp_autostart_3, (SELECT + SELCHK_STRT)); WR_HARPOON(port + hp_autostart_3, (SELECT + SELCHK_STRT));
auto_loaded = 1; auto_loaded = 1;
@ -2758,9 +2730,9 @@ static void FPT_sres(u32 port, unsigned char p_card,
if (message == 0) { if (message == 0) {
msgRetryCount++; msgRetryCount++;
if (msgRetryCount == 1) { if (msgRetryCount == 1) {
FPT_SendMsg(port, SMPARITY); FPT_SendMsg(port, MSG_PARITY_ERROR);
} else { } else {
FPT_SendMsg(port, SMDEV_RESET); FPT_SendMsg(port, TARGET_RESET);
FPT_sssyncv(port, our_target, NARROW_SCSI, FPT_sssyncv(port, our_target, NARROW_SCSI,
currTar_Info); currTar_Info);
@ -2860,8 +2832,8 @@ static void FPT_SendMsg(u32 port, unsigned char message)
WR_HARPOON(port + hp_portctrl_0, 0x00); WR_HARPOON(port + hp_portctrl_0, 0x00);
if ((message == SMABORT) || (message == SMDEV_RESET) || if ((message == ABORT_TASK_SET) || (message == TARGET_RESET) ||
(message == SMABORT_TAG)) { (message == ABORT_TASK)) {
while (! while (!
(RDW_HARPOON((port + hp_intstat)) & (RDW_HARPOON((port + hp_intstat)) &
(BUS_FREE | PHASE))) { (BUS_FREE | PHASE))) {
@ -2893,7 +2865,7 @@ static void FPT_sdecm(unsigned char message, u32 port, unsigned char p_card)
currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID]; currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
if (message == SMREST_DATA_PTR) { if (message == RESTORE_POINTERS) {
if (!(currSCCB->Sccb_XferState & F_NO_DATA_YET)) { if (!(currSCCB->Sccb_XferState & F_NO_DATA_YET)) {
currSCCB->Sccb_ATC = currSCCB->Sccb_savedATC; currSCCB->Sccb_ATC = currSCCB->Sccb_savedATC;
@ -2905,7 +2877,7 @@ static void FPT_sdecm(unsigned char message, u32 port, unsigned char p_card)
(AUTO_IMMED + DISCONNECT_START)); (AUTO_IMMED + DISCONNECT_START));
} }
else if (message == SMCMD_COMP) { else if (message == COMMAND_COMPLETE) {
if (currSCCB->Sccb_scsistat == SELECT_Q_ST) { if (currSCCB->Sccb_scsistat == SELECT_Q_ST) {
currTar_Info->TarStatus &= currTar_Info->TarStatus &=
@ -2917,15 +2889,16 @@ static void FPT_sdecm(unsigned char message, u32 port, unsigned char p_card)
} }
else if ((message == SMNO_OP) || (message >= SMIDENT) else if ((message == NOP) || (message >= IDENTIFY_BASE) ||
|| (message == SMINIT_RECOVERY) || (message == SMREL_RECOVERY)) { (message == INITIATE_RECOVERY) ||
(message == RELEASE_RECOVERY)) {
ACCEPT_MSG(port); ACCEPT_MSG(port);
WR_HARPOON(port + hp_autostart_1, WR_HARPOON(port + hp_autostart_1,
(AUTO_IMMED + DISCONNECT_START)); (AUTO_IMMED + DISCONNECT_START));
} }
else if (message == SMREJECT) { else if (message == MESSAGE_REJECT) {
if ((currSCCB->Sccb_scsistat == SELECT_SN_ST) || if ((currSCCB->Sccb_scsistat == SELECT_SN_ST) ||
(currSCCB->Sccb_scsistat == SELECT_WN_ST) || (currSCCB->Sccb_scsistat == SELECT_WN_ST) ||
@ -3026,19 +2999,19 @@ static void FPT_sdecm(unsigned char message, u32 port, unsigned char p_card)
} }
} }
else if (message == SMEXT) { else if (message == EXTENDED_MESSAGE) {
ACCEPT_MSG(port); ACCEPT_MSG(port);
FPT_shandem(port, p_card, currSCCB); FPT_shandem(port, p_card, currSCCB);
} }
else if (message == SMIGNORWR) { else if (message == IGNORE_WIDE_RESIDUE) {
ACCEPT_MSG(port); /* ACK the RESIDUE MSG */ ACCEPT_MSG(port); /* ACK the RESIDUE MSG */
message = FPT_sfm(port, currSCCB); message = FPT_sfm(port, currSCCB);
if (currSCCB->Sccb_scsimsg != SMPARITY) if (currSCCB->Sccb_scsimsg != MSG_PARITY_ERROR)
ACCEPT_MSG(port); ACCEPT_MSG(port);
WR_HARPOON(port + hp_autostart_1, WR_HARPOON(port + hp_autostart_1,
(AUTO_IMMED + DISCONNECT_START)); (AUTO_IMMED + DISCONNECT_START));
@ -3047,7 +3020,7 @@ static void FPT_sdecm(unsigned char message, u32 port, unsigned char p_card)
else { else {
currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL; currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
currSCCB->Sccb_scsimsg = SMREJECT; currSCCB->Sccb_scsimsg = MESSAGE_REJECT;
ACCEPT_MSG_ATN(port); ACCEPT_MSG_ATN(port);
WR_HARPOON(port + hp_autostart_1, WR_HARPOON(port + hp_autostart_1,
@ -3073,7 +3046,7 @@ static void FPT_shandem(u32 port, unsigned char p_card, struct sccb *pCurrSCCB)
message = FPT_sfm(port, pCurrSCCB); message = FPT_sfm(port, pCurrSCCB);
if (message) { if (message) {
if (message == SMSYNC) { if (message == EXTENDED_SDTR) {
if (length == 0x03) { if (length == 0x03) {
@ -3081,10 +3054,10 @@ static void FPT_shandem(u32 port, unsigned char p_card, struct sccb *pCurrSCCB)
FPT_stsyncn(port, p_card); FPT_stsyncn(port, p_card);
} else { } else {
pCurrSCCB->Sccb_scsimsg = SMREJECT; pCurrSCCB->Sccb_scsimsg = MESSAGE_REJECT;
ACCEPT_MSG_ATN(port); ACCEPT_MSG_ATN(port);
} }
} else if (message == SMWDTR) { } else if (message == EXTENDED_WDTR) {
if (length == 0x02) { if (length == 0x02) {
@ -3092,7 +3065,7 @@ static void FPT_shandem(u32 port, unsigned char p_card, struct sccb *pCurrSCCB)
FPT_stwidn(port, p_card); FPT_stwidn(port, p_card);
} else { } else {
pCurrSCCB->Sccb_scsimsg = SMREJECT; pCurrSCCB->Sccb_scsimsg = MESSAGE_REJECT;
ACCEPT_MSG_ATN(port); ACCEPT_MSG_ATN(port);
WR_HARPOON(port + hp_autostart_1, WR_HARPOON(port + hp_autostart_1,
@ -3101,20 +3074,20 @@ static void FPT_shandem(u32 port, unsigned char p_card, struct sccb *pCurrSCCB)
} }
} else { } else {
pCurrSCCB->Sccb_scsimsg = SMREJECT; pCurrSCCB->Sccb_scsimsg = MESSAGE_REJECT;
ACCEPT_MSG_ATN(port); ACCEPT_MSG_ATN(port);
WR_HARPOON(port + hp_autostart_1, WR_HARPOON(port + hp_autostart_1,
(AUTO_IMMED + DISCONNECT_START)); (AUTO_IMMED + DISCONNECT_START));
} }
} else { } else {
if (pCurrSCCB->Sccb_scsimsg != SMPARITY) if (pCurrSCCB->Sccb_scsimsg != MSG_PARITY_ERROR)
ACCEPT_MSG(port); ACCEPT_MSG(port);
WR_HARPOON(port + hp_autostart_1, WR_HARPOON(port + hp_autostart_1,
(AUTO_IMMED + DISCONNECT_START)); (AUTO_IMMED + DISCONNECT_START));
} }
} else { } else {
if (pCurrSCCB->Sccb_scsimsg == SMPARITY) if (pCurrSCCB->Sccb_scsimsg == MSG_PARITY_ERROR)
WR_HARPOON(port + hp_autostart_1, WR_HARPOON(port + hp_autostart_1,
(AUTO_IMMED + DISCONNECT_START)); (AUTO_IMMED + DISCONNECT_START));
} }
@ -3148,10 +3121,10 @@ static unsigned char FPT_sisyncn(u32 port, unsigned char p_card,
WRW_HARPOON((port + ID_MSG_STRT + 2), BRH_OP + ALWAYS + CMDPZ); WRW_HARPOON((port + ID_MSG_STRT + 2), BRH_OP + ALWAYS + CMDPZ);
WRW_HARPOON((port + SYNC_MSGS + 0), WRW_HARPOON((port + SYNC_MSGS + 0),
(MPM_OP + AMSG_OUT + SMEXT)); (MPM_OP + AMSG_OUT + EXTENDED_MESSAGE));
WRW_HARPOON((port + SYNC_MSGS + 2), (MPM_OP + AMSG_OUT + 0x03)); WRW_HARPOON((port + SYNC_MSGS + 2), (MPM_OP + AMSG_OUT + 0x03));
WRW_HARPOON((port + SYNC_MSGS + 4), WRW_HARPOON((port + SYNC_MSGS + 4),
(MPM_OP + AMSG_OUT + SMSYNC)); (MPM_OP + AMSG_OUT + EXTENDED_SDTR));
if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_20MB) if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_20MB)
@ -3221,7 +3194,7 @@ static void FPT_stsyncn(u32 port, unsigned char p_card)
sync_msg = FPT_sfm(port, currSCCB); sync_msg = FPT_sfm(port, currSCCB);
if ((sync_msg == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY)) { if ((sync_msg == 0x00) && (currSCCB->Sccb_scsimsg == MSG_PARITY_ERROR)) {
WR_HARPOON(port + hp_autostart_1, WR_HARPOON(port + hp_autostart_1,
(AUTO_IMMED + DISCONNECT_START)); (AUTO_IMMED + DISCONNECT_START));
return; return;
@ -3231,7 +3204,7 @@ static void FPT_stsyncn(u32 port, unsigned char p_card)
offset = FPT_sfm(port, currSCCB); offset = FPT_sfm(port, currSCCB);
if ((offset == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY)) { if ((offset == 0x00) && (currSCCB->Sccb_scsimsg == MSG_PARITY_ERROR)) {
WR_HARPOON(port + hp_autostart_1, WR_HARPOON(port + hp_autostart_1,
(AUTO_IMMED + DISCONNECT_START)); (AUTO_IMMED + DISCONNECT_START));
return; return;
@ -3343,9 +3316,11 @@ static void FPT_sisyncr(u32 port, unsigned char sync_pulse,
unsigned char offset) unsigned char offset)
{ {
ARAM_ACCESS(port); ARAM_ACCESS(port);
WRW_HARPOON((port + SYNC_MSGS + 0), (MPM_OP + AMSG_OUT + SMEXT)); WRW_HARPOON((port + SYNC_MSGS + 0),
(MPM_OP + AMSG_OUT + EXTENDED_MESSAGE));
WRW_HARPOON((port + SYNC_MSGS + 2), (MPM_OP + AMSG_OUT + 0x03)); WRW_HARPOON((port + SYNC_MSGS + 2), (MPM_OP + AMSG_OUT + 0x03));
WRW_HARPOON((port + SYNC_MSGS + 4), (MPM_OP + AMSG_OUT + SMSYNC)); WRW_HARPOON((port + SYNC_MSGS + 4),
(MPM_OP + AMSG_OUT + EXTENDED_SDTR));
WRW_HARPOON((port + SYNC_MSGS + 6), (MPM_OP + AMSG_OUT + sync_pulse)); WRW_HARPOON((port + SYNC_MSGS + 6), (MPM_OP + AMSG_OUT + sync_pulse));
WRW_HARPOON((port + SYNC_MSGS + 8), (RAT_OP)); WRW_HARPOON((port + SYNC_MSGS + 8), (RAT_OP));
WRW_HARPOON((port + SYNC_MSGS + 10), (MPM_OP + AMSG_OUT + offset)); WRW_HARPOON((port + SYNC_MSGS + 10), (MPM_OP + AMSG_OUT + offset));
@ -3388,10 +3363,10 @@ static unsigned char FPT_siwidn(u32 port, unsigned char p_card)
WRW_HARPOON((port + ID_MSG_STRT + 2), BRH_OP + ALWAYS + CMDPZ); WRW_HARPOON((port + ID_MSG_STRT + 2), BRH_OP + ALWAYS + CMDPZ);
WRW_HARPOON((port + SYNC_MSGS + 0), WRW_HARPOON((port + SYNC_MSGS + 0),
(MPM_OP + AMSG_OUT + SMEXT)); (MPM_OP + AMSG_OUT + EXTENDED_MESSAGE));
WRW_HARPOON((port + SYNC_MSGS + 2), (MPM_OP + AMSG_OUT + 0x02)); WRW_HARPOON((port + SYNC_MSGS + 2), (MPM_OP + AMSG_OUT + 0x02));
WRW_HARPOON((port + SYNC_MSGS + 4), WRW_HARPOON((port + SYNC_MSGS + 4),
(MPM_OP + AMSG_OUT + SMWDTR)); (MPM_OP + AMSG_OUT + EXTENDED_WDTR));
WRW_HARPOON((port + SYNC_MSGS + 6), (RAT_OP)); WRW_HARPOON((port + SYNC_MSGS + 6), (RAT_OP));
WRW_HARPOON((port + SYNC_MSGS + 8), WRW_HARPOON((port + SYNC_MSGS + 8),
(MPM_OP + AMSG_OUT + SM16BIT)); (MPM_OP + AMSG_OUT + SM16BIT));
@ -3436,7 +3411,7 @@ static void FPT_stwidn(u32 port, unsigned char p_card)
width = FPT_sfm(port, currSCCB); width = FPT_sfm(port, currSCCB);
if ((width == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY)) { if ((width == 0x00) && (currSCCB->Sccb_scsimsg == MSG_PARITY_ERROR)) {
WR_HARPOON(port + hp_autostart_1, WR_HARPOON(port + hp_autostart_1,
(AUTO_IMMED + DISCONNECT_START)); (AUTO_IMMED + DISCONNECT_START));
return; return;
@ -3499,9 +3474,11 @@ static void FPT_stwidn(u32 port, unsigned char p_card)
static void FPT_siwidr(u32 port, unsigned char width) static void FPT_siwidr(u32 port, unsigned char width)
{ {
ARAM_ACCESS(port); ARAM_ACCESS(port);
WRW_HARPOON((port + SYNC_MSGS + 0), (MPM_OP + AMSG_OUT + SMEXT)); WRW_HARPOON((port + SYNC_MSGS + 0),
(MPM_OP + AMSG_OUT + EXTENDED_MESSAGE));
WRW_HARPOON((port + SYNC_MSGS + 2), (MPM_OP + AMSG_OUT + 0x02)); WRW_HARPOON((port + SYNC_MSGS + 2), (MPM_OP + AMSG_OUT + 0x02));
WRW_HARPOON((port + SYNC_MSGS + 4), (MPM_OP + AMSG_OUT + SMWDTR)); WRW_HARPOON((port + SYNC_MSGS + 4),
(MPM_OP + AMSG_OUT + EXTENDED_WDTR));
WRW_HARPOON((port + SYNC_MSGS + 6), (RAT_OP)); WRW_HARPOON((port + SYNC_MSGS + 6), (RAT_OP));
WRW_HARPOON((port + SYNC_MSGS + 8), (MPM_OP + AMSG_OUT + width)); WRW_HARPOON((port + SYNC_MSGS + 8), (MPM_OP + AMSG_OUT + width));
WRW_HARPOON((port + SYNC_MSGS + 10), (BRH_OP + ALWAYS + NP)); WRW_HARPOON((port + SYNC_MSGS + 10), (BRH_OP + ALWAYS + NP));
@ -3682,7 +3659,7 @@ static void FPT_ssenss(struct sccb_card *pCurrCard)
} }
currSCCB->CdbLength = SIX_BYTE_CMD; currSCCB->CdbLength = SIX_BYTE_CMD;
currSCCB->Cdb[0] = SCSI_REQUEST_SENSE; currSCCB->Cdb[0] = REQUEST_SENSE;
currSCCB->Cdb[1] = currSCCB->Cdb[1] & (unsigned char)0xE0; /*Keep LUN. */ currSCCB->Cdb[1] = currSCCB->Cdb[1] & (unsigned char)0xE0; /*Keep LUN. */
currSCCB->Cdb[2] = 0x00; currSCCB->Cdb[2] = 0x00;
currSCCB->Cdb[3] = 0x00; currSCCB->Cdb[3] = 0x00;
@ -3939,13 +3916,9 @@ static void FPT_sinits(struct sccb *p_sccb, unsigned char p_card)
*/ */
if ((currTar_Info->TarStatus & TAR_ALLOW_DISC) || if ((currTar_Info->TarStatus & TAR_ALLOW_DISC) ||
(currTar_Info->TarStatus & TAG_Q_TRYING)) { (currTar_Info->TarStatus & TAG_Q_TRYING)) {
p_sccb->Sccb_idmsg = p_sccb->Sccb_idmsg = IDENTIFY(true, p_sccb->Lun);
(unsigned char)(SMIDENT | DISC_PRIV) | p_sccb->Lun; } else {
} p_sccb->Sccb_idmsg = IDENTIFY(false, p_sccb->Lun);
else {
p_sccb->Sccb_idmsg = (unsigned char)SMIDENT | p_sccb->Lun;
} }
p_sccb->HostStatus = 0x00; p_sccb->HostStatus = 0x00;
@ -3962,7 +3935,7 @@ static void FPT_sinits(struct sccb *p_sccb, unsigned char p_card)
*/ */
p_sccb->Sccb_scsistat = BUS_FREE_ST; p_sccb->Sccb_scsistat = BUS_FREE_ST;
p_sccb->SccbStatus = SCCB_IN_PROCESS; p_sccb->SccbStatus = SCCB_IN_PROCESS;
p_sccb->Sccb_scsimsg = SMNO_OP; p_sccb->Sccb_scsimsg = NOP;
} }
@ -4167,7 +4140,7 @@ static void FPT_phaseMsgOut(u32 port, unsigned char p_card)
message = currSCCB->Sccb_scsimsg; message = currSCCB->Sccb_scsimsg;
scsiID = currSCCB->TargID; scsiID = currSCCB->TargID;
if (message == SMDEV_RESET) { if (message == TARGET_RESET) {
currTar_Info = &FPT_sccbMgrTbl[p_card][scsiID]; currTar_Info = &FPT_sccbMgrTbl[p_card][scsiID];
currTar_Info->TarSyncCtrl = 0; currTar_Info->TarSyncCtrl = 0;
@ -4203,7 +4176,7 @@ static void FPT_phaseMsgOut(u32 port, unsigned char p_card)
else if (currSCCB->Sccb_scsistat < COMMAND_ST) { else if (currSCCB->Sccb_scsistat < COMMAND_ST) {
if (message == SMNO_OP) { if (message == NOP) {
currSCCB->Sccb_MGRFlags |= F_DEV_SELECTED; currSCCB->Sccb_MGRFlags |= F_DEV_SELECTED;
FPT_ssel(port, p_card); FPT_ssel(port, p_card);
@ -4211,13 +4184,13 @@ static void FPT_phaseMsgOut(u32 port, unsigned char p_card)
} }
} else { } else {
if (message == SMABORT) if (message == ABORT_TASK_SET)
FPT_queueFlushSccb(p_card, SCCB_COMPLETE); FPT_queueFlushSccb(p_card, SCCB_COMPLETE);
} }
} else { } else {
message = SMABORT; message = ABORT_TASK_SET;
} }
WRW_HARPOON((port + hp_intstat), (BUS_FREE | PHASE | XFER_CNT_0)); WRW_HARPOON((port + hp_intstat), (BUS_FREE | PHASE | XFER_CNT_0));
@ -4232,8 +4205,8 @@ static void FPT_phaseMsgOut(u32 port, unsigned char p_card)
WR_HARPOON(port + hp_portctrl_0, 0x00); WR_HARPOON(port + hp_portctrl_0, 0x00);
if ((message == SMABORT) || (message == SMDEV_RESET) || if ((message == ABORT_TASK_SET) || (message == TARGET_RESET) ||
(message == SMABORT_TAG)) { (message == ABORT_TASK)) {
while (!(RDW_HARPOON((port + hp_intstat)) & (BUS_FREE | PHASE))) { while (!(RDW_HARPOON((port + hp_intstat)) & (BUS_FREE | PHASE))) {
} }
@ -4275,8 +4248,8 @@ static void FPT_phaseMsgOut(u32 port, unsigned char p_card)
else { else {
if (message == SMPARITY) { if (message == MSG_PARITY_ERROR) {
currSCCB->Sccb_scsimsg = SMNO_OP; currSCCB->Sccb_scsimsg = NOP;
WR_HARPOON(port + hp_autostart_1, WR_HARPOON(port + hp_autostart_1,
(AUTO_IMMED + DISCONNECT_START)); (AUTO_IMMED + DISCONNECT_START));
} else { } else {
@ -4306,7 +4279,7 @@ static void FPT_phaseMsgIn(u32 port, unsigned char p_card)
} }
message = RD_HARPOON(port + hp_scsidata_0); message = RD_HARPOON(port + hp_scsidata_0);
if ((message == SMDISC) || (message == SMSAVE_DATA_PTR)) { if ((message == DISCONNECT) || (message == SAVE_POINTERS)) {
WR_HARPOON(port + hp_autostart_1, WR_HARPOON(port + hp_autostart_1,
(AUTO_IMMED + END_DATA_START)); (AUTO_IMMED + END_DATA_START));
@ -4321,7 +4294,7 @@ static void FPT_phaseMsgIn(u32 port, unsigned char p_card)
FPT_sdecm(message, port, p_card); FPT_sdecm(message, port, p_card);
} else { } else {
if (currSCCB->Sccb_scsimsg != SMPARITY) if (currSCCB->Sccb_scsimsg != MSG_PARITY_ERROR)
ACCEPT_MSG(port); ACCEPT_MSG(port);
WR_HARPOON(port + hp_autostart_1, WR_HARPOON(port + hp_autostart_1,
(AUTO_IMMED + DISCONNECT_START)); (AUTO_IMMED + DISCONNECT_START));
@ -4351,7 +4324,7 @@ static void FPT_phaseIllegal(u32 port, unsigned char p_card)
currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL; currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
currSCCB->Sccb_scsistat = ABORT_ST; currSCCB->Sccb_scsistat = ABORT_ST;
currSCCB->Sccb_scsimsg = SMABORT; currSCCB->Sccb_scsimsg = ABORT_TASK_SET;
} }
ACCEPT_MSG_ATN(port); ACCEPT_MSG_ATN(port);
@ -4650,9 +4623,9 @@ static void FPT_autoCmdCmplt(u32 p_port, unsigned char p_card)
FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUN_CA = 0; FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUN_CA = 0;
if (status_byte != SSGOOD) { if (status_byte != SAM_STAT_GOOD) {
if (status_byte == SSQ_FULL) { if (status_byte == SAM_STAT_TASK_SET_FULL) {
if (((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) && if (((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
((FPT_sccbMgrTbl[p_card][currSCCB->TargID]. ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].
@ -4784,7 +4757,7 @@ static void FPT_autoCmdCmplt(u32 p_port, unsigned char p_card)
} }
if (status_byte == SSCHECK) { if (status_byte == SAM_STAT_CHECK_CONDITION) {
if (FPT_BL_Card[p_card].globalFlags & F_DO_RENEGO) { if (FPT_BL_Card[p_card].globalFlags & F_DO_RENEGO) {
if (FPT_sccbMgrTbl[p_card][currSCCB->TargID]. if (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
TarEEValue & EE_SYNC_MASK) { TarEEValue & EE_SYNC_MASK) {
@ -4806,7 +4779,7 @@ static void FPT_autoCmdCmplt(u32 p_port, unsigned char p_card)
currSCCB->SccbStatus = SCCB_ERROR; currSCCB->SccbStatus = SCCB_ERROR;
currSCCB->TargetStatus = status_byte; currSCCB->TargetStatus = status_byte;
if (status_byte == SSCHECK) { if (status_byte == SAM_STAT_CHECK_CONDITION) {
FPT_sccbMgrTbl[p_card][currSCCB->TargID]. FPT_sccbMgrTbl[p_card][currSCCB->TargID].
TarLUN_CA = 1; TarLUN_CA = 1;
@ -6868,14 +6841,14 @@ static void FPT_queueCmdComplete(struct sccb_card *pCurrCard,
if ((p_sccb-> if ((p_sccb->
ControlByte & (SCCB_DATA_XFER_OUT | SCCB_DATA_XFER_IN)) ControlByte & (SCCB_DATA_XFER_OUT | SCCB_DATA_XFER_IN))
&& (p_sccb->HostStatus == SCCB_COMPLETE) && (p_sccb->HostStatus == SCCB_COMPLETE)
&& (p_sccb->TargetStatus != SSCHECK)) && (p_sccb->TargetStatus != SAM_STAT_CHECK_CONDITION))
if ((SCSIcmd == SCSI_READ) || if ((SCSIcmd == READ_6) ||
(SCSIcmd == SCSI_WRITE) || (SCSIcmd == WRITE_6) ||
(SCSIcmd == SCSI_READ_EXTENDED) || (SCSIcmd == READ_10) ||
(SCSIcmd == SCSI_WRITE_EXTENDED) || (SCSIcmd == WRITE_10) ||
(SCSIcmd == SCSI_WRITE_AND_VERIFY) || (SCSIcmd == WRITE_VERIFY) ||
(SCSIcmd == SCSI_START_STOP_UNIT) || (SCSIcmd == START_STOP) ||
(pCurrCard->globalFlags & F_NO_FILTER) (pCurrCard->globalFlags & F_NO_FILTER)
) )
p_sccb->HostStatus = SCCB_DATA_UNDER_RUN; p_sccb->HostStatus = SCCB_DATA_UNDER_RUN;

View File

@ -538,11 +538,11 @@ static void complete_cmd(struct Scsi_Host *instance,
if (hostdata->sensing == cmd) { if (hostdata->sensing == cmd) {
/* Autosense processing ends here */ /* Autosense processing ends here */
if (status_byte(cmd->result) != GOOD) { if (get_status_byte(cmd) != SAM_STAT_GOOD) {
scsi_eh_restore_cmnd(cmd, &hostdata->ses); scsi_eh_restore_cmnd(cmd, &hostdata->ses);
} else { } else {
scsi_eh_restore_cmnd(cmd, &hostdata->ses); scsi_eh_restore_cmnd(cmd, &hostdata->ses);
set_driver_byte(cmd, DRIVER_SENSE); set_status_byte(cmd, SAM_STAT_CHECK_CONDITION);
} }
hostdata->sensing = NULL; hostdata->sensing = NULL;
} }
@ -1815,6 +1815,8 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
switch (tmp) { switch (tmp) {
case ABORT: case ABORT:
set_host_byte(cmd, DID_ABORT);
/* fallthrough */
case COMMAND_COMPLETE: case COMMAND_COMPLETE:
/* Accept message by clearing ACK */ /* Accept message by clearing ACK */
sink = 1; sink = 1;
@ -1826,9 +1828,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
hostdata->connected = NULL; hostdata->connected = NULL;
hostdata->busy[scmd_id(cmd)] &= ~(1 << cmd->device->lun); hostdata->busy[scmd_id(cmd)] &= ~(1 << cmd->device->lun);
cmd->result &= ~0xffff; set_status_byte(cmd, cmd->SCp.Status);
cmd->result |= cmd->SCp.Status;
cmd->result |= cmd->SCp.Message << 8;
set_resid_from_SCp(cmd); set_resid_from_SCp(cmd);

View File

@ -5964,7 +5964,6 @@ static void adv_isr_callback(ADV_DVC_VAR *adv_dvc_varp, ADV_SCSI_REQ_Q *scsiqp)
ASC_DBG(2, "SAM_STAT_CHECK_CONDITION\n"); ASC_DBG(2, "SAM_STAT_CHECK_CONDITION\n");
ASC_DBG_PRT_SENSE(2, scp->sense_buffer, ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
SCSI_SENSE_BUFFERSIZE); SCSI_SENSE_BUFFERSIZE);
set_driver_byte(scp, DRIVER_SENSE);
} }
break; break;
@ -6715,7 +6714,6 @@ static void asc_isr_callback(ASC_DVC_VAR *asc_dvc_varp, ASC_QDONE_INFO *qdonep)
ASC_DBG(2, "SAM_STAT_CHECK_CONDITION\n"); ASC_DBG(2, "SAM_STAT_CHECK_CONDITION\n");
ASC_DBG_PRT_SENSE(2, scp->sense_buffer, ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
SCSI_SENSE_BUFFERSIZE); SCSI_SENSE_BUFFERSIZE);
set_driver_byte(scp, DRIVER_SENSE);
} }
break; break;
@ -6730,14 +6728,12 @@ static void asc_isr_callback(ASC_DVC_VAR *asc_dvc_varp, ASC_QDONE_INFO *qdonep)
case QD_ABORTED_BY_HOST: case QD_ABORTED_BY_HOST:
ASC_DBG(1, "QD_ABORTED_BY_HOST\n"); ASC_DBG(1, "QD_ABORTED_BY_HOST\n");
set_status_byte(scp, qdonep->d3.scsi_stat); set_status_byte(scp, qdonep->d3.scsi_stat);
set_msg_byte(scp, qdonep->d3.scsi_msg);
set_host_byte(scp, DID_ABORT); set_host_byte(scp, DID_ABORT);
break; break;
default: default:
ASC_DBG(1, "done_stat 0x%x\n", qdonep->d3.done_stat); ASC_DBG(1, "done_stat 0x%x\n", qdonep->d3.done_stat);
set_status_byte(scp, qdonep->d3.scsi_stat); set_status_byte(scp, qdonep->d3.scsi_stat);
set_msg_byte(scp, qdonep->d3.scsi_msg);
set_host_byte(scp, DID_ERROR); set_host_byte(scp, DID_ERROR);
break; break;
} }

View File

@ -619,7 +619,8 @@ static struct {
static irqreturn_t intr(int irq, void *dev_id); static irqreturn_t intr(int irq, void *dev_id);
static void reset_ports(struct Scsi_Host *shpnt); static void reset_ports(struct Scsi_Host *shpnt);
static void aha152x_error(struct Scsi_Host *shpnt, char *msg); static void aha152x_error(struct Scsi_Host *shpnt, char *msg);
static void done(struct Scsi_Host *shpnt, int error); static void done(struct Scsi_Host *shpnt, unsigned char status_byte,
unsigned char host_byte);
/* diagnostics */ /* diagnostics */
static void show_command(struct scsi_cmnd * ptr); static void show_command(struct scsi_cmnd * ptr);
@ -1271,7 +1272,8 @@ static int aha152x_biosparam(struct scsi_device *sdev, struct block_device *bdev
* Internal done function * Internal done function
* *
*/ */
static void done(struct Scsi_Host *shpnt, int error) static void done(struct Scsi_Host *shpnt, unsigned char status_byte,
unsigned char host_byte)
{ {
if (CURRENT_SC) { if (CURRENT_SC) {
if(DONE_SC) if(DONE_SC)
@ -1281,7 +1283,8 @@ static void done(struct Scsi_Host *shpnt, int error)
DONE_SC = CURRENT_SC; DONE_SC = CURRENT_SC;
CURRENT_SC = NULL; CURRENT_SC = NULL;
DONE_SC->result = error; set_status_byte(DONE_SC, status_byte);
set_host_byte(DONE_SC, host_byte);
} else } else
printk(KERN_ERR "aha152x: done() called outside of command\n"); printk(KERN_ERR "aha152x: done() called outside of command\n");
} }
@ -1376,13 +1379,13 @@ static void busfree_run(struct Scsi_Host *shpnt)
if(CURRENT_SC->SCp.phase & completed) { if(CURRENT_SC->SCp.phase & completed) {
/* target sent COMMAND COMPLETE */ /* target sent COMMAND COMPLETE */
done(shpnt, (CURRENT_SC->SCp.Status & 0xff) | ((CURRENT_SC->SCp.Message & 0xff) << 8) | (DID_OK << 16)); done(shpnt, CURRENT_SC->SCp.Status, DID_OK);
} else if(CURRENT_SC->SCp.phase & aborted) { } else if(CURRENT_SC->SCp.phase & aborted) {
done(shpnt, (CURRENT_SC->SCp.Status & 0xff) | ((CURRENT_SC->SCp.Message & 0xff) << 8) | (DID_ABORT << 16)); done(shpnt, CURRENT_SC->SCp.Status, DID_ABORT);
} else if(CURRENT_SC->SCp.phase & resetted) { } else if(CURRENT_SC->SCp.phase & resetted) {
done(shpnt, (CURRENT_SC->SCp.Status & 0xff) | ((CURRENT_SC->SCp.Message & 0xff) << 8) | (DID_RESET << 16)); done(shpnt, CURRENT_SC->SCp.Status, DID_RESET);
} else if(CURRENT_SC->SCp.phase & disconnected) { } else if(CURRENT_SC->SCp.phase & disconnected) {
/* target sent DISCONNECT */ /* target sent DISCONNECT */
@ -1394,7 +1397,7 @@ static void busfree_run(struct Scsi_Host *shpnt)
CURRENT_SC = NULL; CURRENT_SC = NULL;
} else { } else {
done(shpnt, DID_ERROR << 16); done(shpnt, SAM_STAT_GOOD, DID_ERROR);
} }
#if defined(AHA152X_STAT) #if defined(AHA152X_STAT)
} else { } else {
@ -1515,7 +1518,7 @@ static void seldo_run(struct Scsi_Host *shpnt)
if (TESTLO(SSTAT0, SELDO)) { if (TESTLO(SSTAT0, SELDO)) {
scmd_printk(KERN_ERR, CURRENT_SC, scmd_printk(KERN_ERR, CURRENT_SC,
"aha152x: passing bus free condition\n"); "aha152x: passing bus free condition\n");
done(shpnt, DID_NO_CONNECT << 16); done(shpnt, SAM_STAT_GOOD, DID_NO_CONNECT);
return; return;
} }
@ -1552,12 +1555,12 @@ static void selto_run(struct Scsi_Host *shpnt)
CURRENT_SC->SCp.phase &= ~selecting; CURRENT_SC->SCp.phase &= ~selecting;
if (CURRENT_SC->SCp.phase & aborted) if (CURRENT_SC->SCp.phase & aborted)
done(shpnt, DID_ABORT << 16); done(shpnt, SAM_STAT_GOOD, DID_ABORT);
else if (TESTLO(SSTAT0, SELINGO)) else if (TESTLO(SSTAT0, SELINGO))
done(shpnt, DID_BUS_BUSY << 16); done(shpnt, SAM_STAT_GOOD, DID_BUS_BUSY);
else else
/* ARBITRATION won, but SELECTION failed */ /* ARBITRATION won, but SELECTION failed */
done(shpnt, DID_NO_CONNECT << 16); done(shpnt, SAM_STAT_GOOD, DID_NO_CONNECT);
} }
/* /*
@ -1891,7 +1894,7 @@ static void cmd_init(struct Scsi_Host *shpnt)
if (CURRENT_SC->SCp.sent_command) { if (CURRENT_SC->SCp.sent_command) {
scmd_printk(KERN_ERR, CURRENT_SC, scmd_printk(KERN_ERR, CURRENT_SC,
"command already sent\n"); "command already sent\n");
done(shpnt, DID_ERROR << 16); done(shpnt, SAM_STAT_GOOD, DID_ERROR);
return; return;
} }
@ -2231,7 +2234,7 @@ static int update_state(struct Scsi_Host *shpnt)
static void parerr_run(struct Scsi_Host *shpnt) static void parerr_run(struct Scsi_Host *shpnt)
{ {
scmd_printk(KERN_ERR, CURRENT_SC, "parity error\n"); scmd_printk(KERN_ERR, CURRENT_SC, "parity error\n");
done(shpnt, DID_PARITY << 16); done(shpnt, SAM_STAT_GOOD, DID_PARITY);
} }
/* /*
@ -2254,7 +2257,7 @@ static void rsti_run(struct Scsi_Host *shpnt)
kfree(ptr->host_scribble); kfree(ptr->host_scribble);
ptr->host_scribble=NULL; ptr->host_scribble=NULL;
ptr->result = DID_RESET << 16; set_host_byte(ptr, DID_RESET);
ptr->scsi_done(ptr); ptr->scsi_done(ptr);
} }
@ -2262,7 +2265,7 @@ static void rsti_run(struct Scsi_Host *shpnt)
} }
if(CURRENT_SC && !CURRENT_SC->device->soft_reset) if(CURRENT_SC && !CURRENT_SC->device->soft_reset)
done(shpnt, DID_RESET << 16 ); done(shpnt, SAM_STAT_GOOD, DID_RESET);
} }

View File

@ -1928,7 +1928,7 @@ ahd_linux_handle_scsi_status(struct ahd_softc *ahd,
memcpy(cmd->sense_buffer, memcpy(cmd->sense_buffer,
ahd_get_sense_buf(ahd, scb) ahd_get_sense_buf(ahd, scb)
+ sense_offset, sense_size); + sense_offset, sense_size);
cmd->result |= (DRIVER_SENSE << 24); set_status_byte(cmd, SAM_STAT_CHECK_CONDITION);
#ifdef AHD_DEBUG #ifdef AHD_DEBUG
if (ahd_debug & AHD_SHOW_SENSE) { if (ahd_debug & AHD_SHOW_SENSE) {
@ -2018,6 +2018,7 @@ ahd_linux_queue_cmd_complete(struct ahd_softc *ahd, struct scsi_cmnd *cmd)
int new_status = DID_OK; int new_status = DID_OK;
int do_fallback = 0; int do_fallback = 0;
int scsi_status; int scsi_status;
struct scsi_sense_data *sense;
/* /*
* Map CAM error codes into Linux Error codes. We * Map CAM error codes into Linux Error codes. We
@ -2041,18 +2042,12 @@ ahd_linux_queue_cmd_complete(struct ahd_softc *ahd, struct scsi_cmnd *cmd)
switch(scsi_status) { switch(scsi_status) {
case SAM_STAT_COMMAND_TERMINATED: case SAM_STAT_COMMAND_TERMINATED:
case SAM_STAT_CHECK_CONDITION: case SAM_STAT_CHECK_CONDITION:
if ((cmd->result >> 24) != DRIVER_SENSE) { sense = (struct scsi_sense_data *)
cmd->sense_buffer;
if (sense->extra_len >= 5 &&
(sense->add_sense_code == 0x47
|| sense->add_sense_code == 0x48))
do_fallback = 1; do_fallback = 1;
} else {
struct scsi_sense_data *sense;
sense = (struct scsi_sense_data *)
cmd->sense_buffer;
if (sense->extra_len >= 5 &&
(sense->add_sense_code == 0x47
|| sense->add_sense_code == 0x48))
do_fallback = 1;
}
break; break;
default: default:
break; break;

View File

@ -1838,7 +1838,6 @@ ahc_linux_handle_scsi_status(struct ahc_softc *ahc,
if (sense_size < SCSI_SENSE_BUFFERSIZE) if (sense_size < SCSI_SENSE_BUFFERSIZE)
memset(&cmd->sense_buffer[sense_size], 0, memset(&cmd->sense_buffer[sense_size], 0,
SCSI_SENSE_BUFFERSIZE - sense_size); SCSI_SENSE_BUFFERSIZE - sense_size);
cmd->result |= (DRIVER_SENSE << 24);
#ifdef AHC_DEBUG #ifdef AHC_DEBUG
if (ahc_debug & AHC_SHOW_SENSE) { if (ahc_debug & AHC_SHOW_SENSE) {
int i; int i;

View File

@ -1326,7 +1326,7 @@ static void arcmsr_report_sense_info(struct CommandControlBlock *ccb)
struct scsi_cmnd *pcmd = ccb->pcmd; struct scsi_cmnd *pcmd = ccb->pcmd;
struct SENSE_DATA *sensebuffer = (struct SENSE_DATA *)pcmd->sense_buffer; struct SENSE_DATA *sensebuffer = (struct SENSE_DATA *)pcmd->sense_buffer;
pcmd->result = (DID_OK << 16) | (CHECK_CONDITION << 1); pcmd->result = (DID_OK << 16) | SAM_STAT_CHECK_CONDITION;
if (sensebuffer) { if (sensebuffer) {
int sense_data_length = int sense_data_length =
sizeof(struct SENSE_DATA) < SCSI_SENSE_BUFFERSIZE sizeof(struct SENSE_DATA) < SCSI_SENSE_BUFFERSIZE
@ -1335,7 +1335,6 @@ static void arcmsr_report_sense_info(struct CommandControlBlock *ccb)
memcpy(sensebuffer, ccb->arcmsr_cdb.SenseData, sense_data_length); memcpy(sensebuffer, ccb->arcmsr_cdb.SenseData, sense_data_length);
sensebuffer->ErrorCode = SCSI_SENSE_CURRENT_ERRORS; sensebuffer->ErrorCode = SCSI_SENSE_CURRENT_ERRORS;
sensebuffer->Valid = 1; sensebuffer->Valid = 1;
pcmd->result |= (DRIVER_SENSE << 24);
} }
} }
@ -3254,7 +3253,7 @@ static int arcmsr_queue_command_lck(struct scsi_cmnd *cmd,
if (!ccb) if (!ccb)
return SCSI_MLQUEUE_HOST_BUSY; return SCSI_MLQUEUE_HOST_BUSY;
if (arcmsr_build_ccb( acb, ccb, cmd ) == FAILED) { if (arcmsr_build_ccb( acb, ccb, cmd ) == FAILED) {
cmd->result = (DID_ERROR << 16) | (RESERVATION_CONFLICT << 1); cmd->result = (DID_ERROR << 16) | SAM_STAT_RESERVATION_CONFLICT;
cmd->scsi_done(cmd); cmd->scsi_done(cmd);
return 0; return 0;
} }

View File

@ -794,7 +794,10 @@ static void acornscsi_done(AS_Host *host, struct scsi_cmnd **SCpntp,
acornscsi_dma_cleanup(host); acornscsi_dma_cleanup(host);
SCpnt->result = result << 16 | host->scsi.SCp.Message << 8 | host->scsi.SCp.Status; set_host_byte(SCpnt, result);
if (result == DID_OK)
scsi_msg_to_host_byte(SCpnt, host->scsi.SCp.Message);
set_status_byte(SCpnt, host->scsi.SCp.Status);
/* /*
* In theory, this should not happen. In practice, it seems to. * In theory, this should not happen. In practice, it seems to.
@ -833,12 +836,12 @@ static void acornscsi_done(AS_Host *host, struct scsi_cmnd **SCpntp,
xfer_warn = 0; xfer_warn = 0;
if (xfer_warn) { if (xfer_warn) {
switch (status_byte(SCpnt->result)) { switch (get_status_byte(SCpnt)) {
case CHECK_CONDITION: case SAM_STAT_CHECK_CONDITION:
case COMMAND_TERMINATED: case SAM_STAT_COMMAND_TERMINATED:
case BUSY: case SAM_STAT_BUSY:
case QUEUE_FULL: case SAM_STAT_TASK_SET_FULL:
case RESERVATION_CONFLICT: case SAM_STAT_RESERVATION_CONFLICT:
break; break;
default: default:
@ -2470,7 +2473,7 @@ static int acornscsi_queuecmd_lck(struct scsi_cmnd *SCpnt,
if (acornscsi_cmdtype(SCpnt->cmnd[0]) == CMD_WRITE && (NO_WRITE & (1 << SCpnt->device->id))) { if (acornscsi_cmdtype(SCpnt->cmnd[0]) == CMD_WRITE && (NO_WRITE & (1 << SCpnt->device->id))) {
printk(KERN_CRIT "scsi%d.%c: WRITE attempted with NO_WRITE flag set\n", printk(KERN_CRIT "scsi%d.%c: WRITE attempted with NO_WRITE flag set\n",
host->host->host_no, '0' + SCpnt->device->id); host->host->host_no, '0' + SCpnt->device->id);
SCpnt->result = DID_NO_CONNECT << 16; set_host_byte(SCpnt, DID_NO_CONNECT);
done(SCpnt); done(SCpnt);
return 0; return 0;
} }
@ -2492,7 +2495,7 @@ static int acornscsi_queuecmd_lck(struct scsi_cmnd *SCpnt,
unsigned long flags; unsigned long flags;
if (!queue_add_cmd_ordered(&host->queues.issue, SCpnt)) { if (!queue_add_cmd_ordered(&host->queues.issue, SCpnt)) {
SCpnt->result = DID_ERROR << 16; set_host_byte(SCpnt, DID_ERROR);
done(SCpnt); done(SCpnt);
return 0; return 0;
} }
@ -2506,31 +2509,6 @@ static int acornscsi_queuecmd_lck(struct scsi_cmnd *SCpnt,
DEF_SCSI_QCMD(acornscsi_queuecmd) DEF_SCSI_QCMD(acornscsi_queuecmd)
/*
* Prototype: void acornscsi_reportstatus(struct scsi_cmnd **SCpntp1, struct scsi_cmnd **SCpntp2, int result)
* Purpose : pass a result to *SCpntp1, and check if *SCpntp1 = *SCpntp2
* Params : SCpntp1 - pointer to command to return
* SCpntp2 - pointer to command to check
* result - result to pass back to mid-level done function
* Returns : *SCpntp2 = NULL if *SCpntp1 is the same command structure as *SCpntp2.
*/
static inline void acornscsi_reportstatus(struct scsi_cmnd **SCpntp1,
struct scsi_cmnd **SCpntp2,
int result)
{
struct scsi_cmnd *SCpnt = *SCpntp1;
if (SCpnt) {
*SCpntp1 = NULL;
SCpnt->result = result;
SCpnt->scsi_done(SCpnt);
}
if (SCpnt == *SCpntp2)
*SCpntp2 = NULL;
}
enum res_abort { res_not_running, res_success, res_success_clear, res_snooze }; enum res_abort { res_not_running, res_success, res_success_clear, res_snooze };
/* /*

View File

@ -2042,8 +2042,10 @@ fas216_std_done(FAS216_Info *info, struct scsi_cmnd *SCpnt, unsigned int result)
{ {
info->stats.fins += 1; info->stats.fins += 1;
SCpnt->result = result << 16 | info->scsi.SCp.Message << 8 | set_host_byte(SCpnt, result);
info->scsi.SCp.Status; if (result == DID_OK)
scsi_msg_to_host_byte(SCpnt, info->scsi.SCp.Message);
set_status_byte(SCpnt, info->scsi.SCp.Status);
fas216_log_command(info, LOG_CONNECT, SCpnt, fas216_log_command(info, LOG_CONNECT, SCpnt,
"command complete, result=0x%08x", SCpnt->result); "command complete, result=0x%08x", SCpnt->result);
@ -2051,23 +2053,22 @@ fas216_std_done(FAS216_Info *info, struct scsi_cmnd *SCpnt, unsigned int result)
/* /*
* If the driver detected an error, we're all done. * If the driver detected an error, we're all done.
*/ */
if (host_byte(SCpnt->result) != DID_OK || if (get_host_byte(SCpnt) != DID_OK)
msg_byte(SCpnt->result) != COMMAND_COMPLETE)
goto done; goto done;
/* /*
* If the command returned CHECK_CONDITION or COMMAND_TERMINATED * If the command returned CHECK_CONDITION or COMMAND_TERMINATED
* status, request the sense information. * status, request the sense information.
*/ */
if (status_byte(SCpnt->result) == CHECK_CONDITION || if (get_status_byte(SCpnt) == SAM_STAT_CHECK_CONDITION ||
status_byte(SCpnt->result) == COMMAND_TERMINATED) get_status_byte(SCpnt) == SAM_STAT_COMMAND_TERMINATED)
goto request_sense; goto request_sense;
/* /*
* If the command did not complete with GOOD status, * If the command did not complete with GOOD status,
* we are all done here. * we are all done here.
*/ */
if (status_byte(SCpnt->result) != GOOD) if (get_status_byte(SCpnt) != SAM_STAT_GOOD)
goto done; goto done;
/* /*

View File

@ -198,8 +198,9 @@ ch_do_scsi(scsi_changer *ch, unsigned char *cmd, int cmd_len,
result = scsi_execute_req(ch->device, cmd, direction, buffer, result = scsi_execute_req(ch->device, cmd, direction, buffer,
buflength, &sshdr, timeout * HZ, buflength, &sshdr, timeout * HZ,
MAX_RETRIES, NULL); MAX_RETRIES, NULL);
if (result < 0)
if (driver_byte(result) == DRIVER_SENSE) { return result;
if (scsi_sense_valid(&sshdr)) {
if (debug) if (debug)
scsi_print_sense_hdr(ch->device, ch->name, &sshdr); scsi_print_sense_hdr(ch->device, ch->name, &sshdr);
errno = ch_find_errno(&sshdr); errno = ch_find_errno(&sshdr);

View File

@ -406,10 +406,6 @@ static const char * const hostbyte_table[]={
"DID_TRANSPORT_DISRUPTED", "DID_TRANSPORT_FAILFAST", "DID_TARGET_FAILURE", "DID_TRANSPORT_DISRUPTED", "DID_TRANSPORT_FAILFAST", "DID_TARGET_FAILURE",
"DID_NEXUS_FAILURE", "DID_ALLOC_FAILURE", "DID_MEDIUM_ERROR" }; "DID_NEXUS_FAILURE", "DID_ALLOC_FAILURE", "DID_MEDIUM_ERROR" };
static const char * const driverbyte_table[]={
"DRIVER_OK", "DRIVER_BUSY", "DRIVER_SOFT", "DRIVER_MEDIA", "DRIVER_ERROR",
"DRIVER_INVALID", "DRIVER_TIMEOUT", "DRIVER_HARD", "DRIVER_SENSE"};
const char *scsi_hostbyte_string(int result) const char *scsi_hostbyte_string(int result)
{ {
const char *hb_string = NULL; const char *hb_string = NULL;
@ -421,17 +417,6 @@ const char *scsi_hostbyte_string(int result)
} }
EXPORT_SYMBOL(scsi_hostbyte_string); EXPORT_SYMBOL(scsi_hostbyte_string);
const char *scsi_driverbyte_string(int result)
{
const char *db_string = NULL;
int db = driver_byte(result);
if (db < ARRAY_SIZE(driverbyte_table))
db_string = driverbyte_table[db];
return db_string;
}
EXPORT_SYMBOL(scsi_driverbyte_string);
#define scsi_mlreturn_name(result) { result, #result } #define scsi_mlreturn_name(result) { result, #result }
static const struct value_name_pair scsi_mlreturn_arr[] = { static const struct value_name_pair scsi_mlreturn_arr[] = {
scsi_mlreturn_name(NEEDS_RETRY), scsi_mlreturn_name(NEEDS_RETRY),

View File

@ -369,8 +369,7 @@ retry:
goto out; goto out;
} }
if (driver_byte(result) == DRIVER_SENSE) { if (result > 0 && scsi_sense_valid(&sshdr)) {
result &= ~(0xFF<<24); /* DRIVER_SENSE is not an error */
if (result & SAM_STAT_CHECK_CONDITION) { if (result & SAM_STAT_CHECK_CONDITION) {
switch (sshdr.sense_key) { switch (sshdr.sense_key) {
case NO_SENSE: case NO_SENSE:

View File

@ -160,22 +160,6 @@
#define DC395x_write16(acb,address,value) outw((value), acb->io_port_base + (address)) #define DC395x_write16(acb,address,value) outw((value), acb->io_port_base + (address))
#define DC395x_write32(acb,address,value) outl((value), acb->io_port_base + (address)) #define DC395x_write32(acb,address,value) outl((value), acb->io_port_base + (address))
/* cmd->result */
#define RES_TARGET 0x000000FF /* Target State */
#define RES_TARGET_LNX STATUS_MASK /* Only official ... */
#define RES_ENDMSG 0x0000FF00 /* End Message */
#define RES_DID 0x00FF0000 /* DID_ codes */
#define RES_DRV 0xFF000000 /* DRIVER_ codes */
#define MK_RES(drv,did,msg,tgt) ((int)(drv)<<24 | (int)(did)<<16 | (int)(msg)<<8 | (int)(tgt))
#define MK_RES_LNX(drv,did,msg,tgt) ((int)(drv)<<24 | (int)(did)<<16 | (int)(msg)<<8 | (int)(tgt)<<1)
#define SET_RES_TARGET(who,tgt) { who &= ~RES_TARGET; who |= (int)(tgt); }
#define SET_RES_TARGET_LNX(who,tgt) { who &= ~RES_TARGET_LNX; who |= (int)(tgt) << 1; }
#define SET_RES_MSG(who,msg) { who &= ~RES_ENDMSG; who |= (int)(msg) << 8; }
#define SET_RES_DID(who,did) { who &= ~RES_DID; who |= (int)(did) << 16; }
#define SET_RES_DRV(who,drv) { who &= ~RES_DRV; who |= (int)(drv) << 24; }
#define TAG_NONE 255 #define TAG_NONE 255
/* /*
@ -986,7 +970,7 @@ static int dc395x_queue_command_lck(struct scsi_cmnd *cmd, void (*done)(struct s
cmd, cmd->device->id, (u8)cmd->device->lun, cmd->cmnd[0]); cmd, cmd->device->id, (u8)cmd->device->lun, cmd->cmnd[0]);
/* Assume BAD_TARGET; will be cleared later */ /* Assume BAD_TARGET; will be cleared later */
cmd->result = DID_BAD_TARGET << 16; set_host_byte(cmd, DID_BAD_TARGET);
/* ignore invalid targets */ /* ignore invalid targets */
if (cmd->device->id >= acb->scsi_host->max_id || if (cmd->device->id >= acb->scsi_host->max_id ||
@ -1013,7 +997,8 @@ static int dc395x_queue_command_lck(struct scsi_cmnd *cmd, void (*done)(struct s
/* set callback and clear result in the command */ /* set callback and clear result in the command */
cmd->scsi_done = done; cmd->scsi_done = done;
cmd->result = 0; set_host_byte(cmd, DID_OK);
set_status_byte(cmd, SAM_STAT_GOOD);
srb = list_first_entry_or_null(&acb->srb_free_list, srb = list_first_entry_or_null(&acb->srb_free_list,
struct ScsiReqBlk, list); struct ScsiReqBlk, list);
@ -1250,7 +1235,7 @@ static int dc395x_eh_abort(struct scsi_cmnd *cmd)
free_tag(dcb, srb); free_tag(dcb, srb);
list_add_tail(&srb->list, &acb->srb_free_list); list_add_tail(&srb->list, &acb->srb_free_list);
dprintkl(KERN_DEBUG, "eh_abort: Command was waiting\n"); dprintkl(KERN_DEBUG, "eh_abort: Command was waiting\n");
cmd->result = DID_ABORT << 16; set_host_byte(cmd, DID_ABORT);
return SUCCESS; return SUCCESS;
} }
srb = find_cmd(cmd, &dcb->srb_going_list); srb = find_cmd(cmd, &dcb->srb_going_list);
@ -3178,6 +3163,8 @@ static void srb_done(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb,
srb, scsi_sg_count(cmd), srb->sg_index, srb->sg_count, srb, scsi_sg_count(cmd), srb->sg_index, srb->sg_count,
scsi_sgtalbe(cmd)); scsi_sgtalbe(cmd));
status = srb->target_status; status = srb->target_status;
set_host_byte(cmd, DID_OK);
set_status_byte(cmd, SAM_STAT_GOOD);
if (srb->flag & AUTO_REQSENSE) { if (srb->flag & AUTO_REQSENSE) {
dprintkdbg(DBG_0, "srb_done: AUTO_REQSENSE1\n"); dprintkdbg(DBG_0, "srb_done: AUTO_REQSENSE1\n");
pci_unmap_srb_sense(acb, srb); pci_unmap_srb_sense(acb, srb);
@ -3186,7 +3173,7 @@ static void srb_done(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb,
*/ */
srb->flag &= ~AUTO_REQSENSE; srb->flag &= ~AUTO_REQSENSE;
srb->adapter_status = 0; srb->adapter_status = 0;
srb->target_status = CHECK_CONDITION << 1; srb->target_status = SAM_STAT_CHECK_CONDITION;
if (debug_enabled(DBG_1)) { if (debug_enabled(DBG_1)) {
switch (cmd->sense_buffer[2] & 0x0f) { switch (cmd->sense_buffer[2] & 0x0f) {
case NOT_READY: case NOT_READY:
@ -3233,22 +3220,13 @@ static void srb_done(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb,
*((unsigned int *)(cmd->sense_buffer + 3))); *((unsigned int *)(cmd->sense_buffer + 3)));
} }
if (status == (CHECK_CONDITION << 1)) { if (status == SAM_STAT_CHECK_CONDITION) {
cmd->result = DID_BAD_TARGET << 16; set_host_byte(cmd, DID_BAD_TARGET);
goto ckc_e; goto ckc_e;
} }
dprintkdbg(DBG_0, "srb_done: AUTO_REQSENSE2\n"); dprintkdbg(DBG_0, "srb_done: AUTO_REQSENSE2\n");
if (srb->total_xfer_length set_status_byte(cmd, SAM_STAT_CHECK_CONDITION);
&& srb->total_xfer_length >= cmd->underflow)
cmd->result =
MK_RES_LNX(DRIVER_SENSE, DID_OK,
srb->end_message, CHECK_CONDITION);
/*SET_RES_DID(cmd->result,DID_OK) */
else
cmd->result =
MK_RES_LNX(DRIVER_SENSE, DID_OK,
srb->end_message, CHECK_CONDITION);
goto ckc_e; goto ckc_e;
} }
@ -3258,10 +3236,10 @@ static void srb_done(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb,
/* /*
* target status.......................... * target status..........................
*/ */
if (status >> 1 == CHECK_CONDITION) { if (status == SAM_STAT_CHECK_CONDITION) {
request_sense(acb, dcb, srb); request_sense(acb, dcb, srb);
return; return;
} else if (status >> 1 == QUEUE_FULL) { } else if (status == SAM_STAT_TASK_SET_FULL) {
tempcnt = (u8)list_size(&dcb->srb_going_list); tempcnt = (u8)list_size(&dcb->srb_going_list);
dprintkl(KERN_INFO, "QUEUE_FULL for dev <%02i-%i> with %i cmnds\n", dprintkl(KERN_INFO, "QUEUE_FULL for dev <%02i-%i> with %i cmnds\n",
dcb->target_id, dcb->target_lun, tempcnt); dcb->target_id, dcb->target_lun, tempcnt);
@ -3277,13 +3255,11 @@ static void srb_done(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb,
} else if (status == SCSI_STAT_SEL_TIMEOUT) { } else if (status == SCSI_STAT_SEL_TIMEOUT) {
srb->adapter_status = H_SEL_TIMEOUT; srb->adapter_status = H_SEL_TIMEOUT;
srb->target_status = 0; srb->target_status = 0;
cmd->result = DID_NO_CONNECT << 16; set_host_byte(cmd, DID_NO_CONNECT);
} else { } else {
srb->adapter_status = 0; srb->adapter_status = 0;
SET_RES_DID(cmd->result, DID_ERROR); set_host_byte(cmd, DID_ERROR);
SET_RES_MSG(cmd->result, srb->end_message); set_status_byte(cmd, status);
SET_RES_TARGET(cmd->result, status);
} }
} else { } else {
/* /*
@ -3292,16 +3268,13 @@ static void srb_done(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb,
status = srb->adapter_status; status = srb->adapter_status;
if (status & H_OVER_UNDER_RUN) { if (status & H_OVER_UNDER_RUN) {
srb->target_status = 0; srb->target_status = 0;
SET_RES_DID(cmd->result, DID_OK); scsi_msg_to_host_byte(cmd, srb->end_message);
SET_RES_MSG(cmd->result, srb->end_message);
} else if (srb->status & PARITY_ERROR) { } else if (srb->status & PARITY_ERROR) {
SET_RES_DID(cmd->result, DID_PARITY); set_host_byte(cmd, DID_PARITY);
SET_RES_MSG(cmd->result, srb->end_message);
} else { /* No error */ } else { /* No error */
srb->adapter_status = 0; srb->adapter_status = 0;
srb->target_status = 0; srb->target_status = 0;
SET_RES_DID(cmd->result, DID_OK);
} }
} }
@ -3322,15 +3295,15 @@ static void srb_done(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb,
base = scsi_kmap_atomic_sg(sg, scsi_sg_count(cmd), &offset, &len); base = scsi_kmap_atomic_sg(sg, scsi_sg_count(cmd), &offset, &len);
ptr = (struct ScsiInqData *)(base + offset); ptr = (struct ScsiInqData *)(base + offset);
if (!ckc_only && (cmd->result & RES_DID) == 0 if (!ckc_only && get_host_byte(cmd) == DID_OK
&& cmd->cmnd[2] == 0 && scsi_bufflen(cmd) >= 8 && cmd->cmnd[2] == 0 && scsi_bufflen(cmd) >= 8
&& dir != DMA_NONE && ptr && (ptr->Vers & 0x07) >= 2) && dir != DMA_NONE && ptr && (ptr->Vers & 0x07) >= 2)
dcb->inquiry7 = ptr->Flags; dcb->inquiry7 = ptr->Flags;
/*if( srb->cmd->cmnd[0] == INQUIRY && */ /*if( srb->cmd->cmnd[0] == INQUIRY && */
/* (host_byte(cmd->result) == DID_OK || status_byte(cmd->result) & CHECK_CONDITION) ) */ /* (host_byte(cmd->result) == DID_OK || status_byte(cmd->result) & CHECK_CONDITION) ) */
if ((cmd->result == (DID_OK << 16) || if ((get_host_byte(cmd) == DID_OK) ||
status_byte(cmd->result) == CHECK_CONDITION)) { (get_status_byte(cmd) == SAM_STAT_CHECK_CONDITION)) {
if (!dcb->init_tcq_flag) { if (!dcb->init_tcq_flag) {
add_dev(acb, dcb, ptr); add_dev(acb, dcb, ptr);
dcb->init_tcq_flag = 1; dcb->init_tcq_flag = 1;
@ -3357,7 +3330,7 @@ static void srb_done(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb,
if (srb != acb->tmp_srb) { if (srb != acb->tmp_srb) {
/* Add to free list */ /* Add to free list */
dprintkdbg(DBG_0, "srb_done: (0x%p) done result=0x%08x\n", dprintkdbg(DBG_0, "srb_done: (0x%p) done result=0x%08x\n",
cmd, cmd->result); cmd, cmd->result);
list_move_tail(&srb->list, &acb->srb_free_list); list_move_tail(&srb->list, &acb->srb_free_list);
} else { } else {
dprintkl(KERN_ERR, "srb_done: ERROR! Completed cmd with tmp_srb\n"); dprintkl(KERN_ERR, "srb_done: ERROR! Completed cmd with tmp_srb\n");
@ -3381,16 +3354,14 @@ static void doing_srb_done(struct AdapterCtlBlk *acb, u8 did_flag,
struct scsi_cmnd *p; struct scsi_cmnd *p;
list_for_each_entry_safe(srb, tmp, &dcb->srb_going_list, list) { list_for_each_entry_safe(srb, tmp, &dcb->srb_going_list, list) {
int result;
p = srb->cmd; p = srb->cmd;
result = MK_RES(0, did_flag, 0, 0);
printk("G:%p(%02i-%i) ", p, printk("G:%p(%02i-%i) ", p,
p->device->id, (u8)p->device->lun); p->device->id, (u8)p->device->lun);
list_del(&srb->list); list_del(&srb->list);
free_tag(dcb, srb); free_tag(dcb, srb);
list_add_tail(&srb->list, &acb->srb_free_list); list_add_tail(&srb->list, &acb->srb_free_list);
p->result = result; set_host_byte(p, did_flag);
set_status_byte(p, SAM_STAT_GOOD);
pci_unmap_srb_sense(acb, srb); pci_unmap_srb_sense(acb, srb);
pci_unmap_srb(acb, srb); pci_unmap_srb(acb, srb);
if (force) { if (force) {
@ -3411,14 +3382,13 @@ static void doing_srb_done(struct AdapterCtlBlk *acb, u8 did_flag,
/* Waiting queue */ /* Waiting queue */
list_for_each_entry_safe(srb, tmp, &dcb->srb_waiting_list, list) { list_for_each_entry_safe(srb, tmp, &dcb->srb_waiting_list, list) {
int result;
p = srb->cmd; p = srb->cmd;
result = MK_RES(0, did_flag, 0, 0);
printk("W:%p<%02i-%i>", p, p->device->id, printk("W:%p<%02i-%i>", p, p->device->id,
(u8)p->device->lun); (u8)p->device->lun);
list_move_tail(&srb->list, &acb->srb_free_list); list_move_tail(&srb->list, &acb->srb_free_list);
p->result = result; set_host_byte(p, did_flag);
set_status_byte(p, SAM_STAT_GOOD);
pci_unmap_srb_sense(acb, srb); pci_unmap_srb_sense(acb, srb);
pci_unmap_srb(acb, srb); pci_unmap_srb(acb, srb);
if (force) { if (force) {

View File

@ -563,12 +563,12 @@ static int alua_rtpg(struct scsi_device *sdev, struct alua_port_group *pg)
kfree(buff); kfree(buff);
return SCSI_DH_OK; return SCSI_DH_OK;
} }
if (!scsi_sense_valid(&sense_hdr)) { if (retval < 0 || !scsi_sense_valid(&sense_hdr)) {
sdev_printk(KERN_INFO, sdev, sdev_printk(KERN_INFO, sdev,
"%s: rtpg failed, result %d\n", "%s: rtpg failed, result %d\n",
ALUA_DH_NAME, retval); ALUA_DH_NAME, retval);
kfree(buff); kfree(buff);
if (driver_byte(retval) == DRIVER_ERROR) if (retval < 0)
return SCSI_DH_DEV_TEMP_BUSY; return SCSI_DH_DEV_TEMP_BUSY;
if (host_byte(retval) == DID_NO_CONNECT) if (host_byte(retval) == DID_NO_CONNECT)
return SCSI_DH_RES_TEMP_UNAVAIL; return SCSI_DH_RES_TEMP_UNAVAIL;
@ -794,11 +794,11 @@ static unsigned alua_stpg(struct scsi_device *sdev, struct alua_port_group *pg)
retval = submit_stpg(sdev, pg->group_id, &sense_hdr); retval = submit_stpg(sdev, pg->group_id, &sense_hdr);
if (retval) { if (retval) {
if (!scsi_sense_valid(&sense_hdr)) { if (retval < 0 || !scsi_sense_valid(&sense_hdr)) {
sdev_printk(KERN_INFO, sdev, sdev_printk(KERN_INFO, sdev,
"%s: stpg failed, result %d", "%s: stpg failed, result %d",
ALUA_DH_NAME, retval); ALUA_DH_NAME, retval);
if (driver_byte(retval) == DRIVER_ERROR) if (retval < 0)
return SCSI_DH_DEV_TEMP_BUSY; return SCSI_DH_DEV_TEMP_BUSY;
} else { } else {
sdev_printk(KERN_INFO, sdev, "%s: stpg failed\n", sdev_printk(KERN_INFO, sdev, "%s: stpg failed\n",

View File

@ -1525,7 +1525,7 @@ void esas2r_complete_request_cb(struct esas2r_adapter *a,
rq->cmd->result = rq->cmd->result =
((esas2r_req_status_to_error(rq->req_stat) << 16) ((esas2r_req_status_to_error(rq->req_stat) << 16)
| (rq->func_rsp.scsi_rsp.scsi_stat & STATUS_MASK)); | rq->func_rsp.scsi_rsp.scsi_stat);
if (rq->req_stat == RS_UNDERRUN) if (rq->req_stat == RS_UNDERRUN)
scsi_set_resid(rq->cmd, scsi_set_resid(rq->cmd,

View File

@ -922,9 +922,7 @@ static void esp_cmd_is_done(struct esp *esp, struct esp_cmd_entry *ent,
* saw originally. Also, report that we are providing * saw originally. Also, report that we are providing
* the sense data. * the sense data.
*/ */
cmd->result = ((DRIVER_SENSE << 24) | cmd->result = SAM_STAT_CHECK_CONDITION;
(DID_OK << 16) |
(SAM_STAT_CHECK_CONDITION << 0));
ent->flags &= ~ESP_CMD_FLAG_AUTOSENSE; ent->flags &= ~ESP_CMD_FLAG_AUTOSENSE;
if (esp_debug & ESP_DEBUG_AUTOSENSE) { if (esp_debug & ESP_DEBUG_AUTOSENSE) {

View File

@ -202,11 +202,10 @@ static int fdomain_select(struct Scsi_Host *sh, int target)
return 1; return 1;
} }
static void fdomain_finish_cmd(struct fdomain *fd, int result) static void fdomain_finish_cmd(struct fdomain *fd)
{ {
outb(0, fd->base + REG_ICTL); outb(0, fd->base + REG_ICTL);
fdomain_make_bus_idle(fd); fdomain_make_bus_idle(fd);
fd->cur_cmd->result = result;
fd->cur_cmd->scsi_done(fd->cur_cmd); fd->cur_cmd->scsi_done(fd->cur_cmd);
fd->cur_cmd = NULL; fd->cur_cmd = NULL;
} }
@ -273,7 +272,8 @@ static void fdomain_work(struct work_struct *work)
if (cmd->SCp.phase & in_arbitration) { if (cmd->SCp.phase & in_arbitration) {
status = inb(fd->base + REG_ASTAT); status = inb(fd->base + REG_ASTAT);
if (!(status & ASTAT_ARB)) { if (!(status & ASTAT_ARB)) {
fdomain_finish_cmd(fd, DID_BUS_BUSY << 16); set_host_byte(cmd, DID_BUS_BUSY);
fdomain_finish_cmd(fd);
goto out; goto out;
} }
cmd->SCp.phase = in_selection; cmd->SCp.phase = in_selection;
@ -290,7 +290,8 @@ static void fdomain_work(struct work_struct *work)
if (!(status & BSTAT_BSY)) { if (!(status & BSTAT_BSY)) {
/* Try again, for slow devices */ /* Try again, for slow devices */
if (fdomain_select(cmd->device->host, scmd_id(cmd))) { if (fdomain_select(cmd->device->host, scmd_id(cmd))) {
fdomain_finish_cmd(fd, DID_NO_CONNECT << 16); set_host_byte(cmd, DID_NO_CONNECT);
fdomain_finish_cmd(fd);
goto out; goto out;
} }
/* Stop arbitration and enable parity */ /* Stop arbitration and enable parity */
@ -333,7 +334,7 @@ static void fdomain_work(struct work_struct *work)
break; break;
case BSTAT_MSG | BSTAT_CMD | BSTAT_IO: /* MESSAGE IN */ case BSTAT_MSG | BSTAT_CMD | BSTAT_IO: /* MESSAGE IN */
cmd->SCp.Message = inb(fd->base + REG_SCSI_DATA); cmd->SCp.Message = inb(fd->base + REG_SCSI_DATA);
if (!cmd->SCp.Message) if (cmd->SCp.Message == COMMAND_COMPLETE)
++done; ++done;
break; break;
} }
@ -359,9 +360,10 @@ static void fdomain_work(struct work_struct *work)
fdomain_read_data(cmd); fdomain_read_data(cmd);
if (done) { if (done) {
fdomain_finish_cmd(fd, (cmd->SCp.Status & 0xff) | set_status_byte(cmd, cmd->SCp.Status);
((cmd->SCp.Message & 0xff) << 8) | set_host_byte(cmd, DID_OK);
(DID_OK << 16)); scsi_msg_to_host_byte(cmd, cmd->SCp.Message);
fdomain_finish_cmd(fd);
} else { } else {
if (cmd->SCp.phase & disconnect) { if (cmd->SCp.phase & disconnect) {
outb(ICTL_FIFO | ICTL_SEL | ICTL_REQ | FIFO_COUNT, outb(ICTL_FIFO | ICTL_SEL | ICTL_REQ | FIFO_COUNT,
@ -439,10 +441,10 @@ static int fdomain_abort(struct scsi_cmnd *cmd)
fdomain_make_bus_idle(fd); fdomain_make_bus_idle(fd);
fd->cur_cmd->SCp.phase |= aborted; fd->cur_cmd->SCp.phase |= aborted;
fd->cur_cmd->result = DID_ABORT << 16;
/* Aborts are not done well. . . */ /* Aborts are not done well. . . */
fdomain_finish_cmd(fd, DID_ABORT << 16); set_host_byte(fd->cur_cmd, DID_ABORT);
fdomain_finish_cmd(fd);
spin_unlock_irqrestore(sh->host_lock, flags); spin_unlock_irqrestore(sh->host_lock, flags);
return SUCCESS; return SUCCESS;
} }

View File

@ -760,7 +760,7 @@ static void hptiop_finish_scsi_req(struct hptiop_hba *hba, u32 tag,
goto skip_resid; goto skip_resid;
default: default:
scp->result = DRIVER_INVALID << 24 | DID_ABORT << 16; scp->result = DID_ABORT << 16;
break; break;
} }

View File

@ -1005,7 +1005,7 @@ static void handle_cmd_rsp(struct srp_event_struct *evt_struct)
if (cmnd) { if (cmnd) {
cmnd->result |= rsp->status; cmnd->result |= rsp->status;
if (((cmnd->result >> 1) & 0x1f) == CHECK_CONDITION) if (scsi_status_is_check_condition(cmnd->result))
memcpy(cmnd->sense_buffer, memcpy(cmnd->sense_buffer,
rsp->data, rsp->data,
be32_to_cpu(rsp->sense_data_len)); be32_to_cpu(rsp->sense_data_len));

View File

@ -829,10 +829,7 @@ static void iscsi_scsi_cmd_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
ascq = session->tt->check_protection(task, &sector); ascq = session->tt->check_protection(task, &sector);
if (ascq) { if (ascq) {
sc->result = DRIVER_SENSE << 24 | scsi_build_sense(sc, 1, ILLEGAL_REQUEST, 0x10, ascq);
SAM_STAT_CHECK_CONDITION;
scsi_build_sense_buffer(1, sc->sense_buffer,
ILLEGAL_REQUEST, 0x10, ascq);
scsi_set_sense_information(sc->sense_buffer, scsi_set_sense_information(sc->sense_buffer,
SCSI_SENSE_BUFFERSIZE, SCSI_SENSE_BUFFERSIZE,
sector); sector);

View File

@ -2896,10 +2896,8 @@ skipit:
} }
out: out:
if (err_type == BGS_GUARD_ERR_MASK) { if (err_type == BGS_GUARD_ERR_MASK) {
scsi_build_sense_buffer(1, cmd->sense_buffer, ILLEGAL_REQUEST, scsi_build_sense(cmd, 1, ILLEGAL_REQUEST, 0x10, 0x1);
0x10, 0x1); set_host_byte(cmd, DID_ABORT);
cmd->result = DRIVER_SENSE << 24 | DID_ABORT << 16 |
SAM_STAT_CHECK_CONDITION;
phba->bg_guard_err_cnt++; phba->bg_guard_err_cnt++;
lpfc_printf_log(phba, KERN_WARNING, LOG_FCP | LOG_BG, lpfc_printf_log(phba, KERN_WARNING, LOG_FCP | LOG_BG,
"9069 BLKGRD: reftag %x grd_tag err %x != %x\n", "9069 BLKGRD: reftag %x grd_tag err %x != %x\n",
@ -2907,10 +2905,8 @@ out:
sum, guard_tag); sum, guard_tag);
} else if (err_type == BGS_REFTAG_ERR_MASK) { } else if (err_type == BGS_REFTAG_ERR_MASK) {
scsi_build_sense_buffer(1, cmd->sense_buffer, ILLEGAL_REQUEST, scsi_build_sense(cmd, 1, ILLEGAL_REQUEST, 0x10, 0x3);
0x10, 0x3); set_host_byte(cmd, DID_ABORT);
cmd->result = DRIVER_SENSE << 24 | DID_ABORT << 16 |
SAM_STAT_CHECK_CONDITION;
phba->bg_reftag_err_cnt++; phba->bg_reftag_err_cnt++;
lpfc_printf_log(phba, KERN_WARNING, LOG_FCP | LOG_BG, lpfc_printf_log(phba, KERN_WARNING, LOG_FCP | LOG_BG,
@ -2919,10 +2915,8 @@ out:
ref_tag, start_ref_tag); ref_tag, start_ref_tag);
} else if (err_type == BGS_APPTAG_ERR_MASK) { } else if (err_type == BGS_APPTAG_ERR_MASK) {
scsi_build_sense_buffer(1, cmd->sense_buffer, ILLEGAL_REQUEST, scsi_build_sense(cmd, 1, ILLEGAL_REQUEST, 0x10, 0x2);
0x10, 0x2); set_host_byte(cmd, DID_ABORT);
cmd->result = DRIVER_SENSE << 24 | DID_ABORT << 16 |
SAM_STAT_CHECK_CONDITION;
phba->bg_apptag_err_cnt++; phba->bg_apptag_err_cnt++;
lpfc_printf_log(phba, KERN_WARNING, LOG_FCP | LOG_BG, lpfc_printf_log(phba, KERN_WARNING, LOG_FCP | LOG_BG,
@ -2981,10 +2975,8 @@ lpfc_sli4_parse_bg_err(struct lpfc_hba *phba, struct lpfc_io_buf *lpfc_cmd,
if (lpfc_bgs_get_guard_err(bgstat)) { if (lpfc_bgs_get_guard_err(bgstat)) {
ret = 1; ret = 1;
scsi_build_sense_buffer(1, cmd->sense_buffer, ILLEGAL_REQUEST, scsi_build_sense(cmd, 1, ILLEGAL_REQUEST, 0x10, 0x1);
0x10, 0x1); set_host_byte(cmd, DID_ABORT);
cmd->result = DRIVER_SENSE << 24 | DID_ABORT << 16 |
SAM_STAT_CHECK_CONDITION;
phba->bg_guard_err_cnt++; phba->bg_guard_err_cnt++;
lpfc_printf_log(phba, KERN_WARNING, LOG_FCP | LOG_BG, lpfc_printf_log(phba, KERN_WARNING, LOG_FCP | LOG_BG,
"9059 BLKGRD: Guard Tag error in cmd" "9059 BLKGRD: Guard Tag error in cmd"
@ -2997,10 +2989,8 @@ lpfc_sli4_parse_bg_err(struct lpfc_hba *phba, struct lpfc_io_buf *lpfc_cmd,
if (lpfc_bgs_get_reftag_err(bgstat)) { if (lpfc_bgs_get_reftag_err(bgstat)) {
ret = 1; ret = 1;
scsi_build_sense_buffer(1, cmd->sense_buffer, ILLEGAL_REQUEST, scsi_build_sense(cmd, 1, ILLEGAL_REQUEST, 0x10, 0x3);
0x10, 0x3); set_host_byte(cmd, DID_ABORT);
cmd->result = DRIVER_SENSE << 24 | DID_ABORT << 16 |
SAM_STAT_CHECK_CONDITION;
phba->bg_reftag_err_cnt++; phba->bg_reftag_err_cnt++;
lpfc_printf_log(phba, KERN_WARNING, LOG_FCP | LOG_BG, lpfc_printf_log(phba, KERN_WARNING, LOG_FCP | LOG_BG,
@ -3014,10 +3004,8 @@ lpfc_sli4_parse_bg_err(struct lpfc_hba *phba, struct lpfc_io_buf *lpfc_cmd,
if (lpfc_bgs_get_apptag_err(bgstat)) { if (lpfc_bgs_get_apptag_err(bgstat)) {
ret = 1; ret = 1;
scsi_build_sense_buffer(1, cmd->sense_buffer, ILLEGAL_REQUEST, scsi_build_sense(cmd, 1, ILLEGAL_REQUEST, 0x10, 0x2);
0x10, 0x2); set_host_byte(cmd, DID_ABORT);
cmd->result = DRIVER_SENSE << 24 | DID_ABORT << 16 |
SAM_STAT_CHECK_CONDITION;
phba->bg_apptag_err_cnt++; phba->bg_apptag_err_cnt++;
lpfc_printf_log(phba, KERN_WARNING, LOG_FCP | LOG_BG, lpfc_printf_log(phba, KERN_WARNING, LOG_FCP | LOG_BG,
@ -3127,10 +3115,8 @@ lpfc_parse_bg_err(struct lpfc_hba *phba, struct lpfc_io_buf *lpfc_cmd,
if (lpfc_bgs_get_guard_err(bgstat)) { if (lpfc_bgs_get_guard_err(bgstat)) {
ret = 1; ret = 1;
scsi_build_sense_buffer(1, cmd->sense_buffer, ILLEGAL_REQUEST, scsi_build_sense(cmd, 1, ILLEGAL_REQUEST, 0x10, 0x1);
0x10, 0x1); set_host_byte(cmd, DID_ABORT);
cmd->result = DRIVER_SENSE << 24 | DID_ABORT << 16 |
SAM_STAT_CHECK_CONDITION;
phba->bg_guard_err_cnt++; phba->bg_guard_err_cnt++;
lpfc_printf_log(phba, KERN_WARNING, LOG_FCP | LOG_BG, lpfc_printf_log(phba, KERN_WARNING, LOG_FCP | LOG_BG,
"9055 BLKGRD: Guard Tag error in cmd " "9055 BLKGRD: Guard Tag error in cmd "
@ -3143,10 +3129,8 @@ lpfc_parse_bg_err(struct lpfc_hba *phba, struct lpfc_io_buf *lpfc_cmd,
if (lpfc_bgs_get_reftag_err(bgstat)) { if (lpfc_bgs_get_reftag_err(bgstat)) {
ret = 1; ret = 1;
scsi_build_sense_buffer(1, cmd->sense_buffer, ILLEGAL_REQUEST, scsi_build_sense(cmd, 1, ILLEGAL_REQUEST, 0x10, 0x3);
0x10, 0x3); set_host_byte(cmd, DID_ABORT);
cmd->result = DRIVER_SENSE << 24 | DID_ABORT << 16 |
SAM_STAT_CHECK_CONDITION;
phba->bg_reftag_err_cnt++; phba->bg_reftag_err_cnt++;
lpfc_printf_log(phba, KERN_WARNING, LOG_FCP | LOG_BG, lpfc_printf_log(phba, KERN_WARNING, LOG_FCP | LOG_BG,
@ -3160,10 +3144,8 @@ lpfc_parse_bg_err(struct lpfc_hba *phba, struct lpfc_io_buf *lpfc_cmd,
if (lpfc_bgs_get_apptag_err(bgstat)) { if (lpfc_bgs_get_apptag_err(bgstat)) {
ret = 1; ret = 1;
scsi_build_sense_buffer(1, cmd->sense_buffer, ILLEGAL_REQUEST, scsi_build_sense(cmd, 1, ILLEGAL_REQUEST, 0x10, 0x2);
0x10, 0x2); set_host_byte(cmd, DID_ABORT);
cmd->result = DRIVER_SENSE << 24 | DID_ABORT << 16 |
SAM_STAT_CHECK_CONDITION;
phba->bg_apptag_err_cnt++; phba->bg_apptag_err_cnt++;
lpfc_printf_log(phba, KERN_WARNING, LOG_FCP | LOG_BG, lpfc_printf_log(phba, KERN_WARNING, LOG_FCP | LOG_BG,

View File

@ -1583,9 +1583,7 @@ mega_cmd_done(adapter_t *adapter, u8 completed[], int nstatus, int status)
memcpy(cmd->sense_buffer, pthru->reqsensearea, memcpy(cmd->sense_buffer, pthru->reqsensearea,
14); 14);
cmd->result = (DRIVER_SENSE << 24) | cmd->result = SAM_STAT_CHECK_CONDITION;
(DID_OK << 16) |
(CHECK_CONDITION << 1);
} }
else { else {
if (mbox->m_out.cmd == MEGA_MBOXCMD_EXTPTHRU) { if (mbox->m_out.cmd == MEGA_MBOXCMD_EXTPTHRU) {
@ -1593,14 +1591,10 @@ mega_cmd_done(adapter_t *adapter, u8 completed[], int nstatus, int status)
memcpy(cmd->sense_buffer, memcpy(cmd->sense_buffer,
epthru->reqsensearea, 14); epthru->reqsensearea, 14);
cmd->result = (DRIVER_SENSE << 24) | cmd->result = SAM_STAT_CHECK_CONDITION;
(DID_OK << 16) | } else
(CHECK_CONDITION << 1); scsi_build_sense(cmd, 0,
} else { ABORTED_COMMAND, 0, 0);
cmd->sense_buffer[0] = 0x70;
cmd->sense_buffer[2] = ABORTED_COMMAND;
cmd->result |= (CHECK_CONDITION << 1);
}
} }
break; break;
@ -1617,7 +1611,7 @@ mega_cmd_done(adapter_t *adapter, u8 completed[], int nstatus, int status)
*/ */
if( cmd->cmnd[0] == TEST_UNIT_READY ) { if( cmd->cmnd[0] == TEST_UNIT_READY ) {
cmd->result |= (DID_ERROR << 16) | cmd->result |= (DID_ERROR << 16) |
(RESERVATION_CONFLICT << 1); SAM_STAT_RESERVATION_CONFLICT;
} }
else else
/* /*
@ -1629,7 +1623,7 @@ mega_cmd_done(adapter_t *adapter, u8 completed[], int nstatus, int status)
cmd->cmnd[0] == RELEASE) ) { cmd->cmnd[0] == RELEASE) ) {
cmd->result |= (DID_ERROR << 16) | cmd->result |= (DID_ERROR << 16) |
(RESERVATION_CONFLICT << 1); SAM_STAT_RESERVATION_CONFLICT;
} }
else else
#endif #endif

View File

@ -1574,10 +1574,8 @@ megaraid_mbox_build_cmd(adapter_t *adapter, struct scsi_cmnd *scp, int *busy)
} }
if (scp->cmnd[1] & MEGA_SCSI_INQ_EVPD) { if (scp->cmnd[1] & MEGA_SCSI_INQ_EVPD) {
scp->sense_buffer[0] = 0x70; scsi_build_sense(scp, 0, ILLEGAL_REQUEST,
scp->sense_buffer[2] = ILLEGAL_REQUEST; MEGA_INVALID_FIELD_IN_CDB, 0);
scp->sense_buffer[12] = MEGA_INVALID_FIELD_IN_CDB;
scp->result = CHECK_CONDITION << 1;
return NULL; return NULL;
} }
@ -2301,8 +2299,7 @@ megaraid_mbox_dpc(unsigned long devp)
memcpy(scp->sense_buffer, pthru->reqsensearea, memcpy(scp->sense_buffer, pthru->reqsensearea,
14); 14);
scp->result = DRIVER_SENSE << 24 | scp->result = SAM_STAT_CHECK_CONDITION;
DID_OK << 16 | CHECK_CONDITION << 1;
} }
else { else {
if (mbox->cmd == MBOXCMD_EXTPTHRU) { if (mbox->cmd == MBOXCMD_EXTPTHRU) {
@ -2310,14 +2307,10 @@ megaraid_mbox_dpc(unsigned long devp)
memcpy(scp->sense_buffer, memcpy(scp->sense_buffer,
epthru->reqsensearea, 14); epthru->reqsensearea, 14);
scp->result = DRIVER_SENSE << 24 | scp->result = SAM_STAT_CHECK_CONDITION;
DID_OK << 16 | } else
CHECK_CONDITION << 1; scsi_build_sense(scp, 0,
} else { ABORTED_COMMAND, 0, 0);
scp->sense_buffer[0] = 0x70;
scp->sense_buffer[2] = ABORTED_COMMAND;
scp->result = CHECK_CONDITION << 1;
}
} }
break; break;
@ -2334,7 +2327,7 @@ megaraid_mbox_dpc(unsigned long devp)
*/ */
if (scp->cmnd[0] == TEST_UNIT_READY) { if (scp->cmnd[0] == TEST_UNIT_READY) {
scp->result = DID_ERROR << 16 | scp->result = DID_ERROR << 16 |
RESERVATION_CONFLICT << 1; SAM_STAT_RESERVATION_CONFLICT;
} }
else else
/* /*
@ -2345,7 +2338,7 @@ megaraid_mbox_dpc(unsigned long devp)
scp->cmnd[0] == RELEASE)) { scp->cmnd[0] == RELEASE)) {
scp->result = DID_ERROR << 16 | scp->result = DID_ERROR << 16 |
RESERVATION_CONFLICT << 1; SAM_STAT_RESERVATION_CONFLICT;
} }
else { else {
scp->result = DID_BAD_TARGET << 16 | status; scp->result = DID_BAD_TARGET << 16 | status;

View File

@ -3667,8 +3667,6 @@ megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd,
SCSI_SENSE_BUFFERSIZE); SCSI_SENSE_BUFFERSIZE);
memcpy(cmd->scmd->sense_buffer, cmd->sense, memcpy(cmd->scmd->sense_buffer, cmd->sense,
hdr->sense_len); hdr->sense_len);
cmd->scmd->result |= DRIVER_SENSE << 24;
} }
break; break;

View File

@ -2051,7 +2051,6 @@ map_cmd_status(struct fusion_context *fusion,
SCSI_SENSE_BUFFERSIZE); SCSI_SENSE_BUFFERSIZE);
memcpy(scmd->sense_buffer, sense, memcpy(scmd->sense_buffer, sense,
SCSI_SENSE_BUFFERSIZE); SCSI_SENSE_BUFFERSIZE);
scmd->result |= DRIVER_SENSE << 24;
} }
/* /*

View File

@ -595,9 +595,10 @@ static void mesh_done(struct mesh_state *ms, int start_next)
ms->current_req = NULL; ms->current_req = NULL;
tp->current_req = NULL; tp->current_req = NULL;
if (cmd) { if (cmd) {
cmd->result = (ms->stat << 16) | cmd->SCp.Status; set_host_byte(cmd, ms->stat);
set_status_byte(cmd, cmd->SCp.Status);
if (ms->stat == DID_OK) if (ms->stat == DID_OK)
cmd->result |= cmd->SCp.Message << 8; scsi_msg_to_host_byte(cmd, cmd->SCp.Message);
if (DEBUG_TARGET(cmd)) { if (DEBUG_TARGET(cmd)) {
printk(KERN_DEBUG "mesh_done: result = %x, data_ptr=%d, buflen=%d\n", printk(KERN_DEBUG "mesh_done: result = %x, data_ptr=%d, buflen=%d\n",
cmd->result, ms->data_ptr, scsi_bufflen(cmd)); cmd->result, ms->data_ptr, scsi_bufflen(cmd));
@ -993,7 +994,7 @@ static void handle_reset(struct mesh_state *ms)
for (tgt = 0; tgt < 8; ++tgt) { for (tgt = 0; tgt < 8; ++tgt) {
tp = &ms->tgts[tgt]; tp = &ms->tgts[tgt];
if ((cmd = tp->current_req) != NULL) { if ((cmd = tp->current_req) != NULL) {
cmd->result = DID_RESET << 16; set_host_byte(cmd, DID_RESET);
tp->current_req = NULL; tp->current_req = NULL;
mesh_completed(ms, cmd); mesh_completed(ms, cmd);
} }
@ -1003,7 +1004,7 @@ static void handle_reset(struct mesh_state *ms)
ms->current_req = NULL; ms->current_req = NULL;
while ((cmd = ms->request_q) != NULL) { while ((cmd = ms->request_q) != NULL) {
ms->request_q = (struct scsi_cmnd *) cmd->host_scribble; ms->request_q = (struct scsi_cmnd *) cmd->host_scribble;
cmd->result = DID_RESET << 16; set_host_byte(cmd, DID_RESET);
mesh_completed(ms, cmd); mesh_completed(ms, cmd);
} }
ms->phase = idle; ms->phase = idle;

View File

@ -2127,8 +2127,7 @@ static void mpi3mr_map_eedp_error(struct scsi_cmnd *scmd,
mpi3mr_build_sense_buffer(0, scmd->sense_buffer, ILLEGAL_REQUEST, mpi3mr_build_sense_buffer(0, scmd->sense_buffer, ILLEGAL_REQUEST,
0x10, ascq); 0x10, ascq);
scmd->result = DRIVER_SENSE << 24 | (DID_ABORT << 16) | scmd->result = (DID_ABORT << 16) | SAM_STAT_CHECK_CONDITION;
SAM_STAT_CHECK_CONDITION;
} }
/** /**
@ -3354,8 +3353,7 @@ static bool mpi3mr_check_return_unmap(struct mpi3mr_ioc *mrioc,
"%s: cdb received with invalid param_len: %d\n", "%s: cdb received with invalid param_len: %d\n",
__func__, param_len); __func__, param_len);
scsi_print_command(scmd); scsi_print_command(scmd);
scmd->result = (DRIVER_SENSE << 24) | scmd->result = SAM_STAT_CHECK_CONDITION;
SAM_STAT_CHECK_CONDITION;
scsi_build_sense_buffer(0, scmd->sense_buffer, ILLEGAL_REQUEST, scsi_build_sense_buffer(0, scmd->sense_buffer, ILLEGAL_REQUEST,
0x1A, 0); 0x1A, 0);
scmd->scsi_done(scmd); scmd->scsi_done(scmd);
@ -3366,8 +3364,7 @@ static bool mpi3mr_check_return_unmap(struct mpi3mr_ioc *mrioc,
"%s: cdb received with param_len: %d bufflen: %d\n", "%s: cdb received with param_len: %d bufflen: %d\n",
__func__, param_len, scsi_bufflen(scmd)); __func__, param_len, scsi_bufflen(scmd));
scsi_print_command(scmd); scsi_print_command(scmd);
scmd->result = (DRIVER_SENSE << 24) | scmd->result = SAM_STAT_CHECK_CONDITION;
SAM_STAT_CHECK_CONDITION;
scsi_build_sense_buffer(0, scmd->sense_buffer, ILLEGAL_REQUEST, scsi_build_sense_buffer(0, scmd->sense_buffer, ILLEGAL_REQUEST,
0x1A, 0); 0x1A, 0);
scmd->scsi_done(scmd); scmd->scsi_done(scmd);
@ -3376,8 +3373,7 @@ static bool mpi3mr_check_return_unmap(struct mpi3mr_ioc *mrioc,
buf = kzalloc(scsi_bufflen(scmd), GFP_ATOMIC); buf = kzalloc(scsi_bufflen(scmd), GFP_ATOMIC);
if (!buf) { if (!buf) {
scsi_print_command(scmd); scsi_print_command(scmd);
scmd->result = (DRIVER_SENSE << 24) | scmd->result = SAM_STAT_CHECK_CONDITION;
SAM_STAT_CHECK_CONDITION;
scsi_build_sense_buffer(0, scmd->sense_buffer, ILLEGAL_REQUEST, scsi_build_sense_buffer(0, scmd->sense_buffer, ILLEGAL_REQUEST,
0x55, 0x03); 0x55, 0x03);
scmd->scsi_done(scmd); scmd->scsi_done(scmd);
@ -3391,8 +3387,7 @@ static bool mpi3mr_check_return_unmap(struct mpi3mr_ioc *mrioc,
"%s: Invalid descriptor length in param list: %d\n", "%s: Invalid descriptor length in param list: %d\n",
__func__, desc_len); __func__, desc_len);
scsi_print_command(scmd); scsi_print_command(scmd);
scmd->result = (DRIVER_SENSE << 24) | scmd->result = SAM_STAT_CHECK_CONDITION;
SAM_STAT_CHECK_CONDITION;
scsi_build_sense_buffer(0, scmd->sense_buffer, ILLEGAL_REQUEST, scsi_build_sense_buffer(0, scmd->sense_buffer, ILLEGAL_REQUEST,
0x26, 0); 0x26, 0);
scmd->scsi_done(scmd); scmd->scsi_done(scmd);

View File

@ -5119,10 +5119,8 @@ _scsih_eedp_error_handling(struct scsi_cmnd *scmd, u16 ioc_status)
ascq = 0x00; ascq = 0x00;
break; break;
} }
scsi_build_sense_buffer(0, scmd->sense_buffer, ILLEGAL_REQUEST, 0x10, scsi_build_sense(scmd, 0, ILLEGAL_REQUEST, 0x10, ascq);
ascq); set_host_byte(scmd, DID_ABORT);
scmd->result = DRIVER_SENSE << 24 | (DID_ABORT << 16) |
SAM_STAT_CHECK_CONDITION;
} }
/** /**
@ -5879,12 +5877,8 @@ _scsih_io_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply)
else if (!xfer_cnt && scmd->cmnd[0] == REPORT_LUNS) { else if (!xfer_cnt && scmd->cmnd[0] == REPORT_LUNS) {
mpi_reply->SCSIState = MPI2_SCSI_STATE_AUTOSENSE_VALID; mpi_reply->SCSIState = MPI2_SCSI_STATE_AUTOSENSE_VALID;
mpi_reply->SCSIStatus = SAM_STAT_CHECK_CONDITION; mpi_reply->SCSIStatus = SAM_STAT_CHECK_CONDITION;
scmd->result = (DRIVER_SENSE << 24) | scsi_build_sense(scmd, 0, ILLEGAL_REQUEST,
SAM_STAT_CHECK_CONDITION; 0x20, 0);
scmd->sense_buffer[0] = 0x70;
scmd->sense_buffer[2] = ILLEGAL_REQUEST;
scmd->sense_buffer[12] = 0x20;
scmd->sense_buffer[13] = 0;
} }
break; break;

View File

@ -1317,11 +1317,10 @@ static void mvumi_complete_cmd(struct mvumi_hba *mhba, struct mvumi_cmd *cmd,
if (ob_frame->rsp_flag & CL_RSP_FLAG_SENSEDATA) { if (ob_frame->rsp_flag & CL_RSP_FLAG_SENSEDATA) {
memcpy(cmd->scmd->sense_buffer, ob_frame->payload, memcpy(cmd->scmd->sense_buffer, ob_frame->payload,
sizeof(struct mvumi_sense_data)); sizeof(struct mvumi_sense_data));
scmd->result |= (DRIVER_SENSE << 24);
} }
break; break;
default: default:
scmd->result |= (DRIVER_INVALID << 24) | (DID_ABORT << 16); scmd->result |= (DID_ABORT << 16);
break; break;
} }
@ -2068,10 +2067,7 @@ static unsigned char mvumi_build_frame(struct mvumi_hba *mhba,
return 0; return 0;
error: error:
scmd->result = (DID_OK << 16) | (DRIVER_SENSE << 24) | scsi_build_sense(scmd, 0, ILLEGAL_REQUEST, 0x24, 0);
SAM_STAT_CHECK_CONDITION;
scsi_build_sense_buffer(0, scmd->sense_buffer, ILLEGAL_REQUEST, 0x24,
0);
return -1; return -1;
} }
@ -2131,7 +2127,7 @@ static enum blk_eh_timer_return mvumi_timed_out(struct scsi_cmnd *scmd)
else else
atomic_dec(&mhba->fw_outstanding); atomic_dec(&mhba->fw_outstanding);
scmd->result = (DRIVER_INVALID << 24) | (DID_ABORT << 16); scmd->result = (DID_ABORT << 16);
scmd->SCp.ptr = NULL; scmd->SCp.ptr = NULL;
if (scsi_bufflen(scmd)) { if (scsi_bufflen(scmd)) {
dma_unmap_sg(&mhba->pdev->dev, scsi_sglist(scmd), dma_unmap_sg(&mhba->pdev->dev, scsi_sglist(scmd),

View File

@ -1397,8 +1397,7 @@ myrb_mode_sense(struct myrb_hba *cb, struct scsi_cmnd *scmd,
static void myrb_request_sense(struct myrb_hba *cb, static void myrb_request_sense(struct myrb_hba *cb,
struct scsi_cmnd *scmd) struct scsi_cmnd *scmd)
{ {
scsi_build_sense_buffer(0, scmd->sense_buffer, scsi_build_sense(scmd, 0, NO_SENSE, 0, 0);
NO_SENSE, 0, 0);
scsi_sg_copy_from_buffer(scmd, scmd->sense_buffer, scsi_sg_copy_from_buffer(scmd, scmd->sense_buffer,
SCSI_SENSE_BUFFERSIZE); SCSI_SENSE_BUFFERSIZE);
} }
@ -1447,10 +1446,7 @@ static int myrb_ldev_queuecommand(struct Scsi_Host *shost,
case INQUIRY: case INQUIRY:
if (scmd->cmnd[1] & 1) { if (scmd->cmnd[1] & 1) {
/* Illegal request, invalid field in CDB */ /* Illegal request, invalid field in CDB */
scsi_build_sense_buffer(0, scmd->sense_buffer, scsi_build_sense(scmd, 0, ILLEGAL_REQUEST, 0x24, 0);
ILLEGAL_REQUEST, 0x24, 0);
scmd->result = (DRIVER_SENSE << 24) |
SAM_STAT_CHECK_CONDITION;
} else { } else {
myrb_inquiry(cb, scmd); myrb_inquiry(cb, scmd);
scmd->result = (DID_OK << 16); scmd->result = (DID_OK << 16);
@ -1465,10 +1461,7 @@ static int myrb_ldev_queuecommand(struct Scsi_Host *shost,
if ((scmd->cmnd[2] & 0x3F) != 0x3F && if ((scmd->cmnd[2] & 0x3F) != 0x3F &&
(scmd->cmnd[2] & 0x3F) != 0x08) { (scmd->cmnd[2] & 0x3F) != 0x08) {
/* Illegal request, invalid field in CDB */ /* Illegal request, invalid field in CDB */
scsi_build_sense_buffer(0, scmd->sense_buffer, scsi_build_sense(scmd, 0, ILLEGAL_REQUEST, 0x24, 0);
ILLEGAL_REQUEST, 0x24, 0);
scmd->result = (DRIVER_SENSE << 24) |
SAM_STAT_CHECK_CONDITION;
} else { } else {
myrb_mode_sense(cb, scmd, ldev_info); myrb_mode_sense(cb, scmd, ldev_info);
scmd->result = (DID_OK << 16); scmd->result = (DID_OK << 16);
@ -1479,20 +1472,14 @@ static int myrb_ldev_queuecommand(struct Scsi_Host *shost,
if ((scmd->cmnd[1] & 1) || if ((scmd->cmnd[1] & 1) ||
(scmd->cmnd[8] & 1)) { (scmd->cmnd[8] & 1)) {
/* Illegal request, invalid field in CDB */ /* Illegal request, invalid field in CDB */
scsi_build_sense_buffer(0, scmd->sense_buffer, scsi_build_sense(scmd, 0, ILLEGAL_REQUEST, 0x24, 0);
ILLEGAL_REQUEST, 0x24, 0);
scmd->result = (DRIVER_SENSE << 24) |
SAM_STAT_CHECK_CONDITION;
scmd->scsi_done(scmd); scmd->scsi_done(scmd);
return 0; return 0;
} }
lba = get_unaligned_be32(&scmd->cmnd[2]); lba = get_unaligned_be32(&scmd->cmnd[2]);
if (lba) { if (lba) {
/* Illegal request, invalid field in CDB */ /* Illegal request, invalid field in CDB */
scsi_build_sense_buffer(0, scmd->sense_buffer, scsi_build_sense(scmd, 0, ILLEGAL_REQUEST, 0x24, 0);
ILLEGAL_REQUEST, 0x24, 0);
scmd->result = (DRIVER_SENSE << 24) |
SAM_STAT_CHECK_CONDITION;
scmd->scsi_done(scmd); scmd->scsi_done(scmd);
return 0; return 0;
} }
@ -1506,10 +1493,7 @@ static int myrb_ldev_queuecommand(struct Scsi_Host *shost,
case SEND_DIAGNOSTIC: case SEND_DIAGNOSTIC:
if (scmd->cmnd[1] != 0x04) { if (scmd->cmnd[1] != 0x04) {
/* Illegal request, invalid field in CDB */ /* Illegal request, invalid field in CDB */
scsi_build_sense_buffer(0, scmd->sense_buffer, scsi_build_sense(scmd, 0, ILLEGAL_REQUEST, 0x24, 0);
ILLEGAL_REQUEST, 0x24, 0);
scmd->result = (DRIVER_SENSE << 24) |
SAM_STAT_CHECK_CONDITION;
} else { } else {
/* Assume good status */ /* Assume good status */
scmd->result = (DID_OK << 16); scmd->result = (DID_OK << 16);
@ -1519,10 +1503,7 @@ static int myrb_ldev_queuecommand(struct Scsi_Host *shost,
case READ_6: case READ_6:
if (ldev_info->state == MYRB_DEVICE_WO) { if (ldev_info->state == MYRB_DEVICE_WO) {
/* Data protect, attempt to read invalid data */ /* Data protect, attempt to read invalid data */
scsi_build_sense_buffer(0, scmd->sense_buffer, scsi_build_sense(scmd, 0, DATA_PROTECT, 0x21, 0x06);
DATA_PROTECT, 0x21, 0x06);
scmd->result = (DRIVER_SENSE << 24) |
SAM_STAT_CHECK_CONDITION;
scmd->scsi_done(scmd); scmd->scsi_done(scmd);
return 0; return 0;
} }
@ -1536,10 +1517,7 @@ static int myrb_ldev_queuecommand(struct Scsi_Host *shost,
case READ_10: case READ_10:
if (ldev_info->state == MYRB_DEVICE_WO) { if (ldev_info->state == MYRB_DEVICE_WO) {
/* Data protect, attempt to read invalid data */ /* Data protect, attempt to read invalid data */
scsi_build_sense_buffer(0, scmd->sense_buffer, scsi_build_sense(scmd, 0, DATA_PROTECT, 0x21, 0x06);
DATA_PROTECT, 0x21, 0x06);
scmd->result = (DRIVER_SENSE << 24) |
SAM_STAT_CHECK_CONDITION;
scmd->scsi_done(scmd); scmd->scsi_done(scmd);
return 0; return 0;
} }
@ -1553,10 +1531,7 @@ static int myrb_ldev_queuecommand(struct Scsi_Host *shost,
case READ_12: case READ_12:
if (ldev_info->state == MYRB_DEVICE_WO) { if (ldev_info->state == MYRB_DEVICE_WO) {
/* Data protect, attempt to read invalid data */ /* Data protect, attempt to read invalid data */
scsi_build_sense_buffer(0, scmd->sense_buffer, scsi_build_sense(scmd, 0, DATA_PROTECT, 0x21, 0x06);
DATA_PROTECT, 0x21, 0x06);
scmd->result = (DRIVER_SENSE << 24) |
SAM_STAT_CHECK_CONDITION;
scmd->scsi_done(scmd); scmd->scsi_done(scmd);
return 0; return 0;
} }
@ -1569,9 +1544,7 @@ static int myrb_ldev_queuecommand(struct Scsi_Host *shost,
break; break;
default: default:
/* Illegal request, invalid opcode */ /* Illegal request, invalid opcode */
scsi_build_sense_buffer(0, scmd->sense_buffer, scsi_build_sense(scmd, 0, ILLEGAL_REQUEST, 0x20, 0);
ILLEGAL_REQUEST, 0x20, 0);
scmd->result = (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION;
scmd->scsi_done(scmd); scmd->scsi_done(scmd);
return 0; return 0;
} }
@ -2352,25 +2325,19 @@ static void myrb_handle_scsi(struct myrb_hba *cb, struct myrb_cmdblk *cmd_blk,
"Bad Data Encountered\n"); "Bad Data Encountered\n");
if (scmd->sc_data_direction == DMA_FROM_DEVICE) if (scmd->sc_data_direction == DMA_FROM_DEVICE)
/* Unrecovered read error */ /* Unrecovered read error */
scsi_build_sense_buffer(0, scmd->sense_buffer, scsi_build_sense(scmd, 0, MEDIUM_ERROR, 0x11, 0);
MEDIUM_ERROR, 0x11, 0);
else else
/* Write error */ /* Write error */
scsi_build_sense_buffer(0, scmd->sense_buffer, scsi_build_sense(scmd, 0, MEDIUM_ERROR, 0x0C, 0);
MEDIUM_ERROR, 0x0C, 0);
scmd->result = (DID_OK << 16) | SAM_STAT_CHECK_CONDITION;
break; break;
case MYRB_STATUS_IRRECOVERABLE_DATA_ERROR: case MYRB_STATUS_IRRECOVERABLE_DATA_ERROR:
scmd_printk(KERN_ERR, scmd, "Irrecoverable Data Error\n"); scmd_printk(KERN_ERR, scmd, "Irrecoverable Data Error\n");
if (scmd->sc_data_direction == DMA_FROM_DEVICE) if (scmd->sc_data_direction == DMA_FROM_DEVICE)
/* Unrecovered read error, auto-reallocation failed */ /* Unrecovered read error, auto-reallocation failed */
scsi_build_sense_buffer(0, scmd->sense_buffer, scsi_build_sense(scmd, 0, MEDIUM_ERROR, 0x11, 0x04);
MEDIUM_ERROR, 0x11, 0x04);
else else
/* Write error, auto-reallocation failed */ /* Write error, auto-reallocation failed */
scsi_build_sense_buffer(0, scmd->sense_buffer, scsi_build_sense(scmd, 0, MEDIUM_ERROR, 0x0C, 0x02);
MEDIUM_ERROR, 0x0C, 0x02);
scmd->result = (DID_OK << 16) | SAM_STAT_CHECK_CONDITION;
break; break;
case MYRB_STATUS_LDRV_NONEXISTENT_OR_OFFLINE: case MYRB_STATUS_LDRV_NONEXISTENT_OR_OFFLINE:
dev_dbg(&scmd->device->sdev_gendev, dev_dbg(&scmd->device->sdev_gendev,
@ -2381,8 +2348,7 @@ static void myrb_handle_scsi(struct myrb_hba *cb, struct myrb_cmdblk *cmd_blk,
dev_dbg(&scmd->device->sdev_gendev, dev_dbg(&scmd->device->sdev_gendev,
"Attempt to Access Beyond End of Logical Drive"); "Attempt to Access Beyond End of Logical Drive");
/* Logical block address out of range */ /* Logical block address out of range */
scsi_build_sense_buffer(0, scmd->sense_buffer, scsi_build_sense(scmd, 0, NOT_READY, 0x21, 0);
NOT_READY, 0x21, 0);
break; break;
case MYRB_STATUS_DEVICE_NONRESPONSIVE: case MYRB_STATUS_DEVICE_NONRESPONSIVE:
dev_dbg(&scmd->device->sdev_gendev, "Device nonresponsive\n"); dev_dbg(&scmd->device->sdev_gendev, "Device nonresponsive\n");

View File

@ -1600,9 +1600,7 @@ static int myrs_queuecommand(struct Scsi_Host *shost,
switch (scmd->cmnd[0]) { switch (scmd->cmnd[0]) {
case REPORT_LUNS: case REPORT_LUNS:
scsi_build_sense_buffer(0, scmd->sense_buffer, ILLEGAL_REQUEST, scsi_build_sense(scmd, 0, ILLEGAL_REQUEST, 0x20, 0x0);
0x20, 0x0);
scmd->result = (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION;
scmd->scsi_done(scmd); scmd->scsi_done(scmd);
return 0; return 0;
case MODE_SENSE: case MODE_SENSE:
@ -1612,10 +1610,7 @@ static int myrs_queuecommand(struct Scsi_Host *shost,
if ((scmd->cmnd[2] & 0x3F) != 0x3F && if ((scmd->cmnd[2] & 0x3F) != 0x3F &&
(scmd->cmnd[2] & 0x3F) != 0x08) { (scmd->cmnd[2] & 0x3F) != 0x08) {
/* Illegal request, invalid field in CDB */ /* Illegal request, invalid field in CDB */
scsi_build_sense_buffer(0, scmd->sense_buffer, scsi_build_sense(scmd, 0, ILLEGAL_REQUEST, 0x24, 0);
ILLEGAL_REQUEST, 0x24, 0);
scmd->result = (DRIVER_SENSE << 24) |
SAM_STAT_CHECK_CONDITION;
} else { } else {
myrs_mode_sense(cs, scmd, ldev_info); myrs_mode_sense(cs, scmd, ldev_info);
scmd->result = (DID_OK << 16); scmd->result = (DID_OK << 16);

File diff suppressed because it is too large Load Diff

View File

@ -221,7 +221,7 @@ static int nsp_queuecommand_lck(struct scsi_cmnd *SCpnt,
data->CurrentSC = SCpnt; data->CurrentSC = SCpnt;
SCpnt->SCp.Status = CHECK_CONDITION; SCpnt->SCp.Status = SAM_STAT_CHECK_CONDITION;
SCpnt->SCp.Message = 0; SCpnt->SCp.Message = 0;
SCpnt->SCp.have_data_in = IO_UNKNOWN; SCpnt->SCp.have_data_in = IO_UNKNOWN;
SCpnt->SCp.sent_command = 0; SCpnt->SCp.sent_command = 0;

View File

@ -234,10 +234,8 @@ static int ps3rom_queuecommand_lck(struct scsi_cmnd *cmd,
} }
if (res) { if (res) {
memset(cmd->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE); scsi_build_sense(cmd, 0, ILLEGAL_REQUEST, 0, 0);
cmd->result = res; cmd->result = res;
cmd->sense_buffer[0] = 0x70;
cmd->sense_buffer[2] = ILLEGAL_REQUEST;
priv->curr_cmd = NULL; priv->curr_cmd = NULL;
cmd->scsi_done(cmd); cmd->scsi_done(cmd);
} }
@ -319,8 +317,7 @@ static irqreturn_t ps3rom_interrupt(int irq, void *data)
goto done; goto done;
} }
scsi_build_sense_buffer(0, cmd->sense_buffer, sense_key, asc, ascq); scsi_build_sense(cmd, 0, sense_key, asc, ascq);
cmd->result = SAM_STAT_CHECK_CONDITION;
done: done:
priv->curr_cmd = NULL; priv->curr_cmd = NULL;

View File

@ -2694,31 +2694,22 @@ qla2x00_handle_dif_error(srb_t *sp, struct sts_entry_24xx *sts24)
/* check guard */ /* check guard */
if (e_guard != a_guard) { if (e_guard != a_guard) {
scsi_build_sense_buffer(1, cmd->sense_buffer, ILLEGAL_REQUEST, scsi_build_sense(cmd, 1, ILLEGAL_REQUEST, 0x10, 0x1);
0x10, 0x1);
set_driver_byte(cmd, DRIVER_SENSE);
set_host_byte(cmd, DID_ABORT); set_host_byte(cmd, DID_ABORT);
cmd->result |= SAM_STAT_CHECK_CONDITION;
return 1; return 1;
} }
/* check ref tag */ /* check ref tag */
if (e_ref_tag != a_ref_tag) { if (e_ref_tag != a_ref_tag) {
scsi_build_sense_buffer(1, cmd->sense_buffer, ILLEGAL_REQUEST, scsi_build_sense(cmd, 1, ILLEGAL_REQUEST, 0x10, 0x3);
0x10, 0x3);
set_driver_byte(cmd, DRIVER_SENSE);
set_host_byte(cmd, DID_ABORT); set_host_byte(cmd, DID_ABORT);
cmd->result |= SAM_STAT_CHECK_CONDITION;
return 1; return 1;
} }
/* check appl tag */ /* check appl tag */
if (e_app_tag != a_app_tag) { if (e_app_tag != a_app_tag) {
scsi_build_sense_buffer(1, cmd->sense_buffer, ILLEGAL_REQUEST, scsi_build_sense(cmd, 1, ILLEGAL_REQUEST, 0x10, 0x2);
0x10, 0x2);
set_driver_byte(cmd, DRIVER_SENSE);
set_host_byte(cmd, DID_ABORT); set_host_byte(cmd, DID_ABORT);
cmd->result |= SAM_STAT_CHECK_CONDITION;
return 1; return 1;
} }

View File

@ -4,9 +4,9 @@
Use at your own risk. Support Tort Reform so you won't have to read all Use at your own risk. Support Tort Reform so you won't have to read all
these silly disclaimers. these silly disclaimers.
Copyright 1994, Tom Zerucha. Copyright 1994, Tom Zerucha.
tz@execpc.com tz@execpc.com
Additional Code, and much appreciated help by Additional Code, and much appreciated help by
Michael A. Griffith Michael A. Griffith
grif@cs.ucr.edu grif@cs.ucr.edu
@ -22,12 +22,12 @@
Functions as standalone, loadable, and PCMCIA driver, the latter from Functions as standalone, loadable, and PCMCIA driver, the latter from
Dave Hinds' PCMCIA package. Dave Hinds' PCMCIA package.
Cleaned up 26/10/2002 by Alan Cox <alan@lxorguk.ukuu.org.uk> as part of the 2.5 Cleaned up 26/10/2002 by Alan Cox <alan@lxorguk.ukuu.org.uk> as part of the 2.5
SCSI driver cleanup and audit. This driver still needs work on the SCSI driver cleanup and audit. This driver still needs work on the
following following
- Non terminating hardware waits - Non terminating hardware waits
- Some layering violations with its pcmcia stub - Some layering violations with its pcmcia stub
Redistributable under terms of the GNU General Public License Redistributable under terms of the GNU General Public License
@ -92,8 +92,9 @@ static void ql_zap(struct qlogicfas408_priv *priv)
/* /*
* Do a pseudo-dma tranfer * Do a pseudo-dma tranfer
*/ */
static int ql_pdma(struct qlogicfas408_priv *priv, int phase, char *request, int reqlen) static int ql_pdma(struct qlogicfas408_priv *priv, int phase, char *request,
int reqlen)
{ {
int j; int j;
int qbase = priv->qbase; int qbase = priv->qbase;
@ -108,7 +109,7 @@ static int ql_pdma(struct qlogicfas408_priv *priv, int phase, char *request, int
request += 128; request += 128;
} }
while (reqlen >= 84 && !(j & 0xc0)) /* 2/3 */ while (reqlen >= 84 && !(j & 0xc0)) /* 2/3 */
if ((j = inb(qbase + 8)) & 4) if ((j = inb(qbase + 8)) & 4)
{ {
insl(qbase + 4, request, 21); insl(qbase + 4, request, 21);
reqlen -= 84; reqlen -= 84;
@ -123,11 +124,11 @@ static int ql_pdma(struct qlogicfas408_priv *priv, int phase, char *request, int
/* until both empty and int (or until reclen is 0) */ /* until both empty and int (or until reclen is 0) */
rtrc(7) rtrc(7)
j = 0; j = 0;
while (reqlen && !((j & 0x10) && (j & 0xc0))) while (reqlen && !((j & 0x10) && (j & 0xc0)))
{ {
/* while bytes to receive and not empty */ /* while bytes to receive and not empty */
j &= 0xc0; j &= 0xc0;
while (reqlen && !((j = inb(qbase + 8)) & 0x10)) while (reqlen && !((j = inb(qbase + 8)) & 0x10))
{ {
*request++ = inb(qbase + 4); *request++ = inb(qbase + 4);
reqlen--; reqlen--;
@ -161,7 +162,7 @@ static int ql_pdma(struct qlogicfas408_priv *priv, int phase, char *request, int
j = 0; j = 0;
while (reqlen && !((j & 2) && (j & 0xc0))) { while (reqlen && !((j & 2) && (j & 0xc0))) {
/* while bytes to send and not full */ /* while bytes to send and not full */
while (reqlen && !((j = inb(qbase + 8)) & 2)) while (reqlen && !((j = inb(qbase + 8)) & 2))
{ {
outb(*request++, qbase + 4); outb(*request++, qbase + 4);
reqlen--; reqlen--;
@ -175,7 +176,7 @@ static int ql_pdma(struct qlogicfas408_priv *priv, int phase, char *request, int
} }
/* /*
* Wait for interrupt flag (polled - not real hardware interrupt) * Wait for interrupt flag (polled - not real hardware interrupt)
*/ */
static int ql_wai(struct qlogicfas408_priv *priv) static int ql_wai(struct qlogicfas408_priv *priv)
@ -205,14 +206,14 @@ static int ql_wai(struct qlogicfas408_priv *priv)
} }
/* /*
* Initiate scsi command - queueing handler * Initiate scsi command - queueing handler
* caller must hold host lock * caller must hold host lock
*/ */
static void ql_icmd(struct scsi_cmnd *cmd) static void ql_icmd(struct scsi_cmnd *cmd)
{ {
struct qlogicfas408_priv *priv = get_priv_by_cmd(cmd); struct qlogicfas408_priv *priv = get_priv_by_cmd(cmd);
int qbase = priv->qbase; int qbase = priv->qbase;
int int_type = priv->int_type; int int_type = priv->int_type;
unsigned int i; unsigned int i;
@ -253,14 +254,13 @@ static void ql_icmd(struct scsi_cmnd *cmd)
} }
/* /*
* Process scsi command - usually after interrupt * Process scsi command - usually after interrupt
*/ */
static unsigned int ql_pcmd(struct scsi_cmnd *cmd) static void ql_pcmd(struct scsi_cmnd *cmd)
{ {
unsigned int i, j; unsigned int i, j;
unsigned long k; unsigned long k;
unsigned int result; /* ultimate return result */
unsigned int status; /* scsi returned status */ unsigned int status; /* scsi returned status */
unsigned int message; /* scsi returned message */ unsigned int message; /* scsi returned message */
unsigned int phase; /* recorded scsi phase */ unsigned int phase; /* recorded scsi phase */
@ -274,13 +274,15 @@ static unsigned int ql_pcmd(struct scsi_cmnd *cmd)
j = inb(qbase + 6); j = inb(qbase + 6);
i = inb(qbase + 5); i = inb(qbase + 5);
if (i == 0x20) { if (i == 0x20) {
return (DID_NO_CONNECT << 16); set_host_byte(cmd, DID_NO_CONNECT);
return;
} }
i |= inb(qbase + 5); /* the 0x10 bit can be set after the 0x08 */ i |= inb(qbase + 5); /* the 0x10 bit can be set after the 0x08 */
if (i != 0x18) { if (i != 0x18) {
printk(KERN_ERR "Ql:Bad Interrupt status:%02x\n", i); printk(KERN_ERR "Ql:Bad Interrupt status:%02x\n", i);
ql_zap(priv); ql_zap(priv);
return (DID_BAD_INTR << 16); set_host_byte(cmd, DID_BAD_INTR);
return;
} }
j &= 7; /* j = inb( qbase + 7 ) >> 5; */ j &= 7; /* j = inb( qbase + 7 ) >> 5; */
@ -293,9 +295,10 @@ static unsigned int ql_pcmd(struct scsi_cmnd *cmd)
printk(KERN_ERR "Ql:Bad sequence for command %d, int %02X, cmdleft = %d\n", printk(KERN_ERR "Ql:Bad sequence for command %d, int %02X, cmdleft = %d\n",
j, i, inb(qbase + 7) & 0x1f); j, i, inb(qbase + 7) & 0x1f);
ql_zap(priv); ql_zap(priv);
return (DID_ERROR << 16); set_host_byte(cmd, DID_ERROR);
return;
} }
result = DID_OK;
if (inb(qbase + 7) & 0x1f) /* if some bytes in fifo */ if (inb(qbase + 7) & 0x1f) /* if some bytes in fifo */
outb(1, qbase + 3); /* clear fifo */ outb(1, qbase + 3); /* clear fifo */
/* note that request_bufflen is the total xfer size when sg is used */ /* note that request_bufflen is the total xfer size when sg is used */
@ -314,28 +317,31 @@ static unsigned int ql_pcmd(struct scsi_cmnd *cmd)
scsi_for_each_sg(cmd, sg, scsi_sg_count(cmd), i) { scsi_for_each_sg(cmd, sg, scsi_sg_count(cmd), i) {
if (priv->qabort) { if (priv->qabort) {
REG0; REG0;
return ((priv->qabort == 1 ? set_host_byte(cmd,
DID_ABORT : DID_RESET) << 16); priv->qabort == 1 ?
DID_ABORT : DID_RESET);
} }
buf = sg_virt(sg); buf = sg_virt(sg);
if (ql_pdma(priv, phase, buf, sg->length)) if (ql_pdma(priv, phase, buf, sg->length))
break; break;
} }
REG0; REG0;
rtrc(2) rtrc(2);
/* /*
* Wait for irq (split into second state of irq handler * Wait for irq (split into second state of irq handler
* if this can take time) * if this can take time)
*/ */
if ((k = ql_wai(priv))) if ((k = ql_wai(priv))) {
return (k << 16); set_host_byte(cmd, k);
return;
}
k = inb(qbase + 5); /* should be 0x10, bus service */ k = inb(qbase + 5); /* should be 0x10, bus service */
} }
/* /*
* Enter Status (and Message In) Phase * Enter Status (and Message In) Phase
*/ */
k = jiffies + WATCHDOG; k = jiffies + WATCHDOG;
while (time_before(jiffies, k) && !priv->qabort && while (time_before(jiffies, k) && !priv->qabort &&
@ -344,57 +350,72 @@ static unsigned int ql_pcmd(struct scsi_cmnd *cmd)
if (time_after_eq(jiffies, k)) { if (time_after_eq(jiffies, k)) {
ql_zap(priv); ql_zap(priv);
return (DID_TIME_OUT << 16); set_host_byte(cmd, DID_TIME_OUT);
return;
} }
/* FIXME: timeout ?? */ /* FIXME: timeout ?? */
while (inb(qbase + 5)) while (inb(qbase + 5))
cpu_relax(); /* clear pending ints */ cpu_relax(); /* clear pending ints */
if (priv->qabort) if (priv->qabort) {
return ((priv->qabort == 1 ? DID_ABORT : DID_RESET) << 16); set_host_byte(cmd,
priv->qabort == 1 ? DID_ABORT : DID_RESET);
return;
}
outb(0x11, qbase + 3); /* get status and message */ outb(0x11, qbase + 3); /* get status and message */
if ((k = ql_wai(priv))) if ((k = ql_wai(priv))) {
return (k << 16); set_host_byte(cmd, k);
return;
}
i = inb(qbase + 5); /* get chip irq stat */ i = inb(qbase + 5); /* get chip irq stat */
j = inb(qbase + 7) & 0x1f; /* and bytes rec'd */ j = inb(qbase + 7) & 0x1f; /* and bytes rec'd */
status = inb(qbase + 2); status = inb(qbase + 2);
message = inb(qbase + 2); message = inb(qbase + 2);
/* /*
* Should get function complete int if Status and message, else * Should get function complete int if Status and message, else
* bus serv if only status * bus serv if only status
*/ */
if (!((i == 8 && j == 2) || (i == 0x10 && j == 1))) { if (!((i == 8 && j == 2) || (i == 0x10 && j == 1))) {
printk(KERN_ERR "Ql:Error during status phase, int=%02X, %d bytes recd\n", i, j); printk(KERN_ERR "Ql:Error during status phase, int=%02X, %d bytes recd\n", i, j);
result = DID_ERROR; set_host_byte(cmd, DID_ERROR);
} }
outb(0x12, qbase + 3); /* done, disconnect */ outb(0x12, qbase + 3); /* done, disconnect */
rtrc(1) rtrc(1);
if ((k = ql_wai(priv))) if ((k = ql_wai(priv))) {
return (k << 16); set_host_byte(cmd, k);
return;
}
/* /*
* Should get bus service interrupt and disconnect interrupt * Should get bus service interrupt and disconnect interrupt
*/ */
i = inb(qbase + 5); /* should be bus service */ i = inb(qbase + 5); /* should be bus service */
while (!priv->qabort && ((i & 0x20) != 0x20)) { while (!priv->qabort && ((i & 0x20) != 0x20)) {
barrier(); barrier();
cpu_relax(); cpu_relax();
i |= inb(qbase + 5); i |= inb(qbase + 5);
} }
rtrc(0) rtrc(0);
if (priv->qabort) if (priv->qabort) {
return ((priv->qabort == 1 ? DID_ABORT : DID_RESET) << 16); set_host_byte(cmd,
priv->qabort == 1 ? DID_ABORT : DID_RESET);
return (result << 16) | (message << 8) | (status & STATUS_MASK); return;
}
set_host_byte(cmd, DID_OK);
if (message != COMMAND_COMPLETE)
scsi_msg_to_host_byte(cmd, message);
set_status_byte(cmd, status);
return;
} }
/* /*
* Interrupt handler * Interrupt handler
*/ */
static void ql_ihandl(void *dev_id) static void ql_ihandl(void *dev_id)
@ -415,11 +436,11 @@ static void ql_ihandl(void *dev_id)
return; return;
} }
icmd = priv->qlcmd; icmd = priv->qlcmd;
icmd->result = ql_pcmd(icmd); ql_pcmd(icmd);
priv->qlcmd = NULL; priv->qlcmd = NULL;
/* /*
* If result is CHECK CONDITION done calls qcommand to request * If result is CHECK CONDITION done calls qcommand to request
* sense * sense
*/ */
(icmd->scsi_done) (icmd); (icmd->scsi_done) (icmd);
} }
@ -443,8 +464,11 @@ static int qlogicfas408_queuecommand_lck(struct scsi_cmnd *cmd,
void (*done) (struct scsi_cmnd *)) void (*done) (struct scsi_cmnd *))
{ {
struct qlogicfas408_priv *priv = get_priv_by_cmd(cmd); struct qlogicfas408_priv *priv = get_priv_by_cmd(cmd);
set_host_byte(cmd, DID_OK);
set_status_byte(cmd, SAM_STAT_GOOD);
if (scmd_id(cmd) == priv->qinitid) { if (scmd_id(cmd) == priv->qinitid) {
cmd->result = DID_BAD_TARGET << 16; set_host_byte(cmd, DID_BAD_TARGET);
done(cmd); done(cmd);
return 0; return 0;
} }
@ -461,8 +485,8 @@ static int qlogicfas408_queuecommand_lck(struct scsi_cmnd *cmd,
DEF_SCSI_QCMD(qlogicfas408_queuecommand) DEF_SCSI_QCMD(qlogicfas408_queuecommand)
/* /*
* Return bios parameters * Return bios parameters
*/ */
int qlogicfas408_biosparam(struct scsi_device *disk, struct block_device *dev, int qlogicfas408_biosparam(struct scsi_device *disk, struct block_device *dev,
@ -487,7 +511,7 @@ int qlogicfas408_biosparam(struct scsi_device *disk, struct block_device *dev,
/* /*
* Abort a command in progress * Abort a command in progress
*/ */
int qlogicfas408_abort(struct scsi_cmnd *cmd) int qlogicfas408_abort(struct scsi_cmnd *cmd)
{ {
struct qlogicfas408_priv *priv = get_priv_by_cmd(cmd); struct qlogicfas408_priv *priv = get_priv_by_cmd(cmd);
@ -566,9 +590,9 @@ void qlogicfas408_setup(int qbase, int id, int int_type)
int qlogicfas408_detect(int qbase, int int_type) int qlogicfas408_detect(int qbase, int int_type)
{ {
REG1; REG1;
return (((inb(qbase + 0xe) ^ inb(qbase + 0xe)) == 7) && return (((inb(qbase + 0xe) ^ inb(qbase + 0xe)) == 7) &&
((inb(qbase + 0xe) ^ inb(qbase + 0xe)) == 7)); ((inb(qbase + 0xe) ^ inb(qbase + 0xe)) == 7));
} }
/* /*

View File

@ -144,7 +144,7 @@ void scsi_log_completion(struct scsi_cmnd *cmd, int disposition)
(level > 1)) { (level > 1)) {
scsi_print_result(cmd, "Done", disposition); scsi_print_result(cmd, "Done", disposition);
scsi_print_command(cmd); scsi_print_command(cmd);
if (status_byte(cmd->result) == CHECK_CONDITION) if (scsi_status_is_check_condition(cmd->result))
scsi_print_sense(cmd); scsi_print_sense(cmd);
if (level > 3) if (level > 3)
scmd_printk(KERN_INFO, cmd, scmd_printk(KERN_INFO, cmd,
@ -185,13 +185,6 @@ void scsi_finish_command(struct scsi_cmnd *cmd)
if (atomic_read(&sdev->device_blocked)) if (atomic_read(&sdev->device_blocked))
atomic_set(&sdev->device_blocked, 0); atomic_set(&sdev->device_blocked, 0);
/*
* If we have valid sense information, then some kind of recovery
* must have taken place. Make a note of this.
*/
if (SCSI_SENSE_VALID(cmd))
cmd->result |= (DRIVER_SENSE << 24);
SCSI_LOG_MLCOMPLETE(4, sdev_printk(KERN_INFO, sdev, SCSI_LOG_MLCOMPLETE(4, sdev_printk(KERN_INFO, sdev,
"Notifying upper driver of completion " "Notifying upper driver of completion "
"(result %x)\n", cmd->result)); "(result %x)\n", cmd->result));
@ -508,6 +501,8 @@ int scsi_report_opcode(struct scsi_device *sdev, unsigned char *buffer,
result = scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buffer, len, result = scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buffer, len,
&sshdr, 30 * HZ, 3, NULL); &sshdr, 30 * HZ, 3, NULL);
if (result < 0)
return result;
if (result && scsi_sense_valid(&sshdr) && if (result && scsi_sense_valid(&sshdr) &&
sshdr.sense_key == ILLEGAL_REQUEST && sshdr.sense_key == ILLEGAL_REQUEST &&
(sshdr.asc == 0x20 || sshdr.asc == 0x24) && sshdr.ascq == 0x00) (sshdr.asc == 0x20 || sshdr.asc == 0x24) && sshdr.ascq == 0x00)

View File

@ -851,10 +851,10 @@ static struct device_driver sdebug_driverfs_driver = {
}; };
static const int check_condition_result = static const int check_condition_result =
(DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION; SAM_STAT_CHECK_CONDITION;
static const int illegal_condition_result = static const int illegal_condition_result =
(DRIVER_SENSE << 24) | (DID_ABORT << 16) | SAM_STAT_CHECK_CONDITION; (DID_ABORT << 16) | SAM_STAT_CHECK_CONDITION;
static const int device_qfull_result = static const int device_qfull_result =
(DID_OK << 16) | SAM_STAT_TASK_SET_FULL; (DID_OK << 16) | SAM_STAT_TASK_SET_FULL;
@ -931,7 +931,7 @@ static void mk_sense_invalid_fld(struct scsi_cmnd *scp,
} }
asc = c_d ? INVALID_FIELD_IN_CDB : INVALID_FIELD_IN_PARAM_LIST; asc = c_d ? INVALID_FIELD_IN_CDB : INVALID_FIELD_IN_PARAM_LIST;
memset(sbuff, 0, SCSI_SENSE_BUFFERSIZE); memset(sbuff, 0, SCSI_SENSE_BUFFERSIZE);
scsi_build_sense_buffer(sdebug_dsense, sbuff, ILLEGAL_REQUEST, asc, 0); scsi_build_sense(scp, sdebug_dsense, ILLEGAL_REQUEST, asc, 0);
memset(sks, 0, sizeof(sks)); memset(sks, 0, sizeof(sks));
sks[0] = 0x80; sks[0] = 0x80;
if (c_d) if (c_d)
@ -957,17 +957,14 @@ static void mk_sense_invalid_fld(struct scsi_cmnd *scp,
static void mk_sense_buffer(struct scsi_cmnd *scp, int key, int asc, int asq) static void mk_sense_buffer(struct scsi_cmnd *scp, int key, int asc, int asq)
{ {
unsigned char *sbuff; if (!scp->sense_buffer) {
sbuff = scp->sense_buffer;
if (!sbuff) {
sdev_printk(KERN_ERR, scp->device, sdev_printk(KERN_ERR, scp->device,
"%s: sense_buffer is NULL\n", __func__); "%s: sense_buffer is NULL\n", __func__);
return; return;
} }
memset(sbuff, 0, SCSI_SENSE_BUFFERSIZE); memset(scp->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
scsi_build_sense_buffer(sdebug_dsense, sbuff, key, asc, asq); scsi_build_sense(scp, sdebug_dsense, key, asc, asq);
if (sdebug_verbose) if (sdebug_verbose)
sdev_printk(KERN_INFO, scp->device, sdev_printk(KERN_INFO, scp->device,

View File

@ -741,42 +741,36 @@ static enum scsi_disposition scsi_eh_completed_normally(struct scsi_cmnd *scmd)
if (host_byte(scmd->result) != DID_OK) if (host_byte(scmd->result) != DID_OK)
return FAILED; return FAILED;
/*
* next, check the message byte.
*/
if (msg_byte(scmd->result) != COMMAND_COMPLETE)
return FAILED;
/* /*
* now, check the status byte to see if this indicates * now, check the status byte to see if this indicates
* anything special. * anything special.
*/ */
switch (status_byte(scmd->result)) { switch (get_status_byte(scmd)) {
case GOOD: case SAM_STAT_GOOD:
scsi_handle_queue_ramp_up(scmd->device); scsi_handle_queue_ramp_up(scmd->device);
fallthrough; fallthrough;
case COMMAND_TERMINATED: case SAM_STAT_COMMAND_TERMINATED:
return SUCCESS; return SUCCESS;
case CHECK_CONDITION: case SAM_STAT_CHECK_CONDITION:
return scsi_check_sense(scmd); return scsi_check_sense(scmd);
case CONDITION_GOOD: case SAM_STAT_CONDITION_MET:
case INTERMEDIATE_GOOD: case SAM_STAT_INTERMEDIATE:
case INTERMEDIATE_C_GOOD: case SAM_STAT_INTERMEDIATE_CONDITION_MET:
/* /*
* who knows? FIXME(eric) * who knows? FIXME(eric)
*/ */
return SUCCESS; return SUCCESS;
case RESERVATION_CONFLICT: case SAM_STAT_RESERVATION_CONFLICT:
if (scmd->cmnd[0] == TEST_UNIT_READY) if (scmd->cmnd[0] == TEST_UNIT_READY)
/* it is a success, we probed the device and /* it is a success, we probed the device and
* found it */ * found it */
return SUCCESS; return SUCCESS;
/* otherwise, we failed to send the command */ /* otherwise, we failed to send the command */
return FAILED; return FAILED;
case QUEUE_FULL: case SAM_STAT_TASK_SET_FULL:
scsi_handle_queue_full(scmd->device); scsi_handle_queue_full(scmd->device);
fallthrough; fallthrough;
case BUSY: case SAM_STAT_BUSY:
return NEEDS_RETRY; return NEEDS_RETRY;
default: default:
return FAILED; return FAILED;
@ -1258,7 +1252,7 @@ int scsi_eh_get_sense(struct list_head *work_q,
current->comm)); current->comm));
break; break;
} }
if (status_byte(scmd->result) != CHECK_CONDITION) if (!scsi_status_is_check_condition(scmd->result))
/* /*
* don't request sense if there's no check condition * don't request sense if there's no check condition
* status because the error we're processing isn't one * status because the error we're processing isn't one
@ -1766,15 +1760,14 @@ int scsi_noretry_cmd(struct scsi_cmnd *scmd)
case DID_PARITY: case DID_PARITY:
return (scmd->request->cmd_flags & REQ_FAILFAST_DEV); return (scmd->request->cmd_flags & REQ_FAILFAST_DEV);
case DID_ERROR: case DID_ERROR:
if (msg_byte(scmd->result) == COMMAND_COMPLETE && if (get_status_byte(scmd) == SAM_STAT_RESERVATION_CONFLICT)
status_byte(scmd->result) == RESERVATION_CONFLICT)
return 0; return 0;
fallthrough; fallthrough;
case DID_SOFT_ERROR: case DID_SOFT_ERROR:
return (scmd->request->cmd_flags & REQ_FAILFAST_DRIVER); return (scmd->request->cmd_flags & REQ_FAILFAST_DRIVER);
} }
if (status_byte(scmd->result) != CHECK_CONDITION) if (!scsi_status_is_check_condition(scmd->result))
return 0; return 0;
check_type: check_type:
@ -1883,8 +1876,7 @@ enum scsi_disposition scsi_decide_disposition(struct scsi_cmnd *scmd)
*/ */
return SUCCESS; return SUCCESS;
case DID_ERROR: case DID_ERROR:
if (msg_byte(scmd->result) == COMMAND_COMPLETE && if (get_status_byte(scmd) == SAM_STAT_RESERVATION_CONFLICT)
status_byte(scmd->result) == RESERVATION_CONFLICT)
/* /*
* execute reservation conflict processing code * execute reservation conflict processing code
* lower down * lower down
@ -1912,24 +1904,18 @@ enum scsi_disposition scsi_decide_disposition(struct scsi_cmnd *scmd)
return FAILED; return FAILED;
} }
/*
* next, check the message byte.
*/
if (msg_byte(scmd->result) != COMMAND_COMPLETE)
return FAILED;
/* /*
* check the status byte to see if this indicates anything special. * check the status byte to see if this indicates anything special.
*/ */
switch (status_byte(scmd->result)) { switch (get_status_byte(scmd)) {
case QUEUE_FULL: case SAM_STAT_TASK_SET_FULL:
scsi_handle_queue_full(scmd->device); scsi_handle_queue_full(scmd->device);
/* /*
* the case of trying to send too many commands to a * the case of trying to send too many commands to a
* tagged queueing device. * tagged queueing device.
*/ */
fallthrough; fallthrough;
case BUSY: case SAM_STAT_BUSY:
/* /*
* device can't talk to us at the moment. Should only * device can't talk to us at the moment. Should only
* occur (SAM-3) when the task queue is empty, so will cause * occur (SAM-3) when the task queue is empty, so will cause
@ -1937,16 +1923,16 @@ enum scsi_disposition scsi_decide_disposition(struct scsi_cmnd *scmd)
* device. * device.
*/ */
return ADD_TO_MLQUEUE; return ADD_TO_MLQUEUE;
case GOOD: case SAM_STAT_GOOD:
if (scmd->cmnd[0] == REPORT_LUNS) if (scmd->cmnd[0] == REPORT_LUNS)
scmd->device->sdev_target->expecting_lun_change = 0; scmd->device->sdev_target->expecting_lun_change = 0;
scsi_handle_queue_ramp_up(scmd->device); scsi_handle_queue_ramp_up(scmd->device);
fallthrough; fallthrough;
case COMMAND_TERMINATED: case SAM_STAT_COMMAND_TERMINATED:
return SUCCESS; return SUCCESS;
case TASK_ABORTED: case SAM_STAT_TASK_ABORTED:
goto maybe_retry; goto maybe_retry;
case CHECK_CONDITION: case SAM_STAT_CHECK_CONDITION:
rtn = scsi_check_sense(scmd); rtn = scsi_check_sense(scmd);
if (rtn == NEEDS_RETRY) if (rtn == NEEDS_RETRY)
goto maybe_retry; goto maybe_retry;
@ -1955,16 +1941,16 @@ enum scsi_disposition scsi_decide_disposition(struct scsi_cmnd *scmd)
* to collect the sense and redo the decide * to collect the sense and redo the decide
* disposition */ * disposition */
return rtn; return rtn;
case CONDITION_GOOD: case SAM_STAT_CONDITION_MET:
case INTERMEDIATE_GOOD: case SAM_STAT_INTERMEDIATE:
case INTERMEDIATE_C_GOOD: case SAM_STAT_INTERMEDIATE_CONDITION_MET:
case ACA_ACTIVE: case SAM_STAT_ACA_ACTIVE:
/* /*
* who knows? FIXME(eric) * who knows? FIXME(eric)
*/ */
return SUCCESS; return SUCCESS;
case RESERVATION_CONFLICT: case SAM_STAT_RESERVATION_CONFLICT:
sdev_printk(KERN_INFO, scmd->device, sdev_printk(KERN_INFO, scmd->device,
"reservation conflict\n"); "reservation conflict\n");
set_host_byte(scmd, DID_NEXUS_FAILURE); set_host_byte(scmd, DID_NEXUS_FAILURE);
@ -2137,10 +2123,10 @@ void scsi_eh_flush_done_q(struct list_head *done_q)
/* /*
* If just we got sense for the device (called * If just we got sense for the device (called
* scsi_eh_get_sense), scmd->result is already * scsi_eh_get_sense), scmd->result is already
* set, do not set DRIVER_TIMEOUT. * set, do not set DID_TIME_OUT.
*/ */
if (!scmd->result) if (!scmd->result)
scmd->result |= (DRIVER_TIMEOUT << 24); scmd->result |= (DID_TIME_OUT << 16);
SCSI_LOG_ERROR_RECOVERY(3, SCSI_LOG_ERROR_RECOVERY(3,
scmd_printk(KERN_INFO, scmd, scmd_printk(KERN_INFO, scmd,
"%s: flush finish cmd\n", "%s: flush finish cmd\n",

View File

@ -101,8 +101,9 @@ static int ioctl_internal_command(struct scsi_device *sdev, char *cmd,
SCSI_LOG_IOCTL(2, sdev_printk(KERN_INFO, sdev, SCSI_LOG_IOCTL(2, sdev_printk(KERN_INFO, sdev,
"Ioctl returned 0x%x\n", result)); "Ioctl returned 0x%x\n", result));
if (driver_byte(result) == DRIVER_SENSE && if (result < 0)
scsi_sense_valid(&sshdr)) { goto out;
if (scsi_sense_valid(&sshdr)) {
switch (sshdr.sense_key) { switch (sshdr.sense_key) {
case ILLEGAL_REQUEST: case ILLEGAL_REQUEST:
if (cmd[0] == ALLOW_MEDIUM_REMOVAL) if (cmd[0] == ALLOW_MEDIUM_REMOVAL)
@ -133,7 +134,7 @@ static int ioctl_internal_command(struct scsi_device *sdev, char *cmd,
break; break;
} }
} }
out:
SCSI_LOG_IOCTL(2, sdev_printk(KERN_INFO, sdev, SCSI_LOG_IOCTL(2, sdev_printk(KERN_INFO, sdev,
"IOCTL Releasing command\n")); "IOCTL Releasing command\n"));
return result; return result;

View File

@ -211,20 +211,23 @@ int __scsi_execute(struct scsi_device *sdev, const unsigned char *cmd,
{ {
struct request *req; struct request *req;
struct scsi_request *rq; struct scsi_request *rq;
int ret = DRIVER_ERROR << 24; int ret;
req = blk_get_request(sdev->request_queue, req = blk_get_request(sdev->request_queue,
data_direction == DMA_TO_DEVICE ? data_direction == DMA_TO_DEVICE ?
REQ_OP_SCSI_OUT : REQ_OP_SCSI_IN, REQ_OP_SCSI_OUT : REQ_OP_SCSI_IN,
rq_flags & RQF_PM ? BLK_MQ_REQ_PM : 0); rq_flags & RQF_PM ? BLK_MQ_REQ_PM : 0);
if (IS_ERR(req)) if (IS_ERR(req))
return ret; return PTR_ERR(req);
rq = scsi_req(req); rq = scsi_req(req);
if (bufflen && blk_rq_map_kern(sdev->request_queue, req, if (bufflen) {
buffer, bufflen, GFP_NOIO)) ret = blk_rq_map_kern(sdev->request_queue, req,
goto out; buffer, bufflen, GFP_NOIO);
if (ret)
goto out;
}
rq->cmd_len = COMMAND_SIZE(cmd[0]); rq->cmd_len = COMMAND_SIZE(cmd[0]);
memcpy(rq->cmd, cmd, rq->cmd_len); memcpy(rq->cmd, cmd, rq->cmd_len);
rq->retries = retries; rq->retries = retries;
@ -588,12 +591,7 @@ static blk_status_t scsi_result_to_blk_status(struct scsi_cmnd *cmd, int result)
{ {
switch (host_byte(result)) { switch (host_byte(result)) {
case DID_OK: case DID_OK:
/* if (scsi_status_is_good(result))
* Also check the other bytes than the status byte in result
* to handle the case when a SCSI LLD sets result to
* DRIVER_SENSE << 24 without setting SAM_STAT_CHECK_CONDITION.
*/
if (scsi_status_is_good(result) && (result & ~0xff) == 0)
return BLK_STS_OK; return BLK_STS_OK;
return BLK_STS_IOERR; return BLK_STS_IOERR;
case DID_TRANSPORT_FAILFAST: case DID_TRANSPORT_FAILFAST:
@ -787,7 +785,7 @@ static void scsi_io_completion_action(struct scsi_cmnd *cmd, int result)
*/ */
if (!level && __ratelimit(&_rs)) { if (!level && __ratelimit(&_rs)) {
scsi_print_result(cmd, NULL, FAILED); scsi_print_result(cmd, NULL, FAILED);
if (driver_byte(result) == DRIVER_SENSE) if (sense_valid)
scsi_print_sense(cmd); scsi_print_sense(cmd);
scsi_print_command(cmd); scsi_print_command(cmd);
} }
@ -875,7 +873,7 @@ static int scsi_io_completion_nz_result(struct scsi_cmnd *cmd, int result,
* if it can't fit). Treat SAM_STAT_CONDITION_MET and the related * if it can't fit). Treat SAM_STAT_CONDITION_MET and the related
* intermediate statuses (both obsolete in SAM-4) as good. * intermediate statuses (both obsolete in SAM-4) as good.
*/ */
if (status_byte(result) && scsi_status_is_good(result)) { if ((result & 0xff) && scsi_status_is_good(result)) {
result = 0; result = 0;
*blk_statp = BLK_STS_OK; *blk_statp = BLK_STS_OK;
} }
@ -2093,9 +2091,7 @@ EXPORT_SYMBOL_GPL(scsi_mode_select);
* @sshdr: place to put sense data (or NULL if no sense to be collected). * @sshdr: place to put sense data (or NULL if no sense to be collected).
* must be SCSI_SENSE_BUFFERSIZE big. * must be SCSI_SENSE_BUFFERSIZE big.
* *
* Returns zero if unsuccessful, or the header offset (either 4 * Returns zero if successful, or a negative error number on failure
* or 8 depending on whether a six or ten byte command was
* issued) if successful.
*/ */
int int
scsi_mode_sense(struct scsi_device *sdev, int dbd, int modepage, scsi_mode_sense(struct scsi_device *sdev, int dbd, int modepage,
@ -2142,58 +2138,60 @@ scsi_mode_sense(struct scsi_device *sdev, int dbd, int modepage,
result = scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buffer, len, result = scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buffer, len,
sshdr, timeout, retries, NULL); sshdr, timeout, retries, NULL);
if (result < 0)
return result;
/* This code looks awful: what it's doing is making sure an /* This code looks awful: what it's doing is making sure an
* ILLEGAL REQUEST sense return identifies the actual command * ILLEGAL REQUEST sense return identifies the actual command
* byte as the problem. MODE_SENSE commands can return * byte as the problem. MODE_SENSE commands can return
* ILLEGAL REQUEST if the code page isn't supported */ * ILLEGAL REQUEST if the code page isn't supported */
if (use_10_for_ms && !scsi_status_is_good(result) && if (!scsi_status_is_good(result)) {
driver_byte(result) == DRIVER_SENSE) {
if (scsi_sense_valid(sshdr)) { if (scsi_sense_valid(sshdr)) {
if ((sshdr->sense_key == ILLEGAL_REQUEST) && if ((sshdr->sense_key == ILLEGAL_REQUEST) &&
(sshdr->asc == 0x20) && (sshdr->ascq == 0)) { (sshdr->asc == 0x20) && (sshdr->ascq == 0)) {
/* /*
* Invalid command operation code * Invalid command operation code
*/ */
sdev->use_10_for_ms = 0; if (use_10_for_ms) {
sdev->use_10_for_ms = 0;
goto retry;
}
}
if (scsi_status_is_check_condition(result) &&
sshdr->sense_key == UNIT_ATTENTION &&
retry_count) {
retry_count--;
goto retry; goto retry;
} }
} }
return -EIO;
} }
if (unlikely(buffer[0] == 0x86 && buffer[1] == 0x0b &&
if (scsi_status_is_good(result)) { (modepage == 6 || modepage == 8))) {
if (unlikely(buffer[0] == 0x86 && buffer[1] == 0x0b && /* Initio breakage? */
(modepage == 6 || modepage == 8))) { header_length = 0;
/* Initio breakage? */ data->length = 13;
header_length = 0; data->medium_type = 0;
data->length = 13; data->device_specific = 0;
data->medium_type = 0; data->longlba = 0;
data->device_specific = 0; data->block_descriptor_length = 0;
data->longlba = 0; } else if (use_10_for_ms) {
data->block_descriptor_length = 0; data->length = buffer[0]*256 + buffer[1] + 2;
} else if (use_10_for_ms) { data->medium_type = buffer[2];
data->length = buffer[0]*256 + buffer[1] + 2; data->device_specific = buffer[3];
data->medium_type = buffer[2]; data->longlba = buffer[4] & 0x01;
data->device_specific = buffer[3]; data->block_descriptor_length = buffer[6]*256
data->longlba = buffer[4] & 0x01; + buffer[7];
data->block_descriptor_length = buffer[6]*256 } else {
+ buffer[7]; data->length = buffer[0] + 1;
} else { data->medium_type = buffer[1];
data->length = buffer[0] + 1; data->device_specific = buffer[2];
data->medium_type = buffer[1]; data->block_descriptor_length = buffer[3];
data->device_specific = buffer[2];
data->block_descriptor_length = buffer[3];
}
data->header_length = header_length;
} else if ((status_byte(result) == CHECK_CONDITION) &&
scsi_sense_valid(sshdr) &&
sshdr->sense_key == UNIT_ATTENTION && retry_count) {
retry_count--;
goto retry;
} }
data->header_length = header_length;
return result; return 0;
} }
EXPORT_SYMBOL(scsi_mode_sense); EXPORT_SYMBOL(scsi_mode_sense);
@ -3218,3 +3216,20 @@ int scsi_vpd_tpg_id(struct scsi_device *sdev, int *rel_id)
return group_id; return group_id;
} }
EXPORT_SYMBOL(scsi_vpd_tpg_id); EXPORT_SYMBOL(scsi_vpd_tpg_id);
/**
* scsi_build_sense - build sense data for a command
* @scmd: scsi command for which the sense should be formatted
* @desc: Sense format (non-zero == descriptor format,
* 0 == fixed format)
* @key: Sense key
* @asc: Additional sense code
* @ascq: Additional sense code qualifier
*
**/
void scsi_build_sense(struct scsi_cmnd *scmd, int desc, u8 key, u8 asc, u8 ascq)
{
scsi_build_sense_buffer(desc, scmd->sense_buffer, key, asc, ascq);
scmd->result = SAM_STAT_CHECK_CONDITION;
}
EXPORT_SYMBOL_GPL(scsi_build_sense);

View File

@ -385,7 +385,6 @@ void scsi_print_result(const struct scsi_cmnd *cmd, const char *msg,
size_t off, logbuf_len; size_t off, logbuf_len;
const char *mlret_string = scsi_mlreturn_string(disposition); const char *mlret_string = scsi_mlreturn_string(disposition);
const char *hb_string = scsi_hostbyte_string(cmd->result); const char *hb_string = scsi_hostbyte_string(cmd->result);
const char *db_string = scsi_driverbyte_string(cmd->result);
unsigned long cmd_age = (jiffies - cmd->jiffies_at_alloc) / HZ; unsigned long cmd_age = (jiffies - cmd->jiffies_at_alloc) / HZ;
logbuf = scsi_log_reserve_buffer(&logbuf_len); logbuf = scsi_log_reserve_buffer(&logbuf_len);
@ -426,13 +425,8 @@ void scsi_print_result(const struct scsi_cmnd *cmd, const char *msg,
if (WARN_ON(off >= logbuf_len)) if (WARN_ON(off >= logbuf_len))
goto out_printk; goto out_printk;
if (db_string) off += scnprintf(logbuf + off, logbuf_len - off,
off += scnprintf(logbuf + off, logbuf_len - off, "driverbyte=DRIVER_OK ");
"driverbyte=%s ", db_string);
else
off += scnprintf(logbuf + off, logbuf_len - off,
"driverbyte=0x%02x ",
driver_byte(cmd->result));
off += scnprintf(logbuf + off, logbuf_len - off, off += scnprintf(logbuf + off, logbuf_len - off,
"cmd_age=%lus", cmd_age); "cmd_age=%lus", cmd_age);

View File

@ -616,14 +616,14 @@ static int scsi_probe_lun(struct scsi_device *sdev, unsigned char *inq_result,
"scsi scan: INQUIRY %s with code 0x%x\n", "scsi scan: INQUIRY %s with code 0x%x\n",
result ? "failed" : "successful", result)); result ? "failed" : "successful", result));
if (result) { if (result > 0) {
/* /*
* not-ready to ready transition [asc/ascq=0x28/0x0] * not-ready to ready transition [asc/ascq=0x28/0x0]
* or power-on, reset [asc/ascq=0x29/0x0], continue. * or power-on, reset [asc/ascq=0x29/0x0], continue.
* INQUIRY should not yield UNIT_ATTENTION * INQUIRY should not yield UNIT_ATTENTION
* but many buggy devices do so anyway. * but many buggy devices do so anyway.
*/ */
if (driver_byte(result) == DRIVER_SENSE && if (scsi_status_is_check_condition(result) &&
scsi_sense_valid(&sshdr)) { scsi_sense_valid(&sshdr)) {
if ((sshdr.sense_key == UNIT_ATTENTION) && if ((sshdr.sense_key == UNIT_ATTENTION) &&
((sshdr.asc == 0x28) || ((sshdr.asc == 0x28) ||
@ -631,7 +631,7 @@ static int scsi_probe_lun(struct scsi_device *sdev, unsigned char *inq_result,
(sshdr.ascq == 0)) (sshdr.ascq == 0))
continue; continue;
} }
} else { } else if (result == 0) {
/* /*
* if nothing was transferred, we try * if nothing was transferred, we try
* again. It's a workaround for some USB * again. It's a workaround for some USB

View File

@ -1229,16 +1229,15 @@ int sas_read_port_mode_page(struct scsi_device *sdev)
char *buffer = kzalloc(BUF_SIZE, GFP_KERNEL), *msdata; char *buffer = kzalloc(BUF_SIZE, GFP_KERNEL), *msdata;
struct sas_end_device *rdev = sas_sdev_to_rdev(sdev); struct sas_end_device *rdev = sas_sdev_to_rdev(sdev);
struct scsi_mode_data mode_data; struct scsi_mode_data mode_data;
int res, error; int error;
if (!buffer) if (!buffer)
return -ENOMEM; return -ENOMEM;
res = scsi_mode_sense(sdev, 1, 0x19, buffer, BUF_SIZE, 30*HZ, 3, error = scsi_mode_sense(sdev, 1, 0x19, buffer, BUF_SIZE, 30*HZ, 3,
&mode_data, NULL); &mode_data, NULL);
error = -EINVAL; if (error)
if (!scsi_status_is_good(res))
goto out; goto out;
msdata = buffer + mode_data.header_length + msdata = buffer + mode_data.header_length +

View File

@ -127,7 +127,7 @@ static int spi_execute(struct scsi_device *sdev, const void *cmd,
REQ_FAILFAST_TRANSPORT | REQ_FAILFAST_TRANSPORT |
REQ_FAILFAST_DRIVER, REQ_FAILFAST_DRIVER,
RQF_PM, NULL); RQF_PM, NULL);
if (driver_byte(result) != DRIVER_SENSE || if (result < 0 || !scsi_sense_valid(sshdr) ||
sshdr->sense_key != UNIT_ATTENTION) sshdr->sense_key != UNIT_ATTENTION)
break; break;
} }

View File

@ -1658,7 +1658,7 @@ static unsigned int sd_check_events(struct gendisk *disk, unsigned int clearing)
&sshdr); &sshdr);
/* failed to execute TUR, assume media not present */ /* failed to execute TUR, assume media not present */
if (host_byte(retval)) { if (retval < 0 || host_byte(retval)) {
set_media_not_present(sdkp); set_media_not_present(sdkp);
goto out; goto out;
} }
@ -1719,16 +1719,20 @@ static int sd_sync_cache(struct scsi_disk *sdkp, struct scsi_sense_hdr *sshdr)
if (res) { if (res) {
sd_print_result(sdkp, "Synchronize Cache(10) failed", res); sd_print_result(sdkp, "Synchronize Cache(10) failed", res);
if (driver_byte(res) == DRIVER_SENSE) if (res < 0)
return res;
if (scsi_status_is_check_condition(res) &&
scsi_sense_valid(sshdr)) {
sd_print_sense_hdr(sdkp, sshdr); sd_print_sense_hdr(sdkp, sshdr);
/* we need to evaluate the error return */ /* we need to evaluate the error return */
if (scsi_sense_valid(sshdr) && if (sshdr->asc == 0x3a || /* medium not present */
(sshdr->asc == 0x3a || /* medium not present */ sshdr->asc == 0x20 || /* invalid command */
sshdr->asc == 0x20 || /* invalid command */ (sshdr->asc == 0x74 && sshdr->ascq == 0x71)) /* drive is password locked */
(sshdr->asc == 0x74 && sshdr->ascq == 0x71))) /* drive is password locked */
/* this is no error here */ /* this is no error here */
return 0; return 0;
}
switch (host_byte(res)) { switch (host_byte(res)) {
/* ignore errors due to racing a disconnection */ /* ignore errors due to racing a disconnection */
@ -1825,7 +1829,7 @@ static int sd_pr_command(struct block_device *bdev, u8 sa,
result = scsi_execute_req(sdev, cmd, DMA_TO_DEVICE, &data, sizeof(data), result = scsi_execute_req(sdev, cmd, DMA_TO_DEVICE, &data, sizeof(data),
&sshdr, SD_TIMEOUT, sdkp->max_retries, NULL); &sshdr, SD_TIMEOUT, sdkp->max_retries, NULL);
if (driver_byte(result) == DRIVER_SENSE && if (scsi_status_is_check_condition(result) &&
scsi_sense_valid(&sshdr)) { scsi_sense_valid(&sshdr)) {
sdev_printk(KERN_INFO, sdev, "PR command failed: %d\n", result); sdev_printk(KERN_INFO, sdev, "PR command failed: %d\n", result);
scsi_print_sense_hdr(sdev, NULL, &sshdr); scsi_print_sense_hdr(sdev, NULL, &sshdr);
@ -2069,7 +2073,7 @@ static int sd_done(struct scsi_cmnd *SCpnt)
} }
sdkp->medium_access_timed_out = 0; sdkp->medium_access_timed_out = 0;
if (driver_byte(result) != DRIVER_SENSE && if (!scsi_status_is_check_condition(result) &&
(!sense_valid || sense_deferred)) (!sense_valid || sense_deferred))
goto out; goto out;
@ -2172,12 +2176,12 @@ sd_spinup_disk(struct scsi_disk *sdkp)
if (the_result) if (the_result)
sense_valid = scsi_sense_valid(&sshdr); sense_valid = scsi_sense_valid(&sshdr);
retries++; retries++;
} while (retries < 3 && } while (retries < 3 &&
(!scsi_status_is_good(the_result) || (!scsi_status_is_good(the_result) ||
((driver_byte(the_result) == DRIVER_SENSE) && (scsi_status_is_check_condition(the_result) &&
sense_valid && sshdr.sense_key == UNIT_ATTENTION))); sense_valid && sshdr.sense_key == UNIT_ATTENTION)));
if (driver_byte(the_result) != DRIVER_SENSE) { if (!scsi_status_is_check_condition(the_result)) {
/* no sense, TUR either succeeded or failed /* no sense, TUR either succeeded or failed
* with a status error */ * with a status error */
if(!spintime && !scsi_status_is_good(the_result)) { if(!spintime && !scsi_status_is_good(the_result)) {
@ -2305,7 +2309,7 @@ static void read_capacity_error(struct scsi_disk *sdkp, struct scsi_device *sdp,
struct scsi_sense_hdr *sshdr, int sense_valid, struct scsi_sense_hdr *sshdr, int sense_valid,
int the_result) int the_result)
{ {
if (driver_byte(the_result) == DRIVER_SENSE) if (sense_valid)
sd_print_sense_hdr(sdkp, sshdr); sd_print_sense_hdr(sdkp, sshdr);
else else
sd_printk(KERN_NOTICE, sdkp, "Sense not available.\n"); sd_printk(KERN_NOTICE, sdkp, "Sense not available.\n");
@ -2362,7 +2366,7 @@ static int read_capacity_16(struct scsi_disk *sdkp, struct scsi_device *sdp,
if (media_not_present(sdkp, &sshdr)) if (media_not_present(sdkp, &sshdr))
return -ENODEV; return -ENODEV;
if (the_result) { if (the_result > 0) {
sense_valid = scsi_sense_valid(&sshdr); sense_valid = scsi_sense_valid(&sshdr);
if (sense_valid && if (sense_valid &&
sshdr.sense_key == ILLEGAL_REQUEST && sshdr.sense_key == ILLEGAL_REQUEST &&
@ -2447,7 +2451,7 @@ static int read_capacity_10(struct scsi_disk *sdkp, struct scsi_device *sdp,
if (media_not_present(sdkp, &sshdr)) if (media_not_present(sdkp, &sshdr))
return -ENODEV; return -ENODEV;
if (the_result) { if (the_result > 0) {
sense_valid = scsi_sense_valid(&sshdr); sense_valid = scsi_sense_valid(&sshdr);
if (sense_valid && if (sense_valid &&
sshdr.sense_key == UNIT_ATTENTION && sshdr.sense_key == UNIT_ATTENTION &&
@ -2670,18 +2674,18 @@ sd_read_write_protect_flag(struct scsi_disk *sdkp, unsigned char *buffer)
* 5: Illegal Request, Sense Code 24: Invalid field in * 5: Illegal Request, Sense Code 24: Invalid field in
* CDB. * CDB.
*/ */
if (!scsi_status_is_good(res)) if (res < 0)
res = sd_do_mode_sense(sdkp, 0, 0, buffer, 4, &data, NULL); res = sd_do_mode_sense(sdkp, 0, 0, buffer, 4, &data, NULL);
/* /*
* Third attempt: ask 255 bytes, as we did earlier. * Third attempt: ask 255 bytes, as we did earlier.
*/ */
if (!scsi_status_is_good(res)) if (res < 0)
res = sd_do_mode_sense(sdkp, 0, 0x3F, buffer, 255, res = sd_do_mode_sense(sdkp, 0, 0x3F, buffer, 255,
&data, NULL); &data, NULL);
} }
if (!scsi_status_is_good(res)) { if (res < 0) {
sd_first_printk(KERN_WARNING, sdkp, sd_first_printk(KERN_WARNING, sdkp,
"Test WP failed, assume Write Enabled\n"); "Test WP failed, assume Write Enabled\n");
} else { } else {
@ -2742,7 +2746,7 @@ sd_read_cache_type(struct scsi_disk *sdkp, unsigned char *buffer)
res = sd_do_mode_sense(sdkp, dbd, modepage, buffer, first_len, res = sd_do_mode_sense(sdkp, dbd, modepage, buffer, first_len,
&data, &sshdr); &data, &sshdr);
if (!scsi_status_is_good(res)) if (res < 0)
goto bad_sense; goto bad_sense;
if (!data.header_length) { if (!data.header_length) {
@ -2774,7 +2778,7 @@ sd_read_cache_type(struct scsi_disk *sdkp, unsigned char *buffer)
res = sd_do_mode_sense(sdkp, dbd, modepage, buffer, len, res = sd_do_mode_sense(sdkp, dbd, modepage, buffer, len,
&data, &sshdr); &data, &sshdr);
if (scsi_status_is_good(res)) { if (!res) {
int offset = data.header_length + data.block_descriptor_length; int offset = data.header_length + data.block_descriptor_length;
while (offset < len) { while (offset < len) {
@ -2892,7 +2896,7 @@ static void sd_read_app_tag_own(struct scsi_disk *sdkp, unsigned char *buffer)
res = scsi_mode_sense(sdp, 1, 0x0a, buffer, 36, SD_TIMEOUT, res = scsi_mode_sense(sdp, 1, 0x0a, buffer, 36, SD_TIMEOUT,
sdkp->max_retries, &data, &sshdr); sdkp->max_retries, &data, &sshdr);
if (!scsi_status_is_good(res) || !data.header_length || if (res < 0 || !data.header_length ||
data.length < 6) { data.length < 6) {
sd_first_printk(KERN_WARNING, sdkp, sd_first_printk(KERN_WARNING, sdkp,
"getting Control mode page failed, assume no ATO\n"); "getting Control mode page failed, assume no ATO\n");
@ -3591,12 +3595,12 @@ static int sd_start_stop_device(struct scsi_disk *sdkp, int start)
SD_TIMEOUT, sdkp->max_retries, 0, RQF_PM, NULL); SD_TIMEOUT, sdkp->max_retries, 0, RQF_PM, NULL);
if (res) { if (res) {
sd_print_result(sdkp, "Start/Stop Unit failed", res); sd_print_result(sdkp, "Start/Stop Unit failed", res);
if (driver_byte(res) == DRIVER_SENSE) if (res > 0 && scsi_sense_valid(&sshdr)) {
sd_print_sense_hdr(sdkp, &sshdr); sd_print_sense_hdr(sdkp, &sshdr);
if (scsi_sense_valid(&sshdr) &&
/* 0x3a is medium not present */ /* 0x3a is medium not present */
sshdr.asc == 0x3a) if (sshdr.asc == 0x3a)
res = 0; res = 0;
}
} }
/* SCSI error codes must not go to the generic layer */ /* SCSI error codes must not go to the generic layer */
@ -3806,15 +3810,14 @@ void sd_print_sense_hdr(struct scsi_disk *sdkp, struct scsi_sense_hdr *sshdr)
void sd_print_result(const struct scsi_disk *sdkp, const char *msg, int result) void sd_print_result(const struct scsi_disk *sdkp, const char *msg, int result)
{ {
const char *hb_string = scsi_hostbyte_string(result); const char *hb_string = scsi_hostbyte_string(result);
const char *db_string = scsi_driverbyte_string(result);
if (hb_string || db_string) if (hb_string)
sd_printk(KERN_INFO, sdkp, sd_printk(KERN_INFO, sdkp,
"%s: Result: hostbyte=%s driverbyte=%s\n", msg, "%s: Result: hostbyte=%s driverbyte=%s\n", msg,
hb_string ? hb_string : "invalid", hb_string ? hb_string : "invalid",
db_string ? db_string : "invalid"); "DRIVER_OK");
else else
sd_printk(KERN_INFO, sdkp, sd_printk(KERN_INFO, sdkp,
"%s: Result: hostbyte=0x%02x driverbyte=0x%02x\n", "%s: Result: hostbyte=0x%02x driverbyte=%s\n",
msg, host_byte(result), driver_byte(result)); msg, host_byte(result), "DRIVER_OK");
} }

View File

@ -116,8 +116,7 @@ static int sd_zbc_do_report_zones(struct scsi_disk *sdkp, unsigned char *buf,
sd_printk(KERN_ERR, sdkp, sd_printk(KERN_ERR, sdkp,
"REPORT ZONES start lba %llu failed\n", lba); "REPORT ZONES start lba %llu failed\n", lba);
sd_print_result(sdkp, "REPORT ZONES", result); sd_print_result(sdkp, "REPORT ZONES", result);
if (driver_byte(result) == DRIVER_SENSE && if (result > 0 && scsi_sense_valid(&sshdr))
scsi_sense_valid(&sshdr))
sd_print_sense_hdr(sdkp, &sshdr); sd_print_sense_hdr(sdkp, &sshdr);
return -EIO; return -EIO;
} }

View File

@ -498,9 +498,11 @@ sg_read(struct file *filp, char __user *buf, size_t count, loff_t * ppos)
old_hdr->host_status = hp->host_status; old_hdr->host_status = hp->host_status;
old_hdr->driver_status = hp->driver_status; old_hdr->driver_status = hp->driver_status;
if ((CHECK_CONDITION & hp->masked_status) || if ((CHECK_CONDITION & hp->masked_status) ||
(DRIVER_SENSE & hp->driver_status)) (srp->sense_b[0] & 0x70) == 0x70) {
old_hdr->driver_status = DRIVER_SENSE;
memcpy(old_hdr->sense_buffer, srp->sense_b, memcpy(old_hdr->sense_buffer, srp->sense_b,
sizeof (old_hdr->sense_buffer)); sizeof (old_hdr->sense_buffer));
}
switch (hp->host_status) { switch (hp->host_status) {
/* This setup of 'result' is for backward compatibility and is best /* This setup of 'result' is for backward compatibility and is best
ignored by the user who should use target, host + driver status */ ignored by the user who should use target, host + driver status */
@ -574,7 +576,7 @@ sg_new_read(Sg_fd * sfp, char __user *buf, size_t count, Sg_request * srp)
hp->sb_len_wr = 0; hp->sb_len_wr = 0;
if ((hp->mx_sb_len > 0) && hp->sbp) { if ((hp->mx_sb_len > 0) && hp->sbp) {
if ((CHECK_CONDITION & hp->masked_status) || if ((CHECK_CONDITION & hp->masked_status) ||
(DRIVER_SENSE & hp->driver_status)) { (srp->sense_b[0] & 0x70) == 0x70) {
int sb_len = SCSI_SENSE_BUFFERSIZE; int sb_len = SCSI_SENSE_BUFFERSIZE;
sb_len = (hp->mx_sb_len > sb_len) ? sb_len : hp->mx_sb_len; sb_len = (hp->mx_sb_len > sb_len) ? sb_len : hp->mx_sb_len;
len = 8 + (int) srp->sense_b[7]; /* Additional sense length field */ len = 8 + (int) srp->sense_b[7]; /* Additional sense length field */
@ -583,6 +585,7 @@ sg_new_read(Sg_fd * sfp, char __user *buf, size_t count, Sg_request * srp)
err = -EFAULT; err = -EFAULT;
goto err_out; goto err_out;
} }
hp->driver_status = DRIVER_SENSE;
hp->sb_len_wr = len; hp->sb_len_wr = len;
} }
} }
@ -1373,7 +1376,7 @@ sg_rq_end_io(struct request *rq, blk_status_t status)
srp->header.status = 0xff & result; srp->header.status = 0xff & result;
srp->header.masked_status = status_byte(result); srp->header.masked_status = status_byte(result);
srp->header.msg_status = msg_byte(result); srp->header.msg_status = COMMAND_COMPLETE;
srp->header.host_status = host_byte(result); srp->header.host_status = host_byte(result);
srp->header.driver_status = driver_byte(result); srp->header.driver_status = driver_byte(result);
if ((sdp->sgdebug > 0) && if ((sdp->sgdebug > 0) &&

View File

@ -3087,8 +3087,7 @@ static void pqi_process_aio_io_error(struct pqi_io_request *io_request)
} }
if (device_offline && sense_data_length == 0) if (device_offline && sense_data_length == 0)
scsi_build_sense_buffer(0, scmd->sense_buffer, HARDWARE_ERROR, scsi_build_sense(scmd, 0, HARDWARE_ERROR, 0x3e, 0x1);
0x3e, 0x1);
scmd->result = scsi_status; scmd->result = scsi_status;
set_host_byte(scmd, host_byte); set_host_byte(scmd, host_byte);

View File

@ -338,7 +338,7 @@ static int sr_done(struct scsi_cmnd *SCpnt)
* care is taken to avoid unnecessary additional work such as * care is taken to avoid unnecessary additional work such as
* memcpy's that could be avoided. * memcpy's that could be avoided.
*/ */
if (driver_byte(result) != 0 && /* An error occurred */ if (scsi_status_is_check_condition(result) &&
(SCpnt->sense_buffer[0] & 0x7f) == 0x70) { /* Sense current */ (SCpnt->sense_buffer[0] & 0x7f) == 0x70) { /* Sense current */
switch (SCpnt->sense_buffer[2]) { switch (SCpnt->sense_buffer[2]) {
case MEDIUM_ERROR: case MEDIUM_ERROR:
@ -911,7 +911,7 @@ static void get_capabilities(struct scsi_cd *cd)
rc = scsi_mode_sense(cd->device, 0, 0x2a, buffer, ms_len, rc = scsi_mode_sense(cd->device, 0, 0x2a, buffer, ms_len,
SR_TIMEOUT, 3, &data, NULL); SR_TIMEOUT, 3, &data, NULL);
if (!scsi_status_is_good(rc) || data.length > ms_len || if (rc < 0 || data.length > ms_len ||
data.header_length + data.block_descriptor_length > data.length) { data.header_length + data.block_descriptor_length > data.length) {
/* failed, drive doesn't have capabilities mode page */ /* failed, drive doesn't have capabilities mode page */
cd->cdi.speed = 1; cd->cdi.speed = 1;

View File

@ -201,7 +201,11 @@ int sr_do_ioctl(Scsi_CD *cd, struct packet_command *cgc)
cgc->timeout, IOCTL_RETRIES, 0, 0, NULL); cgc->timeout, IOCTL_RETRIES, 0, 0, NULL);
/* Minimal error checking. Ignore cases we know about, and report the rest. */ /* Minimal error checking. Ignore cases we know about, and report the rest. */
if (driver_byte(result) != 0) { if (result < 0) {
err = result;
goto out;
}
if (scsi_status_is_check_condition(result)) {
switch (sshdr->sense_key) { switch (sshdr->sense_key) {
case UNIT_ATTENTION: case UNIT_ATTENTION:
SDev->changed = 1; SDev->changed = 1;

View File

@ -390,8 +390,8 @@ static int st_chk_result(struct scsi_tape *STp, struct st_request * SRpnt)
if (!debugging) { /* Abnormal conditions for tape */ if (!debugging) { /* Abnormal conditions for tape */
if (!cmdstatp->have_sense) if (!cmdstatp->have_sense)
st_printk(KERN_WARNING, STp, st_printk(KERN_WARNING, STp,
"Error %x (driver bt 0x%x, host bt 0x%x).\n", "Error %x (driver bt 0, host bt 0x%x).\n",
result, driver_byte(result), host_byte(result)); result, host_byte(result));
else if (cmdstatp->have_sense && else if (cmdstatp->have_sense &&
scode != NO_SENSE && scode != NO_SENSE &&
scode != RECOVERED_ERROR && scode != RECOVERED_ERROR &&
@ -551,7 +551,7 @@ static int st_scsi_execute(struct st_request *SRpnt, const unsigned char *cmd,
data_direction == DMA_TO_DEVICE ? data_direction == DMA_TO_DEVICE ?
REQ_OP_SCSI_OUT : REQ_OP_SCSI_IN, 0); REQ_OP_SCSI_OUT : REQ_OP_SCSI_IN, 0);
if (IS_ERR(req)) if (IS_ERR(req))
return DRIVER_ERROR << 24; return PTR_ERR(req);
rq = scsi_req(req); rq = scsi_req(req);
req->rq_flags |= RQF_QUIET; req->rq_flags |= RQF_QUIET;
@ -562,7 +562,7 @@ static int st_scsi_execute(struct st_request *SRpnt, const unsigned char *cmd,
GFP_KERNEL); GFP_KERNEL);
if (err) { if (err) {
blk_put_request(req); blk_put_request(req);
return DRIVER_ERROR << 24; return err;
} }
} }

View File

@ -398,11 +398,8 @@ static struct status_msg *stex_get_status(struct st_hba *hba)
static void stex_invalid_field(struct scsi_cmnd *cmd, static void stex_invalid_field(struct scsi_cmnd *cmd,
void (*done)(struct scsi_cmnd *)) void (*done)(struct scsi_cmnd *))
{ {
cmd->result = (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION;
/* "Invalid field in cdb" */ /* "Invalid field in cdb" */
scsi_build_sense_buffer(0, cmd->sense_buffer, ILLEGAL_REQUEST, 0x24, scsi_build_sense(cmd, 0, ILLEGAL_REQUEST, 0x24, 0x0);
0x0);
done(cmd); done(cmd);
} }
@ -740,7 +737,7 @@ static void stex_scsi_done(struct st_ccb *ccb)
result |= DID_OK << 16; result |= DID_OK << 16;
break; break;
case SAM_STAT_CHECK_CONDITION: case SAM_STAT_CHECK_CONDITION:
result |= DRIVER_SENSE << 24; result |= DID_OK << 16;
break; break;
case SAM_STAT_BUSY: case SAM_STAT_BUSY:
result |= DID_BUS_BUSY << 16; result |= DID_BUS_BUSY << 16;
@ -751,7 +748,7 @@ static void stex_scsi_done(struct st_ccb *ccb)
} }
} }
else if (ccb->srb_status & SRB_SEE_SENSE) else if (ccb->srb_status & SRB_SEE_SENSE)
result = DRIVER_SENSE << 24 | SAM_STAT_CHECK_CONDITION; result = SAM_STAT_CHECK_CONDITION;
else switch (ccb->srb_status) { else switch (ccb->srb_status) {
case SRB_STATUS_SELECTION_TIMEOUT: case SRB_STATUS_SELECTION_TIMEOUT:
result = DID_NO_CONNECT << 16; result = DID_NO_CONNECT << 16;

View File

@ -170,9 +170,8 @@ static int sym_xerr_cam_status(int cam_status, int x_status)
void sym_set_cam_result_error(struct sym_hcb *np, struct sym_ccb *cp, int resid) void sym_set_cam_result_error(struct sym_hcb *np, struct sym_ccb *cp, int resid)
{ {
struct scsi_cmnd *cmd = cp->cmd; struct scsi_cmnd *cmd = cp->cmd;
u_int cam_status, scsi_status, drv_status; u_int cam_status, scsi_status;
drv_status = 0;
cam_status = DID_OK; cam_status = DID_OK;
scsi_status = cp->ssss_status; scsi_status = cp->ssss_status;
@ -186,7 +185,6 @@ void sym_set_cam_result_error(struct sym_hcb *np, struct sym_ccb *cp, int resid)
cp->xerr_status == 0) { cp->xerr_status == 0) {
cam_status = sym_xerr_cam_status(DID_OK, cam_status = sym_xerr_cam_status(DID_OK,
cp->sv_xerr_status); cp->sv_xerr_status);
drv_status = DRIVER_SENSE;
/* /*
* Bounce back the sense data to user. * Bounce back the sense data to user.
*/ */
@ -235,7 +233,7 @@ void sym_set_cam_result_error(struct sym_hcb *np, struct sym_ccb *cp, int resid)
cam_status = sym_xerr_cam_status(DID_ERROR, cp->xerr_status); cam_status = sym_xerr_cam_status(DID_ERROR, cp->xerr_status);
} }
scsi_set_resid(cmd, resid); scsi_set_resid(cmd, resid);
cmd->result = (drv_status << 24) | (cam_status << 16) | scsi_status; cmd->result = (cam_status << 16) | scsi_status;
} }
static int sym_scatter(struct sym_hcb *np, struct sym_ccb *cp, struct scsi_cmnd *cmd) static int sym_scatter(struct sym_hcb *np, struct sym_ccb *cp, struct scsi_cmnd *cmd)

View File

@ -8605,7 +8605,7 @@ static int ufshcd_set_dev_pwr_mode(struct ufs_hba *hba,
sdev_printk(KERN_WARNING, sdp, sdev_printk(KERN_WARNING, sdp,
"START_STOP failed for power mode: %d, result %x\n", "START_STOP failed for power mode: %d, result %x\n",
pwr_mode, ret); pwr_mode, ret);
if (driver_byte(ret) == DRIVER_SENSE) if (ret > 0 && scsi_sense_valid(&sshdr))
scsi_print_sense_hdr(sdp, NULL, &sshdr); scsi_print_sense_hdr(sdp, NULL, &sshdr);
} }

View File

@ -161,8 +161,7 @@ static void virtscsi_complete_cmd(struct virtio_scsi *vscsi, void *buf)
min_t(u32, min_t(u32,
virtio32_to_cpu(vscsi->vdev, resp->sense_len), virtio32_to_cpu(vscsi->vdev, resp->sense_len),
VIRTIO_SCSI_SENSE_SIZE)); VIRTIO_SCSI_SENSE_SIZE));
if (resp->sense_len) set_status_byte(sc, SAM_STAT_CHECK_CONDITION);
set_driver_byte(sc, DRIVER_SENSE);
} }
sc->scsi_done(sc); sc->scsi_done(sc);
@ -355,7 +354,7 @@ static void virtscsi_rescan_hotunplug(struct virtio_scsi *vscsi)
if (result == 0 && inq_result[0] >> 5) { if (result == 0 && inq_result[0] >> 5) {
/* PQ indicates the LUN is not attached */ /* PQ indicates the LUN is not attached */
scsi_remove_device(sdev); scsi_remove_device(sdev);
} else if (host_byte(result) == DID_BAD_TARGET) { } else if (result > 0 && host_byte(result) == DID_BAD_TARGET) {
/* /*
* If all LUNs of a virtio-scsi device are unplugged * If all LUNs of a virtio-scsi device are unplugged
* it will respond with BAD TARGET on any INQUIRY * it will respond with BAD TARGET on any INQUIRY

View File

@ -576,9 +576,6 @@ static void pvscsi_complete_request(struct pvscsi_adapter *adapter,
cmd->result = (DID_RESET << 16); cmd->result = (DID_RESET << 16);
} else { } else {
cmd->result = (DID_OK << 16) | sdstat; cmd->result = (DID_OK << 16) | sdstat;
if (sdstat == SAM_STAT_CHECK_CONDITION &&
cmd->sense_buffer)
cmd->result |= (DRIVER_SENSE << 24);
} }
} else } else
switch (btstat) { switch (btstat) {
@ -604,9 +601,6 @@ static void pvscsi_complete_request(struct pvscsi_adapter *adapter,
case BTSTAT_LUNMISMATCH: case BTSTAT_LUNMISMATCH:
case BTSTAT_TAGREJECT: case BTSTAT_TAGREJECT:
case BTSTAT_BADMSG: case BTSTAT_BADMSG:
cmd->result = (DRIVER_INVALID << 24);
fallthrough;
case BTSTAT_HAHARDWARE: case BTSTAT_HAHARDWARE:
case BTSTAT_INVPHASE: case BTSTAT_INVPHASE:
case BTSTAT_HATIMEOUT: case BTSTAT_HATIMEOUT:

View File

@ -1176,13 +1176,13 @@ wd33c93_intr(struct Scsi_Host *instance)
if (cmd->SCp.Status == ILLEGAL_STATUS_BYTE) if (cmd->SCp.Status == ILLEGAL_STATUS_BYTE)
cmd->SCp.Status = lun; cmd->SCp.Status = lun;
if (cmd->cmnd[0] == REQUEST_SENSE if (cmd->cmnd[0] == REQUEST_SENSE
&& cmd->SCp.Status != SAM_STAT_GOOD) && cmd->SCp.Status != SAM_STAT_GOOD) {
cmd->result = set_host_byte(cmd, DID_ERROR);
(cmd-> } else {
result & 0x00ffff) | (DID_ERROR << 16); set_host_byte(cmd, DID_OK);
else scsi_msg_to_host_byte(cmd, cmd->SCp.Message);
cmd->result = set_status_byte(cmd, cmd->SCp.Status);
cmd->SCp.Status | (cmd->SCp.Message << 8); }
cmd->scsi_done(cmd); cmd->scsi_done(cmd);
/* We are no longer connected to a target - check to see if /* We are no longer connected to a target - check to see if
@ -1262,11 +1262,14 @@ wd33c93_intr(struct Scsi_Host *instance)
hostdata->connected = NULL; hostdata->connected = NULL;
hostdata->busy[cmd->device->id] &= ~(1 << (cmd->device->lun & 0xff)); hostdata->busy[cmd->device->id] &= ~(1 << (cmd->device->lun & 0xff));
hostdata->state = S_UNCONNECTED; hostdata->state = S_UNCONNECTED;
if (cmd->cmnd[0] == REQUEST_SENSE && cmd->SCp.Status != SAM_STAT_GOOD) if (cmd->cmnd[0] == REQUEST_SENSE &&
cmd->result = cmd->SCp.Status != SAM_STAT_GOOD) {
(cmd->result & 0x00ffff) | (DID_ERROR << 16); set_host_byte(cmd, DID_ERROR);
else } else {
cmd->result = cmd->SCp.Status | (cmd->SCp.Message << 8); set_host_byte(cmd, DID_OK);
scsi_msg_to_host_byte(cmd, cmd->SCp.Message);
set_status_byte(cmd, cmd->SCp.Status);
}
cmd->scsi_done(cmd); cmd->scsi_done(cmd);
/* We are no longer connected to a target - check to see if /* We are no longer connected to a target - check to see if
@ -1295,14 +1298,14 @@ wd33c93_intr(struct Scsi_Host *instance)
hostdata->busy[cmd->device->id] &= ~(1 << (cmd->device->lun & 0xff)); hostdata->busy[cmd->device->id] &= ~(1 << (cmd->device->lun & 0xff));
hostdata->state = S_UNCONNECTED; hostdata->state = S_UNCONNECTED;
DB(DB_INTR, printk(":%d", cmd->SCp.Status)) DB(DB_INTR, printk(":%d", cmd->SCp.Status))
if (cmd->cmnd[0] == REQUEST_SENSE if (cmd->cmnd[0] == REQUEST_SENSE
&& cmd->SCp.Status != SAM_STAT_GOOD) && cmd->SCp.Status != SAM_STAT_GOOD) {
cmd->result = set_host_byte(cmd, DID_ERROR);
(cmd-> } else {
result & 0x00ffff) | (DID_ERROR << 16); set_host_byte(cmd, DID_OK);
else scsi_msg_to_host_byte(cmd, cmd->SCp.Message);
cmd->result = set_status_byte(cmd, cmd->SCp.Status);
cmd->SCp.Status | (cmd->SCp.Message << 8); }
cmd->scsi_done(cmd); cmd->scsi_done(cmd);
break; break;
case S_PRE_TMP_DISC: case S_PRE_TMP_DISC:

View File

@ -251,6 +251,7 @@ static void scsifront_cdb_cmd_done(struct vscsifrnt_info *info,
struct scsi_cmnd *sc; struct scsi_cmnd *sc;
uint32_t id; uint32_t id;
uint8_t sense_len; uint8_t sense_len;
int result;
id = ring_rsp->rqid; id = ring_rsp->rqid;
shadow = info->shadow[id]; shadow = info->shadow[id];
@ -261,7 +262,12 @@ static void scsifront_cdb_cmd_done(struct vscsifrnt_info *info,
scsifront_gnttab_done(info, shadow); scsifront_gnttab_done(info, shadow);
scsifront_put_rqid(info, id); scsifront_put_rqid(info, id);
sc->result = ring_rsp->rslt; result = ring_rsp->rslt;
if (result >> 24)
set_host_byte(sc, DID_ERROR);
else
set_host_byte(sc, host_byte(result));
set_status_byte(sc, result & 0xff);
scsi_set_resid(sc, ring_rsp->residual_len); scsi_set_resid(sc, ring_rsp->residual_len);
sense_len = min_t(uint8_t, VSCSIIF_SENSE_BUFFERSIZE, sense_len = min_t(uint8_t, VSCSIIF_SENSE_BUFFERSIZE,

View File

@ -566,7 +566,6 @@ static int tcm_loop_queue_data_or_status(const char *func,
memcpy(sc->sense_buffer, se_cmd->sense_buffer, memcpy(sc->sense_buffer, se_cmd->sense_buffer,
SCSI_SENSE_BUFFERSIZE); SCSI_SENSE_BUFFERSIZE);
sc->result = SAM_STAT_CHECK_CONDITION; sc->result = SAM_STAT_CHECK_CONDITION;
set_driver_byte(sc, DRIVER_SENSE);
} else } else
sc->result = scsi_status; sc->result = scsi_status;

View File

@ -123,7 +123,7 @@ target_emulate_report_referrals(struct se_cmd *cmd)
transport_kunmap_data_sg(cmd); transport_kunmap_data_sg(cmd);
target_complete_cmd(cmd, GOOD); target_complete_cmd(cmd, SAM_STAT_GOOD);
return 0; return 0;
} }
@ -255,7 +255,7 @@ target_emulate_report_target_port_groups(struct se_cmd *cmd)
} }
transport_kunmap_data_sg(cmd); transport_kunmap_data_sg(cmd);
target_complete_cmd_with_length(cmd, GOOD, rd_len + 4); target_complete_cmd_with_length(cmd, SAM_STAT_GOOD, rd_len + 4);
return 0; return 0;
} }
@ -424,7 +424,7 @@ target_emulate_set_target_port_groups(struct se_cmd *cmd)
out: out:
transport_kunmap_data_sg(cmd); transport_kunmap_data_sg(cmd);
if (!rc) if (!rc)
target_complete_cmd(cmd, GOOD); target_complete_cmd(cmd, SAM_STAT_GOOD);
return rc; return rc;
} }

View File

@ -474,7 +474,7 @@ iblock_execute_zero_out(struct block_device *bdev, struct se_cmd *cmd)
if (ret) if (ret)
return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
target_complete_cmd(cmd, GOOD); target_complete_cmd(cmd, SAM_STAT_GOOD);
return 0; return 0;
} }

View File

@ -234,7 +234,7 @@ target_scsi2_reservation_release(struct se_cmd *cmd)
out_unlock: out_unlock:
spin_unlock(&dev->dev_reservation_lock); spin_unlock(&dev->dev_reservation_lock);
out: out:
target_complete_cmd(cmd, GOOD); target_complete_cmd(cmd, SAM_STAT_GOOD);
return 0; return 0;
} }
@ -297,7 +297,7 @@ out_unlock:
spin_unlock(&dev->dev_reservation_lock); spin_unlock(&dev->dev_reservation_lock);
out: out:
if (!ret) if (!ret)
target_complete_cmd(cmd, GOOD); target_complete_cmd(cmd, SAM_STAT_GOOD);
return ret; return ret;
} }
@ -3676,7 +3676,7 @@ target_scsi3_emulate_pr_out(struct se_cmd *cmd)
} }
if (!ret) if (!ret)
target_complete_cmd(cmd, GOOD); target_complete_cmd(cmd, SAM_STAT_GOOD);
return ret; return ret;
} }
@ -4073,7 +4073,7 @@ target_scsi3_emulate_pr_in(struct se_cmd *cmd)
} }
if (!ret) if (!ret)
target_complete_cmd(cmd, GOOD); target_complete_cmd(cmd, SAM_STAT_GOOD);
return ret; return ret;
} }

View File

@ -1044,7 +1044,7 @@ static void pscsi_req_done(struct request *req, blk_status_t status)
struct se_cmd *cmd = req->end_io_data; struct se_cmd *cmd = req->end_io_data;
struct pscsi_plugin_task *pt = cmd->priv; struct pscsi_plugin_task *pt = cmd->priv;
int result = scsi_req(req)->result; int result = scsi_req(req)->result;
u8 scsi_status = status_byte(result) << 1; u8 scsi_status = result & 0xff;
if (scsi_status != SAM_STAT_GOOD) { if (scsi_status != SAM_STAT_GOOD) {
pr_debug("PSCSI Status Byte exception at cmd: %p CDB:" pr_debug("PSCSI Status Byte exception at cmd: %p CDB:"

View File

@ -67,7 +67,7 @@ sbc_emulate_readcapacity(struct se_cmd *cmd)
transport_kunmap_data_sg(cmd); transport_kunmap_data_sg(cmd);
} }
target_complete_cmd_with_length(cmd, GOOD, 8); target_complete_cmd_with_length(cmd, SAM_STAT_GOOD, 8);
return 0; return 0;
} }
@ -130,7 +130,7 @@ sbc_emulate_readcapacity_16(struct se_cmd *cmd)
transport_kunmap_data_sg(cmd); transport_kunmap_data_sg(cmd);
} }
target_complete_cmd_with_length(cmd, GOOD, 32); target_complete_cmd_with_length(cmd, SAM_STAT_GOOD, 32);
return 0; return 0;
} }
@ -202,14 +202,14 @@ sbc_execute_write_same_unmap(struct se_cmd *cmd)
return ret; return ret;
} }
target_complete_cmd(cmd, GOOD); target_complete_cmd(cmd, SAM_STAT_GOOD);
return 0; return 0;
} }
static sense_reason_t static sense_reason_t
sbc_emulate_noop(struct se_cmd *cmd) sbc_emulate_noop(struct se_cmd *cmd)
{ {
target_complete_cmd(cmd, GOOD); target_complete_cmd(cmd, SAM_STAT_GOOD);
return 0; return 0;
} }
@ -1245,7 +1245,7 @@ sbc_execute_unmap(struct se_cmd *cmd)
err: err:
transport_kunmap_data_sg(cmd); transport_kunmap_data_sg(cmd);
if (!ret) if (!ret)
target_complete_cmd(cmd, GOOD); target_complete_cmd(cmd, SAM_STAT_GOOD);
return ret; return ret;
} }

View File

@ -781,7 +781,7 @@ out:
kfree(buf); kfree(buf);
if (!ret) if (!ret)
target_complete_cmd_with_length(cmd, GOOD, len); target_complete_cmd_with_length(cmd, SAM_STAT_GOOD, len);
return ret; return ret;
} }
@ -1135,7 +1135,7 @@ set_length:
transport_kunmap_data_sg(cmd); transport_kunmap_data_sg(cmd);
} }
target_complete_cmd_with_length(cmd, GOOD, length); target_complete_cmd_with_length(cmd, SAM_STAT_GOOD, length);
return 0; return 0;
} }
@ -1153,7 +1153,7 @@ static sense_reason_t spc_emulate_modeselect(struct se_cmd *cmd)
int i; int i;
if (!cmd->data_length) { if (!cmd->data_length) {
target_complete_cmd(cmd, GOOD); target_complete_cmd(cmd, SAM_STAT_GOOD);
return 0; return 0;
} }
@ -1196,7 +1196,7 @@ out:
transport_kunmap_data_sg(cmd); transport_kunmap_data_sg(cmd);
if (!ret) if (!ret)
target_complete_cmd(cmd, GOOD); target_complete_cmd(cmd, SAM_STAT_GOOD);
return ret; return ret;
} }
@ -1229,7 +1229,7 @@ static sense_reason_t spc_emulate_request_sense(struct se_cmd *cmd)
memcpy(rbuf, buf, min_t(u32, sizeof(buf), cmd->data_length)); memcpy(rbuf, buf, min_t(u32, sizeof(buf), cmd->data_length));
transport_kunmap_data_sg(cmd); transport_kunmap_data_sg(cmd);
target_complete_cmd(cmd, GOOD); target_complete_cmd(cmd, SAM_STAT_GOOD);
return 0; return 0;
} }
@ -1296,7 +1296,7 @@ done:
transport_kunmap_data_sg(cmd); transport_kunmap_data_sg(cmd);
} }
target_complete_cmd_with_length(cmd, GOOD, 8 + lun_count * 8); target_complete_cmd_with_length(cmd, SAM_STAT_GOOD, 8 + lun_count * 8);
return 0; return 0;
} }
EXPORT_SYMBOL(spc_emulate_report_luns); EXPORT_SYMBOL(spc_emulate_report_luns);
@ -1304,7 +1304,7 @@ EXPORT_SYMBOL(spc_emulate_report_luns);
static sense_reason_t static sense_reason_t
spc_emulate_testunitready(struct se_cmd *cmd) spc_emulate_testunitready(struct se_cmd *cmd)
{ {
target_complete_cmd(cmd, GOOD); target_complete_cmd(cmd, SAM_STAT_GOOD);
return 0; return 0;
} }

View File

@ -998,7 +998,7 @@ static sense_reason_t target_rcr_operating_parameters(struct se_cmd *se_cmd)
put_unaligned_be32(42, &p[0]); put_unaligned_be32(42, &p[0]);
transport_kunmap_data_sg(se_cmd); transport_kunmap_data_sg(se_cmd);
target_complete_cmd(se_cmd, GOOD); target_complete_cmd(se_cmd, SAM_STAT_GOOD);
return TCM_NO_SENSE; return TCM_NO_SENSE;
} }

View File

@ -221,11 +221,11 @@ static void cypress_atacb_passthrough(struct scsi_cmnd *srb, struct us_data *us)
desc[12] = regs[6]; /* device */ desc[12] = regs[6]; /* device */
desc[13] = regs[7]; /* command */ desc[13] = regs[7]; /* command */
srb->result = (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION; srb->result = SAM_STAT_CHECK_CONDITION;
} }
goto end; goto end;
invalid_fld: invalid_fld:
srb->result = (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION; srb->result = SAM_STAT_CHECK_CONDITION;
memcpy(srb->sense_buffer, memcpy(srb->sense_buffer,
usb_stor_sense_invalidCDB, usb_stor_sense_invalidCDB,

View File

@ -222,10 +222,10 @@ static void scsiback_print_status(char *sense_buffer, int errors,
{ {
struct scsiback_tpg *tpg = pending_req->v2p->tpg; struct scsiback_tpg *tpg = pending_req->v2p->tpg;
pr_err("[%s:%d] cmnd[0]=%02x -> st=%02x msg=%02x host=%02x drv=%02x\n", pr_err("[%s:%d] cmnd[0]=%02x -> st=%02x msg=%02x host=%02x\n",
tpg->tport->tport_name, pending_req->v2p->lun, tpg->tport->tport_name, pending_req->v2p->lun,
pending_req->cmnd[0], status_byte(errors), msg_byte(errors), pending_req->cmnd[0], errors & 0xff, COMMAND_COMPLETE,
host_byte(errors), driver_byte(errors)); host_byte(errors));
} }
static void scsiback_fast_flush_area(struct vscsibk_pend *req) static void scsiback_fast_flush_area(struct vscsibk_pend *req)
@ -719,10 +719,10 @@ static int scsiback_do_cmd_fn(struct vscsibk_info *info,
result = DID_NO_CONNECT; result = DID_NO_CONNECT;
break; break;
default: default:
result = DRIVER_ERROR; result = DID_ERROR;
break; break;
} }
scsiback_send_response(info, NULL, result << 24, 0, scsiback_send_response(info, NULL, result << 16, 0,
ring_req.rqid); ring_req.rqid);
return 1; return 1;
} }
@ -732,7 +732,7 @@ static int scsiback_do_cmd_fn(struct vscsibk_info *info,
if (scsiback_gnttab_data_map(&ring_req, pending_req)) { if (scsiback_gnttab_data_map(&ring_req, pending_req)) {
scsiback_fast_flush_area(pending_req); scsiback_fast_flush_area(pending_req);
scsiback_do_resp_with_sense(NULL, scsiback_do_resp_with_sense(NULL,
DRIVER_ERROR << 24, 0, pending_req); DID_ERROR << 16, 0, pending_req);
transport_generic_free_cmd(&pending_req->se_cmd, 0); transport_generic_free_cmd(&pending_req->se_cmd, 0);
} else { } else {
scsiback_cmd_exec(pending_req); scsiback_cmd_exec(pending_req);
@ -747,7 +747,7 @@ static int scsiback_do_cmd_fn(struct vscsibk_info *info,
break; break;
default: default:
pr_err_ratelimited("invalid request\n"); pr_err_ratelimited("invalid request\n");
scsiback_do_resp_with_sense(NULL, DRIVER_ERROR << 24, 0, scsiback_do_resp_with_sense(NULL, DID_ERROR << 16, 0,
pending_req); pending_req);
transport_generic_free_cmd(&pending_req->se_cmd, 0); transport_generic_free_cmd(&pending_req->se_cmd, 0);
break; break;
@ -1401,8 +1401,7 @@ static int scsiback_queue_status(struct se_cmd *se_cmd)
if (se_cmd->sense_buffer && if (se_cmd->sense_buffer &&
((se_cmd->se_cmd_flags & SCF_TRANSPORT_TASK_SENSE) || ((se_cmd->se_cmd_flags & SCF_TRANSPORT_TASK_SENSE) ||
(se_cmd->se_cmd_flags & SCF_EMULATED_TASK_SENSE))) (se_cmd->se_cmd_flags & SCF_EMULATED_TASK_SENSE)))
pending_req->result = (DRIVER_SENSE << 24) | pending_req->result = SAM_STAT_CHECK_CONDITION;
SAM_STAT_CHECK_CONDITION;
else else
pending_req->result = se_cmd->scsi_status; pending_req->result = se_cmd->scsi_status;

View File

@ -62,6 +62,21 @@ static inline int scsi_is_wlun(u64 lun)
return (lun & 0xff00) == SCSI_W_LUN_BASE; return (lun & 0xff00) == SCSI_W_LUN_BASE;
} }
/**
* scsi_status_is_check_condition - check the status return.
*
* @status: the status passed up from the driver (including host and
* driver components)
*
* This returns true if the status code is SAM_STAT_CHECK_CONDITION.
*/
static inline int scsi_status_is_check_condition(int status)
{
if (status < 0)
return false;
status &= 0xfe;
return status == SAM_STAT_CHECK_CONDITION;
}
/* /*
* MESSAGE CODES * MESSAGE CODES
@ -137,20 +152,6 @@ static inline int scsi_is_wlun(u64 lun)
#define DID_TRANSPORT_MARGINAL 0x14 /* Transport marginal errors */ #define DID_TRANSPORT_MARGINAL 0x14 /* Transport marginal errors */
#define DRIVER_OK 0x00 /* Driver status */ #define DRIVER_OK 0x00 /* Driver status */
/*
* These indicate the error that occurred, and what is available.
*/
#define DRIVER_BUSY 0x01
#define DRIVER_SOFT 0x02
#define DRIVER_MEDIA 0x03
#define DRIVER_ERROR 0x04
#define DRIVER_INVALID 0x05
#define DRIVER_TIMEOUT 0x06
#define DRIVER_HARD 0x07
#define DRIVER_SENSE 0x08
/* /*
* Internal return values. * Internal return values.
*/ */
@ -180,14 +181,10 @@ enum scsi_disposition {
* These are set by: * These are set by:
* *
* status byte = set from target device * status byte = set from target device
* msg_byte = return status from host adapter itself. * msg_byte (unused)
* host_byte = set by low-level driver to indicate status. * host_byte = set by low-level driver to indicate status.
* driver_byte = set by mid-level.
*/ */
#define status_byte(result) (((result) >> 1) & 0x7f)
#define msg_byte(result) (((result) >> 8) & 0xff)
#define host_byte(result) (((result) >> 16) & 0xff) #define host_byte(result) (((result) >> 16) & 0xff)
#define driver_byte(result) (((result) >> 24) & 0xff)
#define sense_class(sense) (((sense) >> 4) & 0x7) #define sense_class(sense) (((sense) >> 4) & 0x7)
#define sense_error(sense) ((sense) & 0xf) #define sense_error(sense) ((sense) & 0xf)
@ -259,10 +256,13 @@ enum scsi_disposition {
* This returns true for known good conditions that may be treated as * This returns true for known good conditions that may be treated as
* command completed normally * command completed normally
*/ */
static inline int scsi_status_is_good(int status) static inline bool scsi_status_is_good(int status)
{ {
if (status < 0)
return false;
if (host_byte(status) == DID_NO_CONNECT) if (host_byte(status) == DID_NO_CONNECT)
return 0; return false;
/* /*
* FIXME: bit0 is listed as reserved in SCSI-2, but is * FIXME: bit0 is listed as reserved in SCSI-2, but is

View File

@ -315,9 +315,9 @@ static inline void set_status_byte(struct scsi_cmnd *cmd, char status)
cmd->result = (cmd->result & 0xffffff00) | status; cmd->result = (cmd->result & 0xffffff00) | status;
} }
static inline void set_msg_byte(struct scsi_cmnd *cmd, char status) static inline u8 get_status_byte(struct scsi_cmnd *cmd)
{ {
cmd->result = (cmd->result & 0xffff00ff) | (status << 8); return cmd->result & 0xff;
} }
static inline void set_host_byte(struct scsi_cmnd *cmd, char status) static inline void set_host_byte(struct scsi_cmnd *cmd, char status)
@ -325,9 +325,36 @@ static inline void set_host_byte(struct scsi_cmnd *cmd, char status)
cmd->result = (cmd->result & 0xff00ffff) | (status << 16); cmd->result = (cmd->result & 0xff00ffff) | (status << 16);
} }
static inline void set_driver_byte(struct scsi_cmnd *cmd, char status) static inline u8 get_host_byte(struct scsi_cmnd *cmd)
{ {
cmd->result = (cmd->result & 0x00ffffff) | (status << 24); return (cmd->result >> 16) & 0xff;
}
/**
* scsi_msg_to_host_byte() - translate message byte
*
* Translate the SCSI parallel message byte to a matching
* host byte setting. A message of COMMAND_COMPLETE indicates
* a successful command execution, any other message indicate
* an error. As the messages themselves only have a meaning
* for the SCSI parallel protocol this function translates
* them into a matching host byte value for SCSI EH.
*/
static inline void scsi_msg_to_host_byte(struct scsi_cmnd *cmd, u8 msg)
{
switch (msg) {
case COMMAND_COMPLETE:
break;
case ABORT_TASK_SET:
set_host_byte(cmd, DID_ABORT);
break;
case TARGET_RESET:
set_host_byte(cmd, DID_RESET);
break;
default:
set_host_byte(cmd, DID_ERROR);
break;
}
} }
static inline unsigned scsi_transfer_length(struct scsi_cmnd *scmd) static inline unsigned scsi_transfer_length(struct scsi_cmnd *scmd)
@ -341,4 +368,7 @@ static inline unsigned scsi_transfer_length(struct scsi_cmnd *scmd)
return xfer_len; return xfer_len;
} }
extern void scsi_build_sense(struct scsi_cmnd *scmd, int desc,
u8 key, u8 asc, u8 ascq);
#endif /* _SCSI_SCSI_CMND_H */ #endif /* _SCSI_SCSI_CMND_H */

View File

@ -202,27 +202,7 @@ struct scsi_varlen_cdb_hdr {
#define SAM_STAT_ACA_ACTIVE 0x30 #define SAM_STAT_ACA_ACTIVE 0x30
#define SAM_STAT_TASK_ABORTED 0x40 #define SAM_STAT_TASK_ABORTED 0x40
/* #define STATUS_MASK 0xfe
* Status codes. These are deprecated as they are shifted 1 bit right
* from those found in the SCSI standards. This causes confusion for
* applications that are ported to several OSes. Prefer SAM Status codes
* above.
*/
#define GOOD 0x00
#define CHECK_CONDITION 0x01
#define CONDITION_GOOD 0x02
#define BUSY 0x04
#define INTERMEDIATE_GOOD 0x08
#define INTERMEDIATE_C_GOOD 0x0a
#define RESERVATION_CONFLICT 0x0c
#define COMMAND_TERMINATED 0x11
#define QUEUE_FULL 0x14
#define ACA_ACTIVE 0x18
#define TASK_ABORTED 0x20
#define STATUS_MASK 0xfe
/* /*
* SENSE KEYS * SENSE KEYS
*/ */

View File

@ -131,6 +131,39 @@ struct compat_sg_io_hdr {
#define SG_INFO_DIRECT_IO 0x2 /* direct IO requested and performed */ #define SG_INFO_DIRECT_IO 0x2 /* direct IO requested and performed */
#define SG_INFO_MIXED_IO 0x4 /* part direct, part indirect IO */ #define SG_INFO_MIXED_IO 0x4 /* part direct, part indirect IO */
/*
* Obsolete DRIVER_SENSE driver byte
*
* Originally the SCSI midlayer would set the DRIVER_SENSE driver byte when
* a sense code was generated and a sense buffer was allocated.
* However, as nowadays every scsi command has a sense code allocated this
* distinction became moot as one could check the sense buffer directly.
* Consequently this byte is not set anymore from the midlayer, but SG will
* keep setting this byte to be compatible with previous releases.
*/
#define DRIVER_SENSE 0x08
/* Obsolete driver_byte() declaration */
#define driver_byte(result) (((result) >> 24) & 0xff)
/*
* Original linux SCSI Status codes. They are shifted 1 bit right
* from those found in the SCSI standards.
*/
#define GOOD 0x00
#define CHECK_CONDITION 0x01
#define CONDITION_GOOD 0x02
#define BUSY 0x04
#define INTERMEDIATE_GOOD 0x08
#define INTERMEDIATE_C_GOOD 0x0a
#define RESERVATION_CONFLICT 0x0c
#define COMMAND_TERMINATED 0x11
#define QUEUE_FULL 0x14
#define ACA_ACTIVE 0x18
#define TASK_ABORTED 0x20
/* Obsolete status_byte() declaration */
#define status_byte(result) (((result) >> 1) & 0x7f)
typedef struct sg_scsi_id { /* used by SG_GET_SCSI_ID ioctl() */ typedef struct sg_scsi_id { /* used by SG_GET_SCSI_ID ioctl() */
int host_no; /* as in "scsi<n>" where 'n' is one of 0, 1, 2 etc */ int host_no; /* as in "scsi<n>" where 'n' is one of 0, 1, 2 etc */

View File

@ -124,50 +124,6 @@
scsi_hostbyte_name(DID_TRANSPORT_DISRUPTED), \ scsi_hostbyte_name(DID_TRANSPORT_DISRUPTED), \
scsi_hostbyte_name(DID_TRANSPORT_FAILFAST)) scsi_hostbyte_name(DID_TRANSPORT_FAILFAST))
#define scsi_driverbyte_name(result) { result, #result }
#define show_driverbyte_name(val) \
__print_symbolic(val, \
scsi_driverbyte_name(DRIVER_OK), \
scsi_driverbyte_name(DRIVER_BUSY), \
scsi_driverbyte_name(DRIVER_SOFT), \
scsi_driverbyte_name(DRIVER_MEDIA), \
scsi_driverbyte_name(DRIVER_ERROR), \
scsi_driverbyte_name(DRIVER_INVALID), \
scsi_driverbyte_name(DRIVER_TIMEOUT), \
scsi_driverbyte_name(DRIVER_HARD), \
scsi_driverbyte_name(DRIVER_SENSE))
#define scsi_msgbyte_name(result) { result, #result }
#define show_msgbyte_name(val) \
__print_symbolic(val, \
scsi_msgbyte_name(COMMAND_COMPLETE), \
scsi_msgbyte_name(EXTENDED_MESSAGE), \
scsi_msgbyte_name(SAVE_POINTERS), \
scsi_msgbyte_name(RESTORE_POINTERS), \
scsi_msgbyte_name(DISCONNECT), \
scsi_msgbyte_name(INITIATOR_ERROR), \
scsi_msgbyte_name(ABORT_TASK_SET), \
scsi_msgbyte_name(MESSAGE_REJECT), \
scsi_msgbyte_name(NOP), \
scsi_msgbyte_name(MSG_PARITY_ERROR), \
scsi_msgbyte_name(LINKED_CMD_COMPLETE), \
scsi_msgbyte_name(LINKED_FLG_CMD_COMPLETE), \
scsi_msgbyte_name(TARGET_RESET), \
scsi_msgbyte_name(ABORT_TASK), \
scsi_msgbyte_name(CLEAR_TASK_SET), \
scsi_msgbyte_name(INITIATE_RECOVERY), \
scsi_msgbyte_name(RELEASE_RECOVERY), \
scsi_msgbyte_name(CLEAR_ACA), \
scsi_msgbyte_name(LOGICAL_UNIT_RESET), \
scsi_msgbyte_name(SIMPLE_QUEUE_TAG), \
scsi_msgbyte_name(HEAD_OF_QUEUE_TAG), \
scsi_msgbyte_name(ORDERED_QUEUE_TAG), \
scsi_msgbyte_name(IGNORE_WIDE_RESIDUE), \
scsi_msgbyte_name(ACA), \
scsi_msgbyte_name(QAS_REQUEST), \
scsi_msgbyte_name(BUS_DEVICE_RESET), \
scsi_msgbyte_name(ABORT))
#define scsi_statusbyte_name(result) { result, #result } #define scsi_statusbyte_name(result) { result, #result }
#define show_statusbyte_name(val) \ #define show_statusbyte_name(val) \
__print_symbolic(val, \ __print_symbolic(val, \
@ -327,9 +283,9 @@ DECLARE_EVENT_CLASS(scsi_cmd_done_timeout_template,
show_opcode_name(__entry->opcode), show_opcode_name(__entry->opcode),
__parse_cdb(__get_dynamic_array(cmnd), __entry->cmd_len), __parse_cdb(__get_dynamic_array(cmnd), __entry->cmd_len),
__print_hex(__get_dynamic_array(cmnd), __entry->cmd_len), __print_hex(__get_dynamic_array(cmnd), __entry->cmd_len),
show_driverbyte_name(((__entry->result) >> 24) & 0xff), "DRIVER_OK",
show_hostbyte_name(((__entry->result) >> 16) & 0xff), show_hostbyte_name(((__entry->result) >> 16) & 0xff),
show_msgbyte_name(((__entry->result) >> 8) & 0xff), "COMMAND_COMPLETE",
show_statusbyte_name(__entry->result & 0xff)) show_statusbyte_name(__entry->result & 0xff))
); );