Commit d9883b01 authored by Guennadi Liakhovetski's avatar Guennadi Liakhovetski Committed by James Bottomley

[PATCH] tmscsim: no internal queue

Here comes the 2nd one. I wanted to get Christoph's patches now in, but
already the first his patch comes on the top of this one: remove internal
command queuing in the driver. And, in fact, it fixes some bugs in it. So,
they should go in together. Here's the original comment from Christoph's
email of 1 Feb 2004:

<start quote>

Patch looks mostly good for me.  But there's some fishyness in queuecommand,
mostly from before you patch:

 - many failure cases return one with the new EH code although we wouldn't
   want to requeue the midlayer in that case.  I removed the ifdef and added
   a failed goto to handle them.
 - we need to set cmd->result onlyh if we have an error instead of always
   an overriding it - else it will leak to the midlayer in the return 1
   case.
 - the check for ids out of range are superflous (this was one of the errors
   above, I decided to remove it instead of fixing it).
 - you don't do DC390_UNLOCK_ACB when failing.  While it's a noop I think
   it's bad to have locking macros in place and don't balance them.  You
   should probably remove it completly in one of the next patches.
 - the pDCB->pWaitingSRB looks a bit strange.  By unifying the the codepathes
   it becomes much more readable.

<end quote>
parent aec4b22a
......@@ -1152,7 +1152,6 @@ dc390_Disconnect( PACB pACB )
pSRB = psrb;
}
pDCB->pGoingSRB = 0;
dc390_Query_to_Waiting (pACB);
dc390_Waiting_process (pACB);
}
else
......@@ -1634,7 +1633,6 @@ dc390_SRBdone( PACB pACB, PDCB pDCB, PSRB pSRB )
pcmd->scsi_done (pcmd);
DC390_LOCK_ACB_NI;
dc390_Query_to_Waiting (pACB);
dc390_Waiting_process (pACB);
return;
}
......@@ -1681,7 +1679,6 @@ dc390_DoingSRB_Done( PACB pACB, PSCSICMD cmd )
pdcb->TagMask = 0;
pdcb = pdcb->pNextDCB;
} while( pdcb != pDCB );
dc390_Query_to_Waiting (pACB);
}
......
......@@ -169,6 +169,9 @@
* use the current PCI-mapping API, update *
* command-queuing. *
* 2.1b 04/04/13 GL Fix for 64-bit platforms *
* 2.1b1 04/01/31 GL (applied 05.04) Remove internal *
* command-queuing. *
* 2.1b2 04/02/01 CH (applied 05.04) Fix error-handling *
***********************************************************************/
/* Uncomment SA_INTERRUPT, if the driver refuses to share its IRQ with other devices */
......@@ -752,37 +755,6 @@ static PSRB dc390_find_cmd_in_SRBq (PSCSICMD cmd, PSRB queue)
return q;
}
#endif
/* Append to Query List */
static void dc390_Query_append( PSCSICMD cmd, PACB pACB )
{
dc390_cmd_scp_t *cmdq = (dc390_cmd_scp_t *)&cmd->SCp;
DEBUG0(printk ("DC390: Append cmd %li to Query\n", cmd->pid));
list_add_tail(&cmdq->list, &pACB->cmdq);
pACB->QueryCnt++;
pACB->CmdOutOfSRB++;
}
/* Return next cmd from Query list */
static PSCSICMD dc390_Query_get ( PACB pACB )
{
PSCSICMD pcmd;
dc390_cmd_scp_t *cmdq;
if (list_empty(&pACB->cmdq))
return NULL;
pcmd = (PSCSICMD) list_entry(pACB->cmdq.next, struct scsi_cmnd_list, scp.list);
DEBUG0(printk ("DC390: Get cmd %li from Query\n", pcmd->pid));
cmdq = (dc390_cmd_scp_t *)&pcmd->SCp;
list_del(&cmdq->list);
pACB->QueryCnt--;
return pcmd;
}
/* Return next free SRB */
static __inline__ PSRB dc390_Free_get ( PACB pACB )
......@@ -1114,37 +1086,6 @@ static void dc390_BuildSRB (Scsi_Cmnd* pcmd, PDCB pDCB, PSRB pSRB)
/* KG: deferred PCI mapping to dc390_StartSCSI */
}
/* Put cmnd from Query to Waiting list and send next Waiting cmnd */
static void dc390_Query_to_Waiting (PACB pACB)
{
Scsi_Cmnd *pcmd;
PSRB pSRB;
PDCB pDCB;
if( pACB->ACBFlag & (RESET_DETECT+RESET_DONE+RESET_DEV) )
return;
while (pACB->QueryCnt)
{
pSRB = dc390_Free_get ( pACB );
if (!pSRB) return;
pcmd = dc390_Query_get ( pACB );
if (!pcmd) { dc390_Free_insert (pACB, pSRB); return; } /* should not happen */
pDCB = dc390_findDCB (pACB, pcmd->device->id, pcmd->device->lun);
if (!pDCB)
{
dc390_Free_insert (pACB, pSRB);
printk (KERN_ERR "DC390: Command in queue to non-existing device!\n");
pcmd->result = MK_RES(DRIVER_ERROR,DID_ERROR,0,0);
DC390_UNLOCK_ACB_NI;
pcmd->done (pcmd);
DC390_LOCK_ACB_NI;
}
dc390_BuildSRB (pcmd, pDCB, pSRB);
dc390_Waiting_append ( pDCB, pSRB );
}
}
/***********************************************************************
* Function : static int DC390_queue_command (Scsi_Cmnd *cmd,
* void (*done)(Scsi_Cmnd *))
......@@ -1177,10 +1118,7 @@ int DC390_queue_command (Scsi_Cmnd *cmd, void (* done)(Scsi_Cmnd *))
cmd->cmnd[0],cmd->device->id,cmd->device->lun,cmd->pid, cmd->buffer));
DC390_LOCK_ACB;
/* Assume BAD_TARGET; will be cleared later */
cmd->result = DID_BAD_TARGET << 16;
/* TODO: Change the policy: Always accept TEST_UNIT_READY or INQUIRY
* commands and alloc a DCB for the device if not yet there. DCB will
* be removed in dc390_SRBdone if SEL_TIMEOUT */
......@@ -1191,17 +1129,6 @@ int DC390_queue_command (Scsi_Cmnd *cmd, void (* done)(Scsi_Cmnd *))
else if( (pACB->scan_devices) && (cmd->cmnd[0] == READ_6) )
pACB->scan_devices = 0;
if ( ( cmd->device->id >= pACB->pScsiHost->max_id ) ||
(cmd->device->lun >= pACB->pScsiHost->max_lun) )
{
/* printk ("DC390: Ignore target %d lun %d\n",
cmd->device->id, cmd->device->lun); */
DC390_UNLOCK_ACB;
//return (1);
done (cmd);
return (0);
}
if( (pACB->scan_devices || cmd->cmnd[0] == TEST_UNIT_READY || cmd->cmnd[0] == INQUIRY) &&
!(pACB->DCBmap[cmd->device->id] & (1 << cmd->device->lun)) )
{
......@@ -1212,14 +1139,7 @@ int DC390_queue_command (Scsi_Cmnd *cmd, void (* done)(Scsi_Cmnd *))
{
printk (KERN_ERR "DC390: kmalloc for DCB failed, target %02x lun %02x\n",
cmd->device->id, cmd->device->lun);
DC390_UNLOCK_ACB;
printk ("DC390: No DCB in queue_command!\n");
#ifdef USE_NEW_EH
return (1);
#else
done (cmd);
return (0);
#endif
goto fail;
}
}
......@@ -1227,10 +1147,7 @@ int DC390_queue_command (Scsi_Cmnd *cmd, void (* done)(Scsi_Cmnd *))
{
printk(KERN_INFO "DC390: Ignore target %02x lun %02x\n",
cmd->device->id, cmd->device->lun);
DC390_UNLOCK_ACB;
//return (1);
done (cmd);
return (0);
goto fail;
}
else
{
......@@ -1239,60 +1156,37 @@ int DC390_queue_command (Scsi_Cmnd *cmd, void (* done)(Scsi_Cmnd *))
{ /* should never happen */
printk (KERN_ERR "DC390: no DCB failed, target %02x lun %02x\n",
cmd->device->id, cmd->device->lun);
DC390_UNLOCK_ACB;
printk ("DC390: No DCB in queuecommand (2)!\n");
#ifdef USE_NEW_EH
return (1);
#else
done (cmd);
return (0);
#endif
goto fail;
}
}
pACB->Cmds++;
cmd->scsi_done = done;
cmd->result = 0;
dc390_Query_to_Waiting (pACB);
if( pACB->QueryCnt ) /* Unsent commands ? */
{
DEBUG0(printk ("DC390: QueryCnt != 0\n"));
dc390_Query_append ( cmd, pACB );
dc390_Waiting_process (pACB);
}
else if (pDCB->pWaitingSRB)
{
pSRB = dc390_Free_get ( pACB );
DEBUG0(if (!pSRB) printk ("DC390: No free SRB but Waiting\n"); else printk ("DC390: Free SRB w/ Waiting\n"));
if (!pSRB) dc390_Query_append (cmd, pACB);
else
{
dc390_BuildSRB (cmd, pDCB, pSRB);
dc390_Waiting_append (pDCB, pSRB);
}
dc390_Waiting_process (pACB);
}
else
{
pSRB = dc390_Free_get ( pACB );
DEBUG0(if (!pSRB) printk ("DC390: No free SRB w/o Waiting\n"); else printk ("DC390: Free SRB w/o Waiting\n"));
if (!pSRB)
{
dc390_Query_append (cmd, pACB);
dc390_Waiting_process (pACB);
}
else
{
dc390_BuildSRB (cmd, pDCB, pSRB);
dc390_SendSRB (pACB, pSRB);
}
}
pSRB = dc390_Free_get(pACB);
if (!pSRB)
goto requeue;
dc390_BuildSRB(cmd, pDCB, pSRB);
if (pDCB->pWaitingSRB) {
dc390_Waiting_append(pDCB, pSRB);
dc390_Waiting_process(pACB);
} else
dc390_SendSRB(pACB, pSRB);
DC390_UNLOCK_ACB;
DEBUG1(printk (KERN_DEBUG " ... command (pid %li) queued successfully.\n", cmd->pid));
return(0);
requeue:
DC390_UNLOCK_ACB;
return 1;
fail:
DC390_UNLOCK_ACB;
cmd->result = DID_BAD_TARGET << 16;
done(cmd);
return 0;
}
/* We ignore mapping problems, as we expect everybody to respect
......@@ -1499,21 +1393,6 @@ int DC390_abort (Scsi_Cmnd *cmd)
printk ("DC390: Abort command (pid %li, Device %02i-%02i)\n",
cmd->pid, cmd->device->id, cmd->device->lun);
/* First scan Query list */
if( pACB->QueryCnt )
{
struct scsi_cmnd_list *t, *pcmd_l;
list_for_each_entry_safe(pcmd_l, t, &pACB->cmdq, scp.list)
if( (struct scsi_cmnd*)pcmd_l == cmd )
{
/* Found: Dequeue */
list_del(&pcmd_l->scp.list);
pACB->QueryCnt--;
status = SCSI_ABORT_SUCCESS;
goto ABO_X;
}
}
pDCB = dc390_findDCB (pACB, cmd->device->id, cmd->device->lun);
if( !pDCB ) goto NOT_RUN;
......@@ -1971,8 +1850,6 @@ void __init dc390_initACB (PSH psh, ULONG io_port, UCHAR Irq, UCHAR index)
pACB->pActiveDCB = NULL;
pACB->pFreeSRB = pACB->SRB_array;
pACB->SRBCount = MAX_SRB_CNT;
pACB->QueryCnt = 0;
INIT_LIST_HEAD(&pACB->cmdq);
pACB->AdapterIndex = index;
pACB->status = 0;
psh->this_id = dc390_eepromBuf[index][EE_ADAPT_SCSI_ID];
......@@ -2772,7 +2649,6 @@ int DC390_proc_info (struct Scsi_Host *shpnt, char *buffer, char **start,
{
int dev, spd, spd1;
char *pos = buffer;
struct scsi_cmnd_list *cl;
PACB pACB;
PDCB pDCB;
DC390_AFLAGS;
......@@ -2843,9 +2719,6 @@ int DC390_proc_info (struct Scsi_Host *shpnt, char *buffer, char **start,
SPRINTF (" %02i\n", pDCB->MaxCommand);
pDCB = pDCB->pNextDCB;
}
SPRINTF ("Commands in Queues: Query: %li:", pACB->QueryCnt);
list_for_each_entry(cl, &pACB->cmdq, scp.list)
SPRINTF (" %li", ((struct scsi_cmnd*)cl)->pid);
if (timer_pending(&pACB->Waiting_Timer)) SPRINTF ("Waiting queue timer running\n");
else SPRINTF ("\n");
pDCB = pACB->pLinkDCB;
......
......@@ -214,16 +214,12 @@ PSRB pFreeSRB;
PSRB pTmpSRB;
/* 0x2c: */
ULONG QueryCnt;
struct list_head cmdq;
/* 0x38: */
UCHAR msgin123[4];
UCHAR DCBmap[MAX_SCSI_ID];
UCHAR Connected;
UCHAR pad;
/* 0x3c: */
/* 0x30: */
#if defined(USE_SPINLOCKS) && USE_SPINLOCKS > 1 && (defined(CONFIG_SMP) || DEBUG_SPINLOCKS > 0)
spinlock_t lock;
#endif
......@@ -234,20 +230,20 @@ UCHAR MsgLen;
UCHAR Ignore_IRQ; /* Not used */
PDEVDECL1; /* Pointer to PCI cfg. space */
/* 0x4c/0x48: */
/* 0x40/0x3c: */
ULONG Cmds;
UINT SelLost;
UINT SelConn;
UINT CmdInQ;
UINT CmdOutOfSRB;
/* 0x60/0x5c: */
/* 0x54/0x50: */
struct timer_list Waiting_Timer;
/* 0x74/0x70: */
/* 0x68/0x64: */
DC390_SRB TmpSRB;
/* 0xd8/0xd4: */
/* 0xcc/0xc8: */
DC390_SRB SRB_array[MAX_SRB_CNT]; /* 50 SRBs */
/* 0xfb0/0xfac: */
/* 0xfa4/0xfa0: */
};
typedef struct _ACB DC390_ACB, *PACB;
......@@ -406,16 +402,9 @@ typedef struct _ACB DC390_ACB, *PACB;
* SISC query queue
*/
typedef struct {
struct list_head list;
dma_addr_t saved_dma_handle;
} dc390_cmd_scp_t;
struct scsi_cmnd_list
{
char dummy[offsetof(struct scsi_cmnd, SCp)];
dc390_cmd_scp_t scp;
};
/*
** Inquiry Data format
*/
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment