Re: [PATCH] tmscsim: INQUIRY always only untagged

Guennadi Liakhovetski
2004-09-05T14:56:53Z

[-- Attachment #1: Type: TEXT/PLAIN, Size: 917 bytes --]

On Sat, 4 Sep 2004, Christoph Hellwig wrote:

> On Sun, Sep 05, 2004 at 12:26:14AM +0200, Guennadi Liakhovetski wrote:
>> On Sat, 4 Sep 2004, Christoph Hellwig wrote:
>>
>>> On Sat, Sep 04, 2004 at 12:41:00AM +0200, Guennadi Liakhovetski wrote:
>>>> Hello
>>>>
>>>> The attached patch makes sure, all INQUIRY commands are only sent
>>>> untagged. This way drives, affected by bug 2139, also survive further
>>>> INQUIRYs, sent after the initial scan, e.g., by scsiinfo.
>>>
>>> Looks basically good to me, but if you want to store SCSI_NO_TAG in
>>> ->TagNumber I'd suggest that you make it an unsigned type.
>>
>> It is unsigned (u8) now. Or did you mean signed, since SCSI_NO_TAG is
>> defined as (-1). I thought about making TagNumber an int, but I didn't
>> bother, because it is anyway due removal...
>
> Umm, yes signed of course.

Ok, how about the attached version?

Thanks
Guennadi
---
Guennadi Liakhovetski

[-- Attachment #2: Type: TEXT/PLAIN, Size: 5533 bytes --]

INQUIRY always send only untagged.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>

diff -u a/drivers/scsi/scsiiom.c b/drivers/scsi/scsiiom.c
--- a/drivers/scsi/scsiiom.c 17 Aug 2004 21:16:53
+++ b/drivers/scsi/scsiiom.c 5 Sep 2004 11:13:15
@@ -8,9 +8,9 @@
static void __inline__
dc390_freetag (struct dc390_dcb* pDCB, struct dc390_srb* pSRB)
{
- if (pSRB->TagNumber < 255) {
+ if (pSRB->TagNumber != SCSI_NO_TAG) {
pDCB->TagMask &= ~(1 << pSRB->TagNumber); /* free tag mask */
- pSRB->TagNumber = 255;
+ pSRB->TagNumber = SCSI_NO_TAG;
}
}

@@ -67,9 +67,9 @@
pSRB->MsgCnt = 0; cmd = SEL_W_ATN;
DC390_write8 (ScsiFifo, IDENTIFY(disc_allowed, pDCB->TargetLUN));
/* Change 99/05/31: Don't use tags when not disconnecting (BUSY) */
- if ((pDCB->SyncMode & EN_TAG_QUEUEING) && disc_allowed)
+ if ((pDCB->SyncMode & EN_TAG_QUEUEING) && disc_allowed && pSRB->pcmd->cmnd[0] != INQUIRY)
{
- u8 tag_no = 0;
+ int tag_no = 0;
while ((1 << tag_no) & pDCB->TagMask) tag_no++;
if (tag_no >= sizeof (pDCB->TagMask)*8 || tag_no >= pDCB->MaxCommand) {
printk (KERN_WARNING "DC390: Out of tags for Dev. %02x %02x\n", pDCB->TargetID, pDCB->TargetLUN);
@@ -79,7 +79,7 @@
DC390_write8 (ScsiFifo, SIMPLE_QUEUE_TAG);
pDCB->TagMask |= (1 << tag_no); pSRB->TagNumber = tag_no;
DC390_write8 (ScsiFifo, tag_no);
- DEBUG1(printk (KERN_DEBUG "DC390: Select w/DisCn for Cmd %li (SRB %p), Using Tag %02x\n", pSRB->pcmd->pid, pSRB, tag_no));
+ DEBUG1(printk (KERN_DEBUG "DC390: Select w/DisCn for Cmd %li (SRB %p), Using Tag %d\n", pSRB->pcmd->pid, pSRB, tag_no));
cmd = SEL_W_ATN3;
}
else /* No TagQ */
@@ -612,7 +612,7 @@
}

static struct dc390_srb*
-dc390_MsgIn_QTag (struct dc390_acb* pACB, struct dc390_dcb* pDCB, u8 tag)
+dc390_MsgIn_QTag (struct dc390_acb* pACB, struct dc390_dcb* pDCB, int tag)
{
struct dc390_srb* lastSRB = pDCB->pGoingLast;
struct dc390_srb* pSRB = pDCB->pGoingSRB;
@@ -903,18 +903,11 @@
printk(KERN_ERR "DC390: pSRB == pTmpSRB! (TagQ Error?) (%02i-%i)\n", pDCB->TargetID, pDCB->TargetLUN);
else
printk(KERN_ERR "DC390: pSRB == pTmpSRB! (TagQ Error?) (DCB 0!)\n");
-
- /* Try to recover - some broken disks react badly to tagged INQUIRY */
- if (pDCB && pACB->scan_devices && pDCB->GoingSRBCnt == 1) {
- pSRB = pDCB->pGoingSRB;
- pDCB->pActiveSRB = pSRB;
- } else {
- pSRB->pSRBDCB = pDCB;
- dc390_EnableMsgOut_Abort(pACB, pSRB);
- if (pDCB)
- pDCB->DCBFlag |= ABORT_DEV;
- return;
- }
+ pSRB->pSRBDCB = pDCB;
+ dc390_EnableMsgOut_Abort(pACB, pSRB);
+ if (pDCB)
+ pDCB->DCBFlag |= ABORT_DEV;
+ return;
}

if( pSRB->SGIndex < pSRB->SGcount )
@@ -1257,7 +1250,7 @@
}
pACB->pActiveDCB = pDCB;
/* TagQ: We expect a message soon, so never mind the exact SRB */
- if( pDCB->SyncMode & EN_TAG_QUEUEING )
+ if ((pDCB->SyncMode & EN_TAG_QUEUEING) && (!pDCB->pActiveSRB || pDCB->pActiveSRB->TagNumber != SCSI_NO_TAG))
{
pSRB = pACB->pTmpSRB;
pDCB->pActiveSRB = pSRB;
@@ -1288,7 +1281,7 @@
}
}

- DEBUG1(printk (KERN_DEBUG "Resel SRB(%p): TagNum (%02x)\n", pSRB, pSRB->TagNumber));
+ DEBUG1(printk (KERN_DEBUG "Resel SRB(%p): TagNum %d\n", pSRB, pSRB->TagNumber));
pSRB->ScsiPhase = SCSI_NOP0;
DC390_write8 (Scsi_Dest_ID, pDCB->TargetID);
DC390_write8 (Sync_Period, pDCB->SyncPeriod);
diff -u a/drivers/scsi/tmscsim.h b/drivers/scsi/tmscsim.h
--- a/drivers/scsi/tmscsim.h 17 Aug 2004 21:16:53
+++ b/drivers/scsi/tmscsim.h 5 Sep 2004 11:09:27
@@ -44,17 +44,15 @@
struct scsi_cmnd *pcmd;
struct scatterlist *pSegmentList;

-/* 0x10: */
struct scatterlist Segmentx; /* make a one entry of S/G list table */

-/* 0x1c: */
unsigned long SGBusAddr; /*;a segment starting address as seen by AM53C974A*/
unsigned long SGToBeXferLen; /*; to be xfer length */
unsigned long TotalXferredLen;
unsigned long SavedTotXLen;
+int TagNumber;
u32 SRBState;

-/* 0x30: */
u8 SRBStatus;
u8 SRBFlag; /*; b0-AutoReqSense,b6-Read,b7-write */
/*; b4-settimeout,b5-Residual valid */
@@ -62,11 +60,9 @@
u8 TargetStatus;

u8 ScsiPhase;
-u8 TagNumber;
u8 SGIndex;
u8 SGcount;

-/* 0x38: */
u8 MsgCnt;
u8 EndMessage;
u8 RetryCnt;
@@ -74,12 +70,10 @@

unsigned long Saved_Ptr;

-/* 0x40: */
u8 MsgInBuf[6];
u8 MsgOutBuf[6];

//u8 IORBFlag; /*;81h-Reset, 2-retry */
-/* 0x4c: */
};

diff -u a/drivers/scsi/tmscsim.c b/drivers/scsi/tmscsim.c
--- a/drivers/scsi/tmscsim.c 3 Sep 2004 22:10:14
+++ b/drivers/scsi/tmscsim.c 5 Sep 2004 11:14:40
@@ -245,6 +245,7 @@
#include <scsi/scsi_device.h>
#include <scsi/scsi_host.h>
#include <scsi/scsicam.h>
+#include <scsi/scsi_tcq.h>

#define DC390_BANNER "Tekram DC390/AM53C974"
@@ -861,6 +862,10 @@
goto host_busy;
if (acb->ACBFlag & (RESET_DETECT|RESET_DONE|RESET_DEV))
goto host_busy;
+ /* INQUIRY only untagged, do not accept more commands if the going one is untagged, e.g., INQUIRY */
+ if (unlikely((cmd->cmnd[0] == INQUIRY && dcb->pGoingSRB) ||
+ (dcb->pGoingSRB && dcb->pGoingSRB->TagNumber == SCSI_NO_TAG)))
+ goto device_busy;

srb = acb->pFreeSRB;
if (unlikely(srb == NULL))
@@ -892,7 +897,7 @@
srb->SGToBeXferLen = 0;
srb->ScsiPhase = 0;
srb->EndMessage = 0;
- srb->TagNumber = 255;
+ srb->TagNumber = SCSI_NO_TAG;

if (dc390_StartSCSI(acb, dcb, srb)) {
dc390_Waiting_insert(dcb, srb);