scsi: ncr53c8xx: Use SAM status values
Use SAM status values instead of the driver-defined ones. This also fixes a potential bug as the driver-defined values declare 'COMMAND TERMINATED' with a value of 0x20, whereas SCSI-II defines it with a value of 0x22. Link: https://lore.kernel.org/r/20210113090500.129644-36-hare@suse.de Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Hannes Reinecke <hare@suse.de> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
parent
aced5500ec
commit
491152c7c3
@ -148,6 +148,11 @@ static int ncr_debug = SCSI_NCR_DEBUG_FLAGS;
|
|||||||
#define DEBUG_FLAGS SCSI_NCR_DEBUG_FLAGS
|
#define DEBUG_FLAGS SCSI_NCR_DEBUG_FLAGS
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Locally used status flag
|
||||||
|
*/
|
||||||
|
#define SAM_STAT_ILLEGAL 0xff
|
||||||
|
|
||||||
static inline struct list_head *ncr_list_pop(struct list_head *head)
|
static inline struct list_head *ncr_list_pop(struct list_head *head)
|
||||||
{
|
{
|
||||||
if (!list_empty(head)) {
|
if (!list_empty(head)) {
|
||||||
@ -998,8 +1003,6 @@ typedef u32 tagmap_t;
|
|||||||
** Other definitions
|
** Other definitions
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define ScsiResult(host_code, scsi_code) (((host_code) << 16) + ((scsi_code) & 0x7f))
|
|
||||||
|
|
||||||
#define initverbose (driver_setup.verbose)
|
#define initverbose (driver_setup.verbose)
|
||||||
#define bootverbose (np->verbose)
|
#define bootverbose (np->verbose)
|
||||||
|
|
||||||
@ -2430,7 +2433,7 @@ static struct script script0 __initdata = {
|
|||||||
*/
|
*/
|
||||||
SCR_FROM_REG (SS_REG),
|
SCR_FROM_REG (SS_REG),
|
||||||
0,
|
0,
|
||||||
SCR_CALL ^ IFFALSE (DATA (S_GOOD)),
|
SCR_CALL ^ IFFALSE (DATA (SAM_STAT_GOOD)),
|
||||||
PADDRH (bad_status),
|
PADDRH (bad_status),
|
||||||
|
|
||||||
#ifndef SCSI_NCR_CCB_DONE_SUPPORT
|
#ifndef SCSI_NCR_CCB_DONE_SUPPORT
|
||||||
@ -2879,7 +2882,7 @@ static struct scripth scripth0 __initdata = {
|
|||||||
8,
|
8,
|
||||||
SCR_TO_REG (HS_REG),
|
SCR_TO_REG (HS_REG),
|
||||||
0,
|
0,
|
||||||
SCR_LOAD_REG (SS_REG, S_GOOD),
|
SCR_LOAD_REG (SS_REG, SAM_STAT_GOOD),
|
||||||
0,
|
0,
|
||||||
SCR_JUMP,
|
SCR_JUMP,
|
||||||
PADDR (cleanup_ok),
|
PADDR (cleanup_ok),
|
||||||
@ -3341,15 +3344,15 @@ static struct scripth scripth0 __initdata = {
|
|||||||
PADDRH (reset),
|
PADDRH (reset),
|
||||||
}/*-------------------------< BAD_STATUS >-----------------*/,{
|
}/*-------------------------< BAD_STATUS >-----------------*/,{
|
||||||
/*
|
/*
|
||||||
** If command resulted in either QUEUE FULL,
|
** If command resulted in either TASK_SET FULL,
|
||||||
** CHECK CONDITION or COMMAND TERMINATED,
|
** CHECK CONDITION or COMMAND TERMINATED,
|
||||||
** call the C code.
|
** call the C code.
|
||||||
*/
|
*/
|
||||||
SCR_INT ^ IFTRUE (DATA (S_QUEUE_FULL)),
|
SCR_INT ^ IFTRUE (DATA (SAM_STAT_TASK_SET_FULL)),
|
||||||
SIR_BAD_STATUS,
|
SIR_BAD_STATUS,
|
||||||
SCR_INT ^ IFTRUE (DATA (S_CHECK_COND)),
|
SCR_INT ^ IFTRUE (DATA (SAM_STAT_CHECK_CONDITION)),
|
||||||
SIR_BAD_STATUS,
|
SIR_BAD_STATUS,
|
||||||
SCR_INT ^ IFTRUE (DATA (S_TERMINATED)),
|
SCR_INT ^ IFTRUE (DATA (SAM_STAT_COMMAND_TERMINATED)),
|
||||||
SIR_BAD_STATUS,
|
SIR_BAD_STATUS,
|
||||||
SCR_RETURN,
|
SCR_RETURN,
|
||||||
0,
|
0,
|
||||||
@ -4371,7 +4374,7 @@ static int ncr_queue_command (struct ncb *np, struct scsi_cmnd *cmd)
|
|||||||
*/
|
*/
|
||||||
cp->actualquirks = 0;
|
cp->actualquirks = 0;
|
||||||
cp->host_status = cp->nego_status ? HS_NEGOTIATE : HS_BUSY;
|
cp->host_status = cp->nego_status ? HS_NEGOTIATE : HS_BUSY;
|
||||||
cp->scsi_status = S_ILLEGAL;
|
cp->scsi_status = SAM_STAT_ILLEGAL;
|
||||||
cp->parity_status = 0;
|
cp->parity_status = 0;
|
||||||
|
|
||||||
cp->xerr_status = XE_OK;
|
cp->xerr_status = XE_OK;
|
||||||
@ -4602,7 +4605,7 @@ static int ncr_reset_bus (struct ncb *np, struct scsi_cmnd *cmd, int sync_reset)
|
|||||||
* in order to keep it alive.
|
* in order to keep it alive.
|
||||||
*/
|
*/
|
||||||
if (!found && sync_reset && !retrieve_from_waiting_list(0, np, cmd)) {
|
if (!found && sync_reset && !retrieve_from_waiting_list(0, np, cmd)) {
|
||||||
cmd->result = DID_RESET << 16;
|
set_host_byte(cmd, DID_RESET);
|
||||||
ncr_queue_done_cmd(np, cmd);
|
ncr_queue_done_cmd(np, cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4630,7 +4633,7 @@ static int ncr_abort_command (struct ncb *np, struct scsi_cmnd *cmd)
|
|||||||
* First, look for the scsi command in the waiting list
|
* First, look for the scsi command in the waiting list
|
||||||
*/
|
*/
|
||||||
if (remove_from_waiting_list(np, cmd)) {
|
if (remove_from_waiting_list(np, cmd)) {
|
||||||
cmd->result = ScsiResult(DID_ABORT, 0);
|
set_host_byte(cmd, DID_ABORT);
|
||||||
ncr_queue_done_cmd(np, cmd);
|
ncr_queue_done_cmd(np, cmd);
|
||||||
return SCSI_ABORT_SUCCESS;
|
return SCSI_ABORT_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -4895,7 +4898,8 @@ void ncr_complete (struct ncb *np, struct ccb *cp)
|
|||||||
** Print out any error for debugging purpose.
|
** Print out any error for debugging purpose.
|
||||||
*/
|
*/
|
||||||
if (DEBUG_FLAGS & (DEBUG_RESULT|DEBUG_TINY)) {
|
if (DEBUG_FLAGS & (DEBUG_RESULT|DEBUG_TINY)) {
|
||||||
if (cp->host_status!=HS_COMPLETE || cp->scsi_status!=S_GOOD) {
|
if (cp->host_status != HS_COMPLETE ||
|
||||||
|
cp->scsi_status != SAM_STAT_GOOD) {
|
||||||
PRINT_ADDR(cmd, "ERROR: cmd=%x host_status=%x "
|
PRINT_ADDR(cmd, "ERROR: cmd=%x host_status=%x "
|
||||||
"scsi_status=%x\n", cmd->cmnd[0],
|
"scsi_status=%x\n", cmd->cmnd[0],
|
||||||
cp->host_status, cp->scsi_status);
|
cp->host_status, cp->scsi_status);
|
||||||
@ -4905,15 +4909,16 @@ void ncr_complete (struct ncb *np, struct ccb *cp)
|
|||||||
/*
|
/*
|
||||||
** Check the status.
|
** Check the status.
|
||||||
*/
|
*/
|
||||||
|
cmd->result = 0;
|
||||||
if ( (cp->host_status == HS_COMPLETE)
|
if ( (cp->host_status == HS_COMPLETE)
|
||||||
&& (cp->scsi_status == S_GOOD ||
|
&& (cp->scsi_status == SAM_STAT_GOOD ||
|
||||||
cp->scsi_status == S_COND_MET)) {
|
cp->scsi_status == SAM_STAT_CONDITION_MET)) {
|
||||||
/*
|
/*
|
||||||
* All went well (GOOD status).
|
* All went well (GOOD status).
|
||||||
* CONDITION MET status is returned on
|
* CONDITION MET status is returned on
|
||||||
* `Pre-Fetch' or `Search data' success.
|
* `Pre-Fetch' or `Search data' success.
|
||||||
*/
|
*/
|
||||||
cmd->result = ScsiResult(DID_OK, cp->scsi_status);
|
set_status_byte(cmd, cp->scsi_status);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** @RESID@
|
** @RESID@
|
||||||
@ -4944,11 +4949,11 @@ void ncr_complete (struct ncb *np, struct ccb *cp)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if ((cp->host_status == HS_COMPLETE)
|
} else if ((cp->host_status == HS_COMPLETE)
|
||||||
&& (cp->scsi_status == S_CHECK_COND)) {
|
&& (cp->scsi_status == SAM_STAT_CHECK_CONDITION)) {
|
||||||
/*
|
/*
|
||||||
** Check condition code
|
** Check condition code
|
||||||
*/
|
*/
|
||||||
cmd->result = DID_OK << 16 | S_CHECK_COND;
|
set_status_byte(cmd, SAM_STAT_CHECK_CONDITION);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Copy back sense data to caller's buffer.
|
** Copy back sense data to caller's buffer.
|
||||||
@ -4965,20 +4970,20 @@ void ncr_complete (struct ncb *np, struct ccb *cp)
|
|||||||
printk (".\n");
|
printk (".\n");
|
||||||
}
|
}
|
||||||
} else if ((cp->host_status == HS_COMPLETE)
|
} else if ((cp->host_status == HS_COMPLETE)
|
||||||
&& (cp->scsi_status == S_CONFLICT)) {
|
&& (cp->scsi_status == SAM_STAT_RESERVATION_CONFLICT)) {
|
||||||
/*
|
/*
|
||||||
** Reservation Conflict condition code
|
** Reservation Conflict condition code
|
||||||
*/
|
*/
|
||||||
cmd->result = DID_OK << 16 | S_CONFLICT;
|
set_status_byte(cmd, SAM_STAT_RESERVATION_CONFLICT);
|
||||||
|
|
||||||
} else if ((cp->host_status == HS_COMPLETE)
|
} else if ((cp->host_status == HS_COMPLETE)
|
||||||
&& (cp->scsi_status == S_BUSY ||
|
&& (cp->scsi_status == SAM_STAT_BUSY ||
|
||||||
cp->scsi_status == S_QUEUE_FULL)) {
|
cp->scsi_status == SAM_STAT_TASK_SET_FULL)) {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Target is busy.
|
** Target is busy.
|
||||||
*/
|
*/
|
||||||
cmd->result = ScsiResult(DID_OK, cp->scsi_status);
|
set_status_byte(cmd, cp->scsi_status);
|
||||||
|
|
||||||
} else if ((cp->host_status == HS_SEL_TIMEOUT)
|
} else if ((cp->host_status == HS_SEL_TIMEOUT)
|
||||||
|| (cp->host_status == HS_TIMEOUT)) {
|
|| (cp->host_status == HS_TIMEOUT)) {
|
||||||
@ -4986,21 +4991,24 @@ void ncr_complete (struct ncb *np, struct ccb *cp)
|
|||||||
/*
|
/*
|
||||||
** No response
|
** No response
|
||||||
*/
|
*/
|
||||||
cmd->result = ScsiResult(DID_TIME_OUT, cp->scsi_status);
|
set_status_byte(cmd, cp->scsi_status);
|
||||||
|
set_host_byte(cmd, DID_TIME_OUT);
|
||||||
|
|
||||||
} else if (cp->host_status == HS_RESET) {
|
} else if (cp->host_status == HS_RESET) {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** SCSI bus reset
|
** SCSI bus reset
|
||||||
*/
|
*/
|
||||||
cmd->result = ScsiResult(DID_RESET, cp->scsi_status);
|
set_status_byte(cmd, sp->scsi_status);
|
||||||
|
set_host_byte(cmd, DID_RESET);
|
||||||
|
|
||||||
} else if (cp->host_status == HS_ABORTED) {
|
} else if (cp->host_status == HS_ABORTED) {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Transfer aborted
|
** Transfer aborted
|
||||||
*/
|
*/
|
||||||
cmd->result = ScsiResult(DID_ABORT, cp->scsi_status);
|
set_status_byte(cmd, cp->scsi_status);
|
||||||
|
set_host_byte(cmd, DID_ABORT);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
@ -5010,7 +5018,8 @@ void ncr_complete (struct ncb *np, struct ccb *cp)
|
|||||||
PRINT_ADDR(cmd, "COMMAND FAILED (%x %x) @%p.\n",
|
PRINT_ADDR(cmd, "COMMAND FAILED (%x %x) @%p.\n",
|
||||||
cp->host_status, cp->scsi_status, cp);
|
cp->host_status, cp->scsi_status, cp);
|
||||||
|
|
||||||
cmd->result = ScsiResult(DID_ERROR, cp->scsi_status);
|
set_status_byte(cmd, cp->scsi_status);
|
||||||
|
set_host_byte(cmd, DID_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -5026,10 +5035,10 @@ void ncr_complete (struct ncb *np, struct ccb *cp)
|
|||||||
|
|
||||||
if (cp->host_status==HS_COMPLETE) {
|
if (cp->host_status==HS_COMPLETE) {
|
||||||
switch (cp->scsi_status) {
|
switch (cp->scsi_status) {
|
||||||
case S_GOOD:
|
case SAM_STAT_GOOD:
|
||||||
printk (" GOOD");
|
printk (" GOOD");
|
||||||
break;
|
break;
|
||||||
case S_CHECK_COND:
|
case SAM_STAT_CHECK_CONDITION:
|
||||||
printk (" SENSE:");
|
printk (" SENSE:");
|
||||||
p = (u_char*) &cmd->sense_buffer;
|
p = (u_char*) &cmd->sense_buffer;
|
||||||
for (i=0; i<14; i++)
|
for (i=0; i<14; i++)
|
||||||
@ -6564,7 +6573,7 @@ static void ncr_sir_to_redo(struct ncb *np, int num, struct ccb *cp)
|
|||||||
|
|
||||||
switch(s_status) {
|
switch(s_status) {
|
||||||
default: /* Just for safety, should never happen */
|
default: /* Just for safety, should never happen */
|
||||||
case S_QUEUE_FULL:
|
case SAM_STAT_TASK_SET_FULL:
|
||||||
/*
|
/*
|
||||||
** Decrease number of tags to the number of
|
** Decrease number of tags to the number of
|
||||||
** disconnected commands.
|
** disconnected commands.
|
||||||
@ -6588,15 +6597,15 @@ static void ncr_sir_to_redo(struct ncb *np, int num, struct ccb *cp)
|
|||||||
*/
|
*/
|
||||||
cp->phys.header.savep = cp->startp;
|
cp->phys.header.savep = cp->startp;
|
||||||
cp->host_status = HS_BUSY;
|
cp->host_status = HS_BUSY;
|
||||||
cp->scsi_status = S_ILLEGAL;
|
cp->scsi_status = SAM_STAT_ILLEGAL;
|
||||||
|
|
||||||
ncr_put_start_queue(np, cp);
|
ncr_put_start_queue(np, cp);
|
||||||
if (disc_cnt)
|
if (disc_cnt)
|
||||||
INB (nc_ctest2); /* Clear SIGP */
|
INB (nc_ctest2); /* Clear SIGP */
|
||||||
OUTL_DSP (NCB_SCRIPT_PHYS (np, reselect));
|
OUTL_DSP (NCB_SCRIPT_PHYS (np, reselect));
|
||||||
return;
|
return;
|
||||||
case S_TERMINATED:
|
case SAM_STAT_COMMAND_TERMINATED:
|
||||||
case S_CHECK_COND:
|
case SAM_STAT_CHECK_CONDIION:
|
||||||
/*
|
/*
|
||||||
** If we were requesting sense, give up.
|
** If we were requesting sense, give up.
|
||||||
*/
|
*/
|
||||||
@ -6646,7 +6655,7 @@ static void ncr_sir_to_redo(struct ncb *np, int num, struct ccb *cp)
|
|||||||
cp->phys.header.wlastp = startp;
|
cp->phys.header.wlastp = startp;
|
||||||
|
|
||||||
cp->host_status = HS_BUSY;
|
cp->host_status = HS_BUSY;
|
||||||
cp->scsi_status = S_ILLEGAL;
|
cp->scsi_status = SAM_STAT_ILLEGAL;
|
||||||
cp->auto_sense = s_status;
|
cp->auto_sense = s_status;
|
||||||
|
|
||||||
cp->start.schedule.l_paddr =
|
cp->start.schedule.l_paddr =
|
||||||
@ -8035,7 +8044,7 @@ printk("ncr53c8xx_queue_command\n");
|
|||||||
spin_lock_irqsave(&np->smp_lock, flags);
|
spin_lock_irqsave(&np->smp_lock, flags);
|
||||||
|
|
||||||
if ((sts = ncr_queue_command(np, cmd)) != DID_OK) {
|
if ((sts = ncr_queue_command(np, cmd)) != DID_OK) {
|
||||||
cmd->result = sts << 16;
|
set_host_byte(cmd, sts;
|
||||||
#ifdef DEBUG_NCR53C8XX
|
#ifdef DEBUG_NCR53C8XX
|
||||||
printk("ncr53c8xx : command not queued - result=%d\n", sts);
|
printk("ncr53c8xx : command not queued - result=%d\n", sts);
|
||||||
#endif
|
#endif
|
||||||
@ -8226,7 +8235,7 @@ static void process_waiting_list(struct ncb *np, int sts)
|
|||||||
#ifdef DEBUG_WAITING_LIST
|
#ifdef DEBUG_WAITING_LIST
|
||||||
printk("%s: cmd %lx done forced sts=%d\n", ncr_name(np), (u_long) wcmd, sts);
|
printk("%s: cmd %lx done forced sts=%d\n", ncr_name(np), (u_long) wcmd, sts);
|
||||||
#endif
|
#endif
|
||||||
wcmd->result = sts << 16;
|
set_host_byte(wcmd, sts);
|
||||||
ncr_queue_done_cmd(np, wcmd);
|
ncr_queue_done_cmd(np, wcmd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1238,22 +1238,6 @@ struct scr_tblsel {
|
|||||||
**-----------------------------------------------------------
|
**-----------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
|
||||||
** Status
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define S_GOOD (0x00)
|
|
||||||
#define S_CHECK_COND (0x02)
|
|
||||||
#define S_COND_MET (0x04)
|
|
||||||
#define S_BUSY (0x08)
|
|
||||||
#define S_INT (0x10)
|
|
||||||
#define S_INT_COND_MET (0x14)
|
|
||||||
#define S_CONFLICT (0x18)
|
|
||||||
#define S_TERMINATED (0x20)
|
|
||||||
#define S_QUEUE_FULL (0x28)
|
|
||||||
#define S_ILLEGAL (0xff)
|
|
||||||
#define S_SENSE (0x80)
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* End of ncrreg from FreeBSD
|
* End of ncrreg from FreeBSD
|
||||||
*/
|
*/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user