aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOlivier Houchard <cognet@FreeBSD.org>2004-12-04 14:41:37 +0000
committerOlivier Houchard <cognet@FreeBSD.org>2004-12-04 14:41:37 +0000
commiteafc0f956f24576d2c9b7fd7a32ca5f4694d50e8 (patch)
tree5436782946c5c31da55a2855c605b6dd36980ca6
parent690cc0d20f58e8115a4c18916b004a9b902b0037 (diff)
downloadsrc-eafc0f956f24576d2c9b7fd7a32ca5f4694d50e8.tar.gz
src-eafc0f956f24576d2c9b7fd7a32ca5f4694d50e8.zip
MFC the current state of the trm(4) driver. It notably adds support for the
DC395U2W adapters, and should fix panics/hangs under heavy load. Reported and tested by: jmz
Notes
Notes: svn path=/stable/4/; revision=138371
-rw-r--r--sys/dev/trm/trm.c1084
-rw-r--r--sys/dev/trm/trm.h130
2 files changed, 792 insertions, 422 deletions
diff --git a/sys/dev/trm/trm.c b/sys/dev/trm/trm.c
index 75c150c686f3..f105531d44f0 100644
--- a/sys/dev/trm/trm.c
+++ b/sys/dev/trm/trm.c
@@ -1,14 +1,19 @@
/*
- * O.S : FreeBSD CAM
+ * O.S : FreeBSD CAM
* FILE NAME : trm.c
* BY : C.L. Huang (ching@tekram.com.tw)
- * Erich Chen (erich@tekram.com.tw)
- * Description: Device Driver for Tekram DC395U/UW/F ,DC315/U
- * PCI SCSI Bus Master Host Adapter
- * (SCSI chip set used Tekram ASIC TRM-S1040)
- * (C)Copyright 1995-1999 Tekram Technology Co., Ltd.
+ * Erich Chen (erich@tekram.com.tw)
+ * Description: Device Driver for Tekram SCSI adapters
+ * DC395U/UW/F ,DC315/U(TRM-S1040)
+ * DC395U2D/U2W(TRM-S2080)
+ * PCI SCSI Bus Master Host Adapter
+ * (SCSI chip set used Tekram ASIC TRM-S1040,TRM-S2080)
+ *(C)Copyright 1995-2001 Tekram Technology Co.,Ltd.
*/
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
/*
* HISTORY:
*
@@ -17,6 +22,9 @@
* 1.06 07/29/1999 ERICH CHEN Modify for NEW PCI
* 1.07 12/12/1999 ERICH CHEN Modify for 3.3.x ,DCB no free
* 1.08 06/12/2000 ERICH CHEN Modify for 4.x.x
+ * 1.09 11/03/2000 ERICH CHEN Modify for 4.1.R ,new sim
+ * 1.10 10/10/2001 Oscar Feng Fixed CAM rescan hang up bug.
+ * 1.11 10/13/2001 Oscar Feng Fixed wrong Async speed display bug.
*/
/*
@@ -56,9 +64,6 @@
* <doginou@ci0.org>, 2002-03-04
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include <sys/param.h>
#include <sys/systm.h>
@@ -70,6 +75,7 @@ __FBSDID("$FreeBSD$");
#include <sys/buf.h>
#include <sys/bus.h>
#include <sys/kernel.h>
+#include <sys/module.h>
#include <vm/vm.h>
#include <vm/pmap.h>
@@ -89,6 +95,7 @@ __FBSDID("$FreeBSD$");
#include <cam/cam_debug.h>
#include <cam/scsi/scsi_all.h>
+#include <cam/scsi/scsi_message.h>
#include <dev/trm/trm.h>
@@ -105,6 +112,7 @@ __FBSDID("$FreeBSD$");
#define PCI_Vendor_ID_TEKRAM 0x1DE1
#define PCI_Device_ID_TRM_S1040 0x0391
#define PCI_DEVICEID_TRMS1040 0x03911DE1
+#define PCI_DEVICEID_TRMS2080 0x03921DE1
#ifdef trm_DEBUG1
#define TRM_DPRINTF(fmt, arg...) printf("trm: " fmt, ##arg)
@@ -113,40 +121,40 @@ __FBSDID("$FreeBSD$");
#endif /* TRM_DEBUG */
static void trm_check_eeprom(PNVRAMTYPE pEEpromBuf,PACB pACB);
-static void TRM_read_all(PNVRAMTYPE pEEpromBuf,PACB pACB);
-static u_int8_t TRM_get_data(PACB pACB, u_int8_t bAddr);
-static void TRM_write_all(PNVRAMTYPE pEEpromBuf,PACB pACB);
-static void TRM_set_data(PACB pACB, u_int8_t bAddr, u_int8_t bData);
-static void TRM_write_cmd(PACB pACB, u_int8_t bCmd, u_int8_t bAddr);
-static void TRM_wait_30us(PACB pACB);
+static void NVRAM_trm_read_all(PNVRAMTYPE pEEpromBuf,PACB pACB);
+static u_int8_t NVRAM_trm_get_data(PACB pACB, u_int8_t bAddr);
+static void NVRAM_trm_write_all(PNVRAMTYPE pEEpromBuf,PACB pACB);
+static void NVRAM_trm_set_data(PACB pACB, u_int8_t bAddr, u_int8_t bData);
+static void NVRAM_trm_write_cmd(PACB pACB, u_int8_t bCmd, u_int8_t bAddr);
+static void NVRAM_trm_wait_30us(PACB pACB);
static void trm_Interrupt(void *vpACB);
static void trm_DataOutPhase0(PACB pACB, PSRB pSRB,
- u_int8_t * pscsi_status);
+ u_int16_t * pscsi_status);
static void trm_DataInPhase0(PACB pACB, PSRB pSRB,
- u_int8_t * pscsi_status);
+ u_int16_t * pscsi_status);
static void trm_CommandPhase0(PACB pACB, PSRB pSRB,
- u_int8_t * pscsi_status);
+ u_int16_t * pscsi_status);
static void trm_StatusPhase0(PACB pACB, PSRB pSRB,
- u_int8_t * pscsi_status);
+ u_int16_t * pscsi_status);
static void trm_MsgOutPhase0(PACB pACB, PSRB pSRB,
- u_int8_t * pscsi_status);
+ u_int16_t * pscsi_status);
static void trm_MsgInPhase0(PACB pACB, PSRB pSRB,
- u_int8_t * pscsi_status);
+ u_int16_t * pscsi_status);
static void trm_DataOutPhase1(PACB pACB, PSRB pSRB,
- u_int8_t * pscsi_status);
+ u_int16_t * pscsi_status);
static void trm_DataInPhase1(PACB pACB, PSRB pSRB,
- u_int8_t * pscsi_status);
+ u_int16_t * pscsi_status);
static void trm_CommandPhase1(PACB pACB, PSRB pSRB,
- u_int8_t * pscsi_status);
+ u_int16_t * pscsi_status);
static void trm_StatusPhase1(PACB pACB, PSRB pSRB,
- u_int8_t * pscsi_status);
+ u_int16_t * pscsi_status);
static void trm_MsgOutPhase1(PACB pACB, PSRB pSRB,
- u_int8_t * pscsi_status);
+ u_int16_t * pscsi_status);
static void trm_MsgInPhase1(PACB pACB, PSRB pSRB,
- u_int8_t * pscsi_status);
-static void trm_Nop0(PACB pACB, PSRB pSRB, u_int8_t * pscsi_status);
-static void trm_Nop1(PACB pACB, PSRB pSRB, u_int8_t * pscsi_status);
+ u_int16_t * pscsi_status);
+static void trm_Nop0(PACB pACB, PSRB pSRB, u_int16_t * pscsi_status);
+static void trm_Nop1(PACB pACB, PSRB pSRB, u_int16_t * pscsi_status);
static void trm_SetXferRate(PACB pACB, PSRB pSRB,PDCB pDCB);
static void trm_DataIO_transfer(PACB pACB, PSRB pSRB, u_int16_t ioDir);
static void trm_Disconnect(PACB pACB);
@@ -165,13 +173,11 @@ static void trm_reset(PACB pACB);
static u_int16_t trm_StartSCSI(PACB pACB, PDCB pDCB, PSRB pSRB);
-static int trm_initAdapter(PACB pACB, u_int16_t unit,
- device_t pci_config_id);
+static int trm_initAdapter(PACB pACB, u_int16_t unit);
static void trm_initDCB(PACB pACB, PDCB pDCB, u_int16_t unit,
u_int32_t i, u_int32_t j);
-static void trm_initSRB(PSRB psrb);
-static void trm_linkSRB(PACB pACB);
-static void trm_initACB(PACB pACB, u_int16_t unit);
+static int trm_initSRB(PACB pACB);
+static void trm_initACB(PACB pACB, u_int8_t adaptType, u_int16_t unit);
/* CAM SIM entry points */
#define ccb_trmsrb_ptr spriv_ptr0
#define ccb_trmacb_ptr spriv_ptr1
@@ -207,7 +213,7 @@ static void * trm_SCSI_phase1[] = {
};
-NVRAMTYPE trm_eepromBuf[MAX_ADAPTER_NUM];
+NVRAMTYPE trm_eepromBuf[TRM_MAX_ADAPTER_NUM];
/*
*Fast20: 000 50ns, 20.0 Mbytes/s
* 001 75ns, 13.3 Mbytes/s
@@ -228,7 +234,7 @@ NVRAMTYPE trm_eepromBuf[MAX_ADAPTER_NUM];
* 111 200ns, 5.0 Mbytes/s
*/
/* real period: */
-u_int8_t dc395x_trm_clock_period[] = {
+u_int8_t dc395x_clock_period[] = {
12,/* 48 ns 20 MB/sec */
18,/* 72 ns 13.3 MB/sec */
25,/* 100 ns 10.0 MB/sec */
@@ -239,17 +245,20 @@ u_int8_t dc395x_trm_clock_period[] = {
62 /* 248 ns 4.0 MB/sec */
};
-u_int8_t dc395x_trm_tinfo_sync_period[] = {
- 12,/* 20.0 MB/sec */
- 18,/* 13.3 MB/sec */
- 25,/* 10.0 MB/sec */
- 31,/* 8.0 MB/sec */
- 37,/* 6.6 MB/sec */
- 43,/* 5.7 MB/sec */
- 50,/* 5.0 MB/sec */
- 62,/* 4.0 MB/sec */
+u_int8_t dc395u2x_clock_period[]={
+ 10,/* 25 ns 40.0 MB/sec */
+ 12,/* 48 ns 20.0 MB/sec */
+ 18,/* 72 ns 13.3 MB/sec */
+ 25,/* 100 ns 10.0 MB/sec */
+ 31,/* 124 ns 8.0 MB/sec */
+ 37,/* 148 ns 6.6 MB/sec */
+ 43,/* 172 ns 5.7 MB/sec */
+ 50,/* 200 ns 5.0 MB/sec */
};
+#define dc395x_tinfo_period dc395x_clock_period
+#define dc395u2x_tinfo_period dc395u2x_clock_period
+
static PSRB
trm_GetSRB(PACB pACB)
{
@@ -279,7 +288,7 @@ trm_RewaitSRB0(PDCB pDCB, PSRB pSRB)
} else {
pSRB->pNextSRB = NULL;
pDCB->pWaitingSRB = pSRB;
- pDCB->pWaitLastSRB = pSRB;
+ pDCB->pWaitingLastSRB = pSRB;
}
splx(intflag);
}
@@ -289,14 +298,21 @@ trm_RewaitSRB(PDCB pDCB, PSRB pSRB)
{
PSRB psrb1;
int intflag;
- u_int8_t bval;
intflag = splcam();
pDCB->GoingSRBCnt--;
psrb1 = pDCB->pGoingSRB;
if (pSRB == psrb1)
+ /*
+ * if this SRB is GoingSRB
+ * remove this SRB from GoingSRB Q
+ */
pDCB->pGoingSRB = psrb1->pNextSRB;
else {
+ /*
+ * if this SRB is not current GoingSRB
+ * remove this SRB from GoingSRB Q
+ */
while (pSRB != psrb1->pNextSRB)
psrb1 = psrb1->pNextSRB;
psrb1->pNextSRB = pSRB->pNextSRB;
@@ -304,15 +320,18 @@ trm_RewaitSRB(PDCB pDCB, PSRB pSRB)
pDCB->pGoingLastSRB = psrb1;
}
if ((psrb1 = pDCB->pWaitingSRB)) {
+ /*
+ * if WaitingSRB Q is not NULL
+ * Q back this SRB into WaitingSRB
+ */
+
pSRB->pNextSRB = psrb1;
pDCB->pWaitingSRB = pSRB;
} else {
pSRB->pNextSRB = NULL;
pDCB->pWaitingSRB = pSRB;
- pDCB->pWaitLastSRB = pSRB;
+ pDCB->pWaitingLastSRB = pSRB;
}
- bval = pSRB->TagNumber;
- pDCB->TagMask &= (~(1 << bval)); /* Free TAG number */
splx(intflag);
}
@@ -334,7 +353,7 @@ trm_DoWaitingSRB(PACB pACB)
ptr1 = ptr;
for (;ptr1 ;) {
pACB->pDCBRunRobin = ptr1->pNextDCB;
- if (!(ptr1->MaxCommand > ptr1->GoingSRBCnt)
+ if (!(ptr1->MaxActiveCommandCnt > ptr1->GoingSRBCnt)
|| !(pSRB = ptr1->pWaitingSRB)) {
if (pACB->pDCBRunRobin == ptr)
break;
@@ -347,9 +366,9 @@ trm_DoWaitingSRB(PACB pACB)
* It's said that SCSI processor is unoccupied
*/
ptr1->GoingSRBCnt++;
- if (ptr1->pWaitLastSRB == pSRB) {
+ if (ptr1->pWaitingLastSRB == pSRB) {
ptr1->pWaitingSRB = NULL;
- ptr1->pWaitLastSRB = NULL;
+ ptr1->pWaitingLastSRB = NULL;
} else
ptr1->pWaitingSRB = pSRB->pNextSRB;
pSRB->pNextSRB = NULL;
@@ -372,17 +391,35 @@ trm_SRBwaiting(PDCB pDCB, PSRB pSRB)
{
if (pDCB->pWaitingSRB) {
- pDCB->pWaitLastSRB->pNextSRB = pSRB;
- pDCB->pWaitLastSRB = pSRB;
+ pDCB->pWaitingLastSRB->pNextSRB = pSRB;
+ pDCB->pWaitingLastSRB = pSRB;
pSRB->pNextSRB = NULL;
} else {
pDCB->pWaitingSRB = pSRB;
- pDCB->pWaitLastSRB = pSRB;
+ pDCB->pWaitingLastSRB = pSRB;
}
}
+static u_int32_t
+trm_get_sense_bufaddr(PACB pACB, PSRB pSRB)
+{
+ int offset;
+
+ offset = pSRB->TagNumber;
+ return (pACB->sense_busaddr +
+ (offset * sizeof(struct scsi_sense_data)));
+}
+
+static struct scsi_sense_data *
+trm_get_sense_buf(PACB pACB, PSRB pSRB)
+{
+ int offset;
+
+ offset = pSRB->TagNumber;
+ return (&pACB->sense_buffers[offset]);
+}
static void
-trm_ExecuteSRB(void *arg, bus_dma_segment_t *dm_segs, int nseg, int vp)
+trm_ExecuteSRB(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
{
int flags;
PACB pACB;
@@ -390,6 +427,7 @@ trm_ExecuteSRB(void *arg, bus_dma_segment_t *dm_segs, int nseg, int vp)
union ccb *ccb;
u_long totalxferlen=0;
+ flags = splcam();
pSRB = (PSRB)arg;
ccb = pSRB->pccb;
pACB = (PACB)ccb->ccb_h.ccb_trmacb_ptr;
@@ -397,15 +435,13 @@ trm_ExecuteSRB(void *arg, bus_dma_segment_t *dm_segs, int nseg, int vp)
if (nseg != 0) {
PSEG psg;
bus_dma_segment_t *end_seg;
- bus_dmasync_op_t op;
+ int op;
/* Copy the segments into our SG list */
end_seg = dm_segs + nseg;
- psg = (PSEG) &pSRB->SegmentX[0];
- pSRB->SRBSGListPointer= psg;
+ psg = pSRB->pSRBSGL;
while (dm_segs < end_seg) {
- psg->address = vp?(u_long)vtophys(dm_segs->ds_addr)
- :(u_long)dm_segs->ds_addr;
+ psg->address = dm_segs->ds_addr;
psg->length = (u_long)dm_segs->ds_len;
totalxferlen += dm_segs->ds_len;
psg++;
@@ -419,7 +455,7 @@ trm_ExecuteSRB(void *arg, bus_dma_segment_t *dm_segs, int nseg, int vp)
bus_dmamap_sync(pACB->buffer_dmat, pSRB->dmamap, op);
}
pSRB->RetryCnt = 0;
- pSRB->SRBTotalXferLength=totalxferlen;
+ pSRB->SRBTotalXferLength = totalxferlen;
pSRB->SRBSGCount = nseg;
pSRB->SRBSGIndex = 0;
pSRB->AdaptStatus = 0;
@@ -430,7 +466,6 @@ trm_ExecuteSRB(void *arg, bus_dma_segment_t *dm_segs, int nseg, int vp)
pSRB->SRBState = 0;
pSRB->ScsiPhase = PH_BUS_FREE; /* SCSI bus free Phase */
- flags = splcam();
if (ccb->ccb_h.status != CAM_REQ_INPROG) {
if (nseg != 0)
bus_dmamap_unload(pACB->buffer_dmat, pSRB->dmamap);
@@ -453,14 +488,12 @@ trm_ExecuteSRB(void *arg, bus_dma_segment_t *dm_segs, int nseg, int vp)
static void
trm_SendSRB(PACB pACB, PSRB pSRB)
{
- int intflag;
PDCB pDCB;
- intflag = splcam();
pDCB = pSRB->pSRBDCB;
- if (!(pDCB->MaxCommand > pDCB->GoingSRBCnt) || (pACB->pActiveDCB)
+ if (!(pDCB->MaxActiveCommandCnt > pDCB->GoingSRBCnt) || (pACB->pActiveDCB)
|| (pACB->ACBFlag & (RESET_DETECT+RESET_DONE+RESET_DEV))) {
- TRM_DPRINTF("pDCB->MaxCommand=%d \n",pDCB->MaxCommand);
+ TRM_DPRINTF("pDCB->MaxCommand=%d \n",pDCB->MaxActiveCommandCnt);
TRM_DPRINTF("pDCB->GoingSRBCnt=%d \n",pDCB->GoingSRBCnt);
TRM_DPRINTF("pACB->pActiveDCB=%8x \n",(u_int)pACB->pActiveDCB);
TRM_DPRINTF("pACB->ACBFlag=%x \n",pACB->ACBFlag);
@@ -498,10 +531,6 @@ trm_SendSRB(PACB pACB, PSRB pSRB)
trm_RewaitSRB0(pDCB, pSRB);
}
SND_EXIT:
- splx(intflag);
- /*
- * enable interrupt
- */
return;
}
@@ -510,10 +539,12 @@ static void
trm_action(struct cam_sim *psim, union ccb *pccb)
{
PACB pACB;
+ int actionflags;
u_int target_id,target_lun;
CAM_DEBUG(pccb->ccb_h.path, CAM_DEBUG_TRACE, ("trm_action\n"));
+ actionflags = splcam();
pACB = (PACB) cam_sim_softc(psim);
target_id = pccb->ccb_h.target_id;
target_lun = pccb->ccb_h.target_lun;
@@ -539,7 +570,18 @@ trm_action(struct cam_sim *psim, union ccb *pccb)
TRM_DPRINTF(
"pACB->scan_devices[target_id][target_lun]= %d \n"
,pACB->scan_devices[target_id][target_lun]);
- pDCB = pACB->pDCB[target_id][target_lun];
+ if ((pccb->ccb_h.status & CAM_STATUS_MASK) !=
+ CAM_REQ_INPROG) {
+ xpt_done(pccb);
+ splx(actionflags);
+ return;
+ }
+ pDCB = &pACB->DCBarray[target_id][target_lun];
+ if (!(pDCB->DCBstatus & DS_IN_QUEUE)) {
+ pACB->scan_devices[target_id][target_lun] = 1;
+ trm_initDCB(pACB, pDCB, pACB->AdapterUnit,
+ target_id, target_lun);
+ }
/*
* Assign an SRB and connect it with this ccb.
*/
@@ -548,6 +590,7 @@ trm_action(struct cam_sim *psim, union ccb *pccb)
/* Freeze SIMQ */
pccb->ccb_h.status = CAM_RESRC_UNAVAIL;
xpt_done(pccb);
+ splx(actionflags);
return;
}
pSRB->pSRBDCB = pDCB;
@@ -559,18 +602,31 @@ trm_action(struct cam_sim *psim, union ccb *pccb)
* move layer of CAM command block to layer of SCSI
* Request Block for SCSI processor command doing
*/
- bcopy(pcsio->cdb_io.cdb_bytes,pSRB->CmdBlock
- ,pcsio->cdb_len);
+ if ((pccb->ccb_h.flags & CAM_CDB_POINTER) != 0) {
+ if ((pccb->ccb_h.flags & CAM_CDB_PHYS) == 0) {
+ bcopy(pcsio->cdb_io.cdb_ptr,pSRB->CmdBlock
+ ,pcsio->cdb_len);
+ } else {
+ pccb->ccb_h.status = CAM_REQ_INVALID;
+ pSRB->pNextSRB = pACB->pFreeSRB;
+ pACB->pFreeSRB= pSRB;
+ xpt_done(pccb);
+ splx(actionflags);
+ return;
+ }
+ } else
+ bcopy(pcsio->cdb_io.cdb_bytes,
+ pSRB->CmdBlock, pcsio->cdb_len);
if ((pccb->ccb_h.flags & CAM_DIR_MASK)
!= CAM_DIR_NONE) {
if ((pccb->ccb_h.flags &
CAM_SCATTER_VALID) == 0) {
if ((pccb->ccb_h.flags
& CAM_DATA_PHYS) == 0) {
- int flags;
+ int vmflags;
int error;
- flags = splsoftvm();
+ vmflags = splsoftvm();
error = bus_dmamap_load(
pACB->buffer_dmat,
pSRB->dmamap,
@@ -586,7 +642,7 @@ trm_action(struct cam_sim *psim, union ccb *pccb)
pccb->ccb_h.status |=
CAM_RELEASE_SIMQ;
}
- splx(flags);
+ splx(vmflags);
} else {
struct bus_dma_segment seg;
@@ -610,6 +666,7 @@ trm_action(struct cam_sim *psim, union ccb *pccb)
pccb->ccb_h.status =
CAM_PROVIDE_FAIL;
xpt_done(pccb);
+ splx(actionflags);
return;
}
@@ -652,6 +709,7 @@ trm_action(struct cam_sim *psim, union ccb *pccb)
cpi->max_lun = pACB->max_lun; /* 7 or 0 */
cpi->initiator_id = pACB->AdaptSCSIID;
cpi->bus_id = cam_sim_bus(psim);
+ cpi->base_transfer_speed = 3300;
strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
strncpy(cpi->hba_vid, "Tekram_TRM", HBA_IDLEN);
strncpy(cpi->dev_name, cam_sim_name(psim), DEV_IDLEN);
@@ -781,7 +839,7 @@ trm_action(struct cam_sim *psim, union ccb *pccb)
TRM_DPRINTF(" XPT_GET_TRAN_SETTINGS \n");
cts = &pccb->cts;
- pDCB = pACB->pDCB[target_id][target_lun];
+ pDCB = &pACB->DCBarray[target_id][target_lun];
intflag = splcam();
/*
* disable interrupt
@@ -847,7 +905,7 @@ trm_action(struct cam_sim *psim, union ccb *pccb)
if ((cts->flags & CCB_TRANS_USER_SETTINGS) != 0)
update_type |= TRM_TRANS_USER;
intflag = splcam();
- pDCB = pACB->pDCB[target_id][target_lun];
+ pDCB = &pACB->DCBarray[target_id][target_lun];
if ((cts->valid & CCB_TRANS_DISC_VALID) != 0) {
/*ccb disc enables */
@@ -928,17 +986,17 @@ trm_action(struct cam_sim *psim, union ccb *pccb)
* Calculate the geometry parameters for a device give
* the sector size and volume size.
*/
- case XPT_CALC_GEOMETRY: {
+ case XPT_CALC_GEOMETRY: {
struct ccb_calc_geometry *ccg;
- u_int32_t size_mb;
- u_int32_t secs_per_cylinder;
- int extended;
+ u_int32_t size_mb;
+ u_int32_t secs_per_cylinder;
+ int extended;
TRM_DPRINTF(" XPT_CALC_GEOMETRY \n");
ccg = &pccb->ccg;
- size_mb = ccg->volume_size /
+ size_mb = ccg->volume_size /
((1024L * 1024L) / ccg->block_size);
- extended = 1;
+ extended = 1;
if (size_mb > 1024 && extended) {
ccg->heads = 255;
ccg->secs_per_track = 63;
@@ -950,8 +1008,8 @@ trm_action(struct cam_sim *psim, union ccb *pccb)
ccg->cylinders = ccg->volume_size / secs_per_cylinder;
pccb->ccb_h.status = CAM_REQ_CMP;
xpt_done(pccb);
- }
break;
+ }
case XPT_ENG_INQ:
TRM_DPRINTF(" XPT_ENG_INQ \n");
pccb->ccb_h.status = CAM_REQ_INVALID;
@@ -1043,12 +1101,13 @@ trm_action(struct cam_sim *psim, union ccb *pccb)
xpt_done(pccb);
break;
}
+ splx(actionflags);
}
static void
trm_poll(struct cam_sim *psim)
{
- trm_Interrupt(cam_sim_softc(psim));
+ trm_Interrupt(cam_sim_softc(psim));
}
static void
@@ -1072,7 +1131,10 @@ trm_ResetDevParam(PACB pACB)
pDCB->AdpMode = pEEpromBuf->NvramChannelCfg;
PeriodIndex =
pEEpromBuf->NvramTarget[pDCB->TargetID].NvmTarPeriod & 0x07;
- pDCB->MaxNegoPeriod = dc395x_trm_clock_period[PeriodIndex];
+ if (pACB->AdaptType == 1) /* is U2? */
+ pDCB->MaxNegoPeriod = dc395u2x_clock_period[PeriodIndex];
+ else
+ pDCB->MaxNegoPeriod = dc395x_clock_period[PeriodIndex];
if ((pDCB->DevMode & NTC_DO_WIDE_NEGO) &&
(pACB->Config & HCC_WIDE_CARD))
pDCB->SyncMode |= WIDE_NEGO_ENABLE;
@@ -1103,13 +1165,12 @@ trm_RecoverSRB(PACB pACB)
pdcb->pWaitingSRB = psrb2;
} else {
pdcb->pWaitingSRB = psrb2;
- pdcb->pWaitLastSRB = psrb2;
+ pdcb->pWaitingLastSRB = psrb2;
psrb2->pNextSRB = NULL;
}
}
pdcb->GoingSRBCnt = 0;
pdcb->pGoingSRB = NULL;
- pdcb->TagMask = 0;
pdcb = pdcb->pNextDCB;
}
while (pdcb != pDCB);
@@ -1152,15 +1213,13 @@ static u_int16_t
trm_StartSCSI(PACB pACB, PDCB pDCB, PSRB pSRB)
{
u_int16_t return_code;
- u_int8_t tag_number, scsicommand, i,command,identify_message;
+ u_int8_t scsicommand, i,command,identify_message;
u_int8_t * ptr;
- u_long tag_mask;
union ccb *pccb;
struct ccb_scsiio *pcsio;
pccb = pSRB->pccb;
pcsio = &pccb->csio;
- pSRB->TagNumber = 31;
trm_reg_write8(pACB->AdaptSCSIID, TRMREG_SCSI_HOSTID);
trm_reg_write8(pDCB->TargetID, TRMREG_SCSI_TARGETID);
@@ -1176,7 +1235,7 @@ trm_StartSCSI(PACB pACB, PDCB pDCB, PSRB pSRB)
(pSRB->CmdBlock[0] == REQUEST_SENSE) ||
(pSRB->SRBFlag & AUTO_REQSENSE)) {
if (((pDCB->SyncMode & WIDE_NEGO_ENABLE) &&
- !(pDCB->SyncMode & WIDE_NEGO_DONE)) \
+ !(pDCB->SyncMode & WIDE_NEGO_DONE))
|| ((pDCB->SyncMode & SYNC_NEGO_ENABLE) &&
!(pDCB->SyncMode & SYNC_NEGO_DONE))) {
if (!(pDCB->IdentifyMsg & 7) ||
@@ -1202,24 +1261,9 @@ trm_StartSCSI(PACB pACB, PDCB pDCB, PSRB pSRB)
pSRB->SRBState = SRB_START_;
if (pDCB->SyncMode & EN_TAG_QUEUING) {
/* Send Tag message */
- /*
- * Get tag id
- */
- tag_mask = 1;
- tag_number = 0;
- while (tag_mask & pDCB->TagMask) {
- tag_mask = tag_mask << 1;
- tag_number++;
- }
- /*
- * Send Tag id
- */
- trm_reg_write8(MSG_SIMPLE_QTAG, TRMREG_SCSI_FIFO);
- trm_reg_write8(tag_number, TRMREG_SCSI_FIFO);
- pDCB->TagMask |= tag_mask;
- pSRB->TagNumber = tag_number;
+ trm_reg_write8(MSG_SIMPLE_QTAG, TRMREG_SCSI_FIFO);
+ trm_reg_write8(pSRB->TagNumber, TRMREG_SCSI_FIFO);
scsicommand = SCMD_SEL_ATN3;
- pSRB->SRBState = SRB_START_;
}
}
polling:
@@ -1248,7 +1292,6 @@ polling:
* SCSI processor has been occupied by one SRB.
*/
pSRB->SRBState = SRB_READY;
- pDCB->TagMask &= ~(1 << pSRB->TagNumber);
return_code = 1;
} else {
/*
@@ -1278,16 +1321,12 @@ void *vpACB;
PDCB pDCB;
PSRB pSRB;
u_int16_t phase;
- void (*stateV)(PACB, PSRB, u_int8_t *);
- u_int8_t scsi_status=0, scsi_intstatus;
+ void (*stateV)(PACB, PSRB, u_int16_t *);
+ u_int16_t scsi_status=0;
+ u_int8_t scsi_intstatus;
pACB = vpACB;
- if (pACB == NULL) {
- TRM_DPRINTF("trm_Interrupt: pACB NULL return......");
- return;
- }
-
scsi_status = trm_reg_read16(TRMREG_SCSI_STATUS);
if (!(scsi_status & SCSIINTERRUPT)) {
TRM_DPRINTF("trm_Interrupt: TRMREG_SCSI_STATUS scsi_status = NULL ,return......");
@@ -1315,11 +1354,10 @@ void *vpACB;
if (scsi_intstatus & (INT_BUSSERVICE | INT_CMDDONE)) {
pDCB = pACB->pActiveDCB;
+ KASSERT(pDCB != NULL, ("no active DCB"));
pSRB = pDCB->pActiveSRB;
- if (pDCB) {
- if (pDCB->DCBFlag & ABORT_DEV_)
+ if (pDCB->DCBFlag & ABORT_DEV_)
trm_EnableMsgOutAbort1(pACB, pSRB);
- }
phase = (u_int16_t) pSRB->ScsiPhase; /* phase: */
stateV = (void *) trm_SCSI_phase0[phase];
stateV(pACB, pSRB, &scsi_status);
@@ -1332,7 +1370,7 @@ void *vpACB;
}
static void
-trm_MsgOutPhase0(PACB pACB, PSRB pSRB, u_int8_t *pscsi_status)
+trm_MsgOutPhase0(PACB pACB, PSRB pSRB, u_int16_t *pscsi_status)
{
if (pSRB->SRBState & (SRB_UNEXPECT_RESEL+SRB_ABORT_SENT))
@@ -1341,7 +1379,7 @@ trm_MsgOutPhase0(PACB pACB, PSRB pSRB, u_int8_t *pscsi_status)
}
static void
-trm_MsgOutPhase1(PACB pACB, PSRB pSRB, u_int8_t *pscsi_status)
+trm_MsgOutPhase1(PACB pACB, PSRB pSRB, u_int16_t *pscsi_status)
{
u_int8_t bval;
u_int16_t i, cnt;
@@ -1409,7 +1447,8 @@ mop1: /* message out phase */
/* SYNCHRONOUS DATA TRANSFER REQUEST code (01h) */
trm_reg_write8(pDCB->MaxNegoPeriod,TRMREG_SCSI_FIFO);
/* Transfer peeriod factor */
- trm_reg_write8(SYNC_NEGO_OFFSET,TRMREG_SCSI_FIFO);
+ trm_reg_write8((pACB->AdaptType == 1) ? 31 : 15,
+ TRMREG_SCSI_FIFO);
/* REQ/ACK offset */
pSRB->SRBState |= SRB_DO_SYNC_NEGO;
}
@@ -1423,13 +1462,13 @@ mop1: /* message out phase */
}
static void
-trm_CommandPhase0(PACB pACB, PSRB pSRB, u_int8_t *pscsi_status)
+trm_CommandPhase0(PACB pACB, PSRB pSRB, u_int16_t *pscsi_status)
{
}
static void
-trm_CommandPhase1(PACB pACB, PSRB pSRB, u_int8_t *pscsi_status)
+trm_CommandPhase1(PACB pACB, PSRB pSRB, u_int16_t *pscsi_status)
{
PDCB pDCB;
u_int8_t * ptr;
@@ -1469,7 +1508,7 @@ trm_CommandPhase1(PACB pACB, PSRB pSRB, u_int8_t *pscsi_status)
}
static void
-trm_DataOutPhase0(PACB pACB, PSRB pSRB, u_int8_t *pscsi_status)
+trm_DataOutPhase0(PACB pACB, PSRB pSRB, u_int16_t *pscsi_status)
{
PDCB pDCB;
u_int8_t TempDMAstatus,SGIndexTemp;
@@ -1489,7 +1528,7 @@ trm_DataOutPhase0(PACB pACB, PSRB pSRB, u_int8_t *pscsi_status)
* if there was some data left in SCSI FIFO
*/
dLeftCounter = (u_long)
- (trm_reg_read8(TRMREG_SCSI_FIFOCNT) & 0x1F);
+ (trm_reg_read8(TRMREG_SCSI_FIFOCNT) & 0x3F);
if (pDCB->SyncPeriod & WIDE_SYNC) {
/*
* if WIDE scsi SCSI FIFOCNT unit is word
@@ -1542,7 +1581,7 @@ trm_DataOutPhase0(PACB pACB, PSRB pSRB, u_int8_t *pscsi_status)
* parsing from last time disconnect SRBSGIndex
*/
pseg =
- pSRB->SRBSGListPointer + pSRB->SRBSGIndex;
+ pSRB->pSRBSGL + pSRB->SRBSGIndex;
for (SGIndexTemp = pSRB->SRBSGIndex;
SGIndexTemp < pSRB->SRBSGCount;
SGIndexTemp++) {
@@ -1578,7 +1617,7 @@ trm_DataOutPhase0(PACB pACB, PSRB pSRB, u_int8_t *pscsi_status)
static void
-trm_DataOutPhase1(PACB pACB, PSRB pSRB, u_int8_t *pscsi_status)
+trm_DataOutPhase1(PACB pACB, PSRB pSRB, u_int16_t *pscsi_status)
{
u_int16_t ioDir;
/*
@@ -1590,9 +1629,9 @@ trm_DataOutPhase1(PACB pACB, PSRB pSRB, u_int8_t *pscsi_status)
}
static void
-trm_DataInPhase0(PACB pACB, PSRB pSRB, u_int8_t *pscsi_status)
+trm_DataInPhase0(PACB pACB, PSRB pSRB, u_int16_t *pscsi_status)
{
- u_int8_t bval,SGIndexTemp;
+ u_int8_t TempDMAstatus, SGIndexTemp;
u_int16_t scsi_status;
PSEG pseg;
u_long TempSRBXferredLength,dLeftCounter = 0;
@@ -1603,9 +1642,9 @@ trm_DataInPhase0(PACB pACB, PSRB pSRB, u_int8_t *pscsi_status)
pSRB->SRBStatus |= PARITY_ERROR;
dLeftCounter += trm_reg_read32(TRMREG_SCSI_COUNTER);
if ((dLeftCounter == 0) || (scsi_status & SCSIXFERCNT_2_ZERO)) {
- bval = trm_reg_read8(TRMREG_DMA_STATUS);
- while (!(bval & DMAXFERCOMP))
- bval = trm_reg_read8(TRMREG_DMA_STATUS);
+ TempDMAstatus = trm_reg_read8(TRMREG_DMA_STATUS);
+ while (!(TempDMAstatus & DMAXFERCOMP))
+ TempDMAstatus = trm_reg_read8(TRMREG_DMA_STATUS);
pSRB->SRBTotalXferLength = 0;
} else {
/*
@@ -1629,7 +1668,7 @@ trm_DataInPhase0(PACB pACB, PSRB pSRB, u_int8_t *pscsi_status)
/*
* parsing from last time disconnect SRBSGIndex
*/
- pseg = pSRB->SRBSGListPointer + pSRB->SRBSGIndex;
+ pseg = pSRB->pSRBSGL + pSRB->SRBSGIndex;
for (SGIndexTemp = pSRB->SRBSGIndex;
SGIndexTemp < pSRB->SRBSGCount;
SGIndexTemp++) {
@@ -1657,7 +1696,7 @@ trm_DataInPhase0(PACB pACB, PSRB pSRB, u_int8_t *pscsi_status)
}
static void
-trm_DataInPhase1(PACB pACB, PSRB pSRB, u_int8_t *pscsi_status)
+trm_DataInPhase1(PACB pACB, PSRB pSRB, u_int16_t *pscsi_status)
{
u_int16_t ioDir;
/*
@@ -1677,11 +1716,19 @@ trm_DataIO_transfer(PACB pACB, PSRB pSRB, u_int16_t ioDir)
pDCB = pSRB->pSRBDCB;
if (pSRB->SRBSGIndex < pSRB->SRBSGCount) {
if (pSRB->SRBTotalXferLength != 0) {
- pSRB->SRBSGPhyAddr = vtophys(pSRB->SRBSGListPointer);
/*
* load what physical address of Scatter/Gather list
table want to be transfer
*/
+ TRM_DPRINTF(" SG->address=%8x \n",pSRB->pSRBSGL->address);
+ TRM_DPRINTF(" SG->length=%8x \n",pSRB->pSRBSGL->length);
+ TRM_DPRINTF(" pDCB->SyncPeriod=%x \n",pDCB->SyncPeriod);
+ TRM_DPRINTF(" pSRB->pSRBSGL=%8x \n",(unsigned int)pSRB->pSRBSGL);
+ TRM_DPRINTF(" pSRB->SRBSGPhyAddr=%8x \n",pSRB->SRBSGPhyAddr);
+ TRM_DPRINTF(" pSRB->SRBSGIndex=%d \n",pSRB->SRBSGIndex);
+ TRM_DPRINTF(" pSRB->SRBSGCount=%d \n",pSRB->SRBSGCount);
+ TRM_DPRINTF(" pSRB->SRBTotalXferLength=%d \n",pSRB->SRBTotalXferLength);
+
pSRB->SRBState = SRB_DATA_XFER;
trm_reg_write32(0, TRMREG_DMA_XHIGHADDR);
trm_reg_write32(
@@ -1740,7 +1787,7 @@ trm_DataIO_transfer(PACB pACB, PSRB pSRB, u_int16_t ioDir)
}
static void
-trm_StatusPhase0(PACB pACB, PSRB pSRB, u_int8_t *pscsi_status)
+trm_StatusPhase0(PACB pACB, PSRB pSRB, u_int16_t *pscsi_status)
{
pSRB->TargetStatus = trm_reg_read8(TRMREG_SCSI_FIFO);
@@ -1758,7 +1805,7 @@ trm_StatusPhase0(PACB pACB, PSRB pSRB, u_int8_t *pscsi_status)
static void
-trm_StatusPhase1(PACB pACB, PSRB pSRB, u_int8_t *pscsi_status)
+trm_StatusPhase1(PACB pACB, PSRB pSRB, u_int16_t *pscsi_status)
{
if (trm_reg_read16(TRMREG_DMA_COMMAND) & 0x0001) {
@@ -1800,7 +1847,7 @@ trm_StatusPhase1(PACB pACB, PSRB pSRB, u_int8_t *pscsi_status)
*/
static void
-trm_MsgInPhase0(PACB pACB, PSRB pSRB, u_int8_t *pscsi_status)
+trm_MsgInPhase0(PACB pACB, PSRB pSRB, u_int16_t *pscsi_status)
{
u_int8_t message_in_code,bIndex,message_in_tag_id;
PDCB pDCB;
@@ -1812,9 +1859,23 @@ trm_MsgInPhase0(PACB pACB, PSRB pSRB, u_int8_t *pscsi_status)
if (!(pSRB->SRBState & SRB_EXTEND_MSGIN)) {
if (message_in_code == MSG_DISCONNECT) {
pSRB->SRBState = SRB_DISCONNECT;
- goto min6;
+ *pscsi_status = PH_BUS_FREE; /* .. initial phase */
+ /* it's important for atn stop */
+ trm_reg_write16(DO_DATALATCH, TRMREG_SCSI_CONTROL);
+ /*
+ * SCSI command
+ */
+ trm_reg_write8(SCMD_MSGACCEPT, TRMREG_SCSI_COMMAND);
+ return;
} else if (message_in_code == MSG_SAVE_PTR) {
- goto min6;
+ *pscsi_status = PH_BUS_FREE; /* .. initial phase */
+ /* it's important for atn stop */
+ trm_reg_write16(DO_DATALATCH, TRMREG_SCSI_CONTROL);
+ /*
+ * SCSI command
+ */
+ trm_reg_write8(SCMD_MSGACCEPT, TRMREG_SCSI_COMMAND);
+ return;
} else if ((message_in_code == MSG_EXTENDED) ||
((message_in_code >= MSG_SIMPLE_QTAG) &&
(message_in_code <= MSG_ORDER_QTAG))) {
@@ -1824,7 +1885,14 @@ trm_MsgInPhase0(PACB pACB, PSRB pSRB, u_int8_t *pscsi_status)
pSRB->MsgCnt = 1;
pSRB->pMsgPtr = &pSRB->MsgInBuf[1];
/* extended message length (n) */
- goto min6;
+ *pscsi_status = PH_BUS_FREE; /* .. initial phase */
+ /* it's important for atn stop */
+ trm_reg_write16(DO_DATALATCH, TRMREG_SCSI_CONTROL);
+ /*
+ * SCSI command
+ */
+ trm_reg_write8(SCMD_MSGACCEPT, TRMREG_SCSI_COMMAND);
+ return;
} else if (message_in_code == MSG_REJECT_) {
/* Reject message */
if (pDCB->SyncMode & WIDE_NEGO_ENABLE) {
@@ -1856,20 +1924,50 @@ trm_MsgInPhase0(PACB pACB, PSRB pSRB, u_int8_t *pscsi_status)
~(SYNC_NEGO_ENABLE+SYNC_NEGO_DONE);
pDCB->SyncPeriod = 0;
pDCB->SyncOffset = 0;
- goto re_prog;
+ /*
+ *
+ * program SCSI control register
+ *
+ */
+ trm_reg_write8(pDCB->SyncPeriod,
+ TRMREG_SCSI_SYNC);
+ trm_reg_write8(pDCB->SyncOffset,
+ TRMREG_SCSI_OFFSET);
+ trm_SetXferRate(pACB,pSRB,pDCB);
}
}
- goto min6;
+ *pscsi_status = PH_BUS_FREE; /* .. initial phase */
+ /* it's important for atn stop */
+ trm_reg_write16(DO_DATALATCH, TRMREG_SCSI_CONTROL);
+ /*
+ * SCSI command
+ */
+ trm_reg_write8(SCMD_MSGACCEPT, TRMREG_SCSI_COMMAND);
+ return;
} else if (message_in_code == MSG_IGNOREWIDE) {
trm_reg_write32(1, TRMREG_SCSI_COUNTER);
trm_reg_read8(TRMREG_SCSI_FIFO);
- goto min6;
+ *pscsi_status = PH_BUS_FREE; /* .. initial phase */
+ /* it's important for atn stop */
+ trm_reg_write16(DO_DATALATCH, TRMREG_SCSI_CONTROL);
+ /*
+ * SCSI command
+ */
+ trm_reg_write8(SCMD_MSGACCEPT, TRMREG_SCSI_COMMAND);
+ return;
} else {
/* Restore data pointer message */
/* Save data pointer message */
/* Completion message */
/* NOP message */
- goto min6;
+ *pscsi_status = PH_BUS_FREE; /* .. initial phase */
+ /* it's important for atn stop */
+ trm_reg_write16(DO_DATALATCH, TRMREG_SCSI_CONTROL);
+ /*
+ * SCSI command
+ */
+ trm_reg_write8(SCMD_MSGACCEPT, TRMREG_SCSI_COMMAND);
+ return;
}
} else {
/*
@@ -1916,13 +2014,15 @@ trm_MsgInPhase0(PACB pACB, PSRB pSRB, u_int8_t *pscsi_status)
trm_EnableMsgOutAbort1(
pACB, pSRB);
}
- if (!(pSRB->SRBState & SRB_DISCONNECT))
+ if (!(pSRB->SRBState & SRB_DISCONNECT)) {
+ TRM_DPRINTF("SRB not yet disconnect........ \n ");
goto mingx0;
+ }
pDCB->pActiveSRB = pSRB;
pSRB->SRBState = SRB_DATA_XFER;
} else {
mingx0:
- pSRB = pACB->pTmpSRB;
+ pSRB = &pACB->TmpSRB;
pSRB->SRBState = SRB_UNEXPECT_RESEL;
pDCB->pActiveSRB = pSRB;
pSRB->MsgOutBuf[0] = MSG_ABORT_TAG;
@@ -1931,6 +2031,15 @@ mingx0:
pSRB);
}
}
+ *pscsi_status = PH_BUS_FREE;
+ /* .. initial phase */
+ trm_reg_write16(DO_DATALATCH, TRMREG_SCSI_CONTROL);
+ /* it's important for atn stop */
+ /*
+ * SCSI command
+ */
+ trm_reg_write8(SCMD_MSGACCEPT, TRMREG_SCSI_COMMAND);
+ return;
} else if ((pSRB->MsgInBuf[0] == MSG_EXTENDED) &&
(pSRB->MsgInBuf[2] == 3) && (pSRB->MsgCnt == 4)) {
/*
@@ -1952,7 +2061,14 @@ mingx0:
pSRB->MsgCnt = 1;
pSRB->MsgInBuf[0] = MSG_REJECT_;
trm_reg_write16(DO_SETATN, TRMREG_SCSI_CONTROL);
- goto min6;
+ *pscsi_status = PH_BUS_FREE; /* .. initial phase */
+ /* it's important for atn stop */
+ trm_reg_write16(DO_DATALATCH, TRMREG_SCSI_CONTROL);
+ /*
+ * SCSI command
+ */
+ trm_reg_write8(SCMD_MSGACCEPT, TRMREG_SCSI_COMMAND);
+ return;
}
if (pDCB->SyncMode & WIDE_NEGO_ENABLE) {
/* Do wide negoniation */
@@ -1965,7 +2081,14 @@ mingx0:
pSRB->MsgInBuf[0] = MSG_REJECT_;
trm_reg_write16(DO_SETATN,
TRMREG_SCSI_CONTROL);
- goto min6;
+ *pscsi_status = PH_BUS_FREE; /* .. initial phase */
+ /* it's important for atn stop */
+ trm_reg_write16(DO_DATALATCH, TRMREG_SCSI_CONTROL);
+ /*
+ * SCSI command
+ */
+ trm_reg_write8(SCMD_MSGACCEPT, TRMREG_SCSI_COMMAND);
+ return;
}
if (pSRB->MsgInBuf[3] == 2) {
pSRB->MsgInBuf[3] = 1;
@@ -1996,7 +2119,14 @@ mingx0:
pSRB->MsgInBuf[3] = 0;
pSRB->SRBState |= SRB_MSGOUT;
trm_reg_write16(DO_SETATN,TRMREG_SCSI_CONTROL);
- goto min6;
+ *pscsi_status = PH_BUS_FREE; /* .. initial phase */
+ /* it's important for atn stop */
+ trm_reg_write16(DO_DATALATCH, TRMREG_SCSI_CONTROL);
+ /*
+ * SCSI command
+ */
+ trm_reg_write8(SCMD_MSGACCEPT, TRMREG_SCSI_COMMAND);
+ return;
} else if ((pSRB->MsgInBuf[0] == MSG_EXTENDED) &&
(pSRB->MsgInBuf[2] == 1) && (pSRB->MsgCnt == 5)) {
/*
@@ -2017,6 +2147,15 @@ mingx0:
pSRB->MsgCnt = 1;
pSRB->MsgInBuf[0] = MSG_REJECT_;
trm_reg_write16(DO_SETATN, TRMREG_SCSI_CONTROL);
+ *pscsi_status = PH_BUS_FREE;
+ /* .. initial phase */
+ trm_reg_write16(DO_DATALATCH, TRMREG_SCSI_CONTROL);
+ /* it's important for atn stop */
+ /*
+ * SCSI cammand
+ */
+ trm_reg_write8(SCMD_MSGACCEPT, TRMREG_SCSI_COMMAND);
+ return;
} else if (!(pSRB->MsgInBuf[3]) || !(pSRB->MsgInBuf[4])) {
/* set async */
pDCB = pSRB->pSRBDCB;
@@ -2031,7 +2170,23 @@ mingx0:
pDCB->tinfo.current.offset = 0;
pDCB->tinfo.current.width =
MSG_EXT_WDTR_BUS_8_BIT;
- goto re_prog;
+ /*
+ *
+ * program SCSI control register
+ *
+ */
+ trm_reg_write8(pDCB->SyncPeriod,TRMREG_SCSI_SYNC);
+ trm_reg_write8(pDCB->SyncOffset,TRMREG_SCSI_OFFSET);
+ trm_SetXferRate(pACB,pSRB,pDCB);
+ *pscsi_status = PH_BUS_FREE;
+ /* .. initial phase */
+ trm_reg_write16(DO_DATALATCH, TRMREG_SCSI_CONTROL);
+ /* it's important for atn stop */
+ /*
+ * SCSI cammand
+ */
+ trm_reg_write8(SCMD_MSGACCEPT, TRMREG_SCSI_COMMAND);
+ return;
} else {
/* set sync */
pDCB = pSRB->pSRBDCB;
@@ -2041,20 +2196,40 @@ mingx0:
/* Transfer period factor */
pDCB->SyncOffset = pSRB->MsgInBuf[4];
/* REQ/ACK offset */
- for (bIndex = 0; bIndex < 7; bIndex++) {
- if (pSRB->MsgInBuf[3] <=
- dc395x_trm_clock_period[bIndex]) {
- break;
- }
+ if (pACB->AdaptType == 1) {
+ for(bIndex = 0; bIndex < 7; bIndex++) {
+ if (pSRB->MsgInBuf[3] <=
+ dc395u2x_clock_period[bIndex]) {
+ pDCB->tinfo.goal.period =
+ dc395u2x_tinfo_period[bIndex];
+ pDCB->tinfo.current.period =
+ dc395u2x_tinfo_period[bIndex];
+ pDCB->tinfo.goal.offset =
+ pDCB->SyncOffset;
+ pDCB->tinfo.current.offset =
+ pDCB->SyncOffset;
+ pDCB->SyncPeriod |= (bIndex|LVDS_SYNC);
+ break;
+ }
+ }
+ } else {
+ for(bIndex = 0; bIndex < 7; bIndex++) {
+ if (pSRB->MsgInBuf[3] <=
+ dc395x_clock_period[bIndex]) {
+ pDCB->tinfo.goal.period =
+ dc395x_tinfo_period[bIndex];
+ pDCB->tinfo.current.period =
+ dc395x_tinfo_period[bIndex];
+ pDCB->tinfo.goal.offset =
+ pDCB->SyncOffset;
+ pDCB->tinfo.current.offset =
+ pDCB->SyncOffset;
+ pDCB->SyncPeriod |=
+ (bIndex|ALT_SYNC);
+ break;
+ }
+ }
}
- pDCB->tinfo.goal.period =
- dc395x_trm_tinfo_sync_period[bIndex];
- pDCB->tinfo.current.period =
- dc395x_trm_tinfo_sync_period[bIndex];
- pDCB->tinfo.goal.offset = pDCB->SyncOffset;
- pDCB->tinfo.current.offset = pDCB->SyncOffset;
- pDCB->SyncPeriod |= (bIndex | ALT_SYNC);
-re_prog:
/*
*
* program SCSI control register
@@ -2065,10 +2240,15 @@ re_prog:
trm_reg_write8(pDCB->SyncOffset,
TRMREG_SCSI_OFFSET);
trm_SetXferRate(pACB,pSRB,pDCB);
+ *pscsi_status=PH_BUS_FREE;/*.. initial phase*/
+ trm_reg_write16(DO_DATALATCH,TRMREG_SCSI_CONTROL);/* it's important for atn stop*/
+ /*
+ ** SCSI command
+ */
+ trm_reg_write8(SCMD_MSGACCEPT,TRMREG_SCSI_COMMAND);
+ return;
}
}
- }
-min6:
*pscsi_status = PH_BUS_FREE;
/* .. initial phase */
trm_reg_write16(DO_DATALATCH, TRMREG_SCSI_CONTROL);
@@ -2077,10 +2257,11 @@ min6:
* SCSI cammand
*/
trm_reg_write8(SCMD_MSGACCEPT, TRMREG_SCSI_COMMAND);
+ }
}
static void
-trm_MsgInPhase1(PACB pACB, PSRB pSRB, u_int8_t *pscsi_status)
+trm_MsgInPhase1(PACB pACB, PSRB pSRB, u_int16_t *pscsi_status)
{
trm_reg_write16(DO_CLRFIFO, TRMREG_SCSI_CONTROL);
@@ -2098,13 +2279,13 @@ trm_MsgInPhase1(PACB pACB, PSRB pSRB, u_int8_t *pscsi_status)
}
static void
-trm_Nop0(PACB pACB, PSRB pSRB, u_int8_t *pscsi_status)
+trm_Nop0(PACB pACB, PSRB pSRB, u_int16_t *pscsi_status)
{
}
static void
-trm_Nop1(PACB pACB, PSRB pSRB, u_int8_t *pscsi_status)
+trm_Nop1(PACB pACB, PSRB pSRB, u_int16_t *pscsi_status)
{
}
@@ -2112,31 +2293,33 @@ trm_Nop1(PACB pACB, PSRB pSRB, u_int8_t *pscsi_status)
static void
trm_SetXferRate(PACB pACB,PSRB pSRB, PDCB pDCB)
{
+ union ccb *pccb;
+ struct ccb_trans_settings neg;
u_int16_t cnt, i;
u_int8_t bval;
PDCB pDCBTemp;
- u_int target_id,target_lun;
/*
* set all lun device's period , offset
*/
- target_id = pSRB->pccb->ccb_h.target_id;
- target_lun = pSRB->pccb->ccb_h.target_lun;
- TRM_DPRINTF("trm_SetXferRate:target_id= %d ,target_lun= %d \n"
- ,target_id,target_lun);
+ TRM_DPRINTF("trm_SetXferRate\n");
+ pccb = pSRB->pccb;
+ neg.sync_period = pDCB->tinfo.goal.period;
+ neg.sync_offset = pDCB->tinfo.goal.offset;
+ neg.valid = CCB_TRANS_SYNC_RATE_VALID | CCB_TRANS_SYNC_OFFSET_VALID;
+ xpt_setup_ccb(&neg.ccb_h, pccb->ccb_h.path, /* priority */1);
+ xpt_async(AC_TRANSFER_NEG, pccb->ccb_h.path, &neg);
if (!(pDCB->IdentifyMsg & 0x07)) {
- if (!pACB->scan_devices[target_id][target_lun]) {
- pDCBTemp = pACB->pLinkDCB;
- cnt = pACB->DeviceCnt;
- bval = pDCB->TargetID;
- for (i = 0; i < cnt; i++) {
- if (pDCBTemp->TargetID == bval) {
- pDCBTemp->SyncPeriod = pDCB->SyncPeriod;
- pDCBTemp->SyncOffset = pDCB->SyncOffset;
- pDCBTemp->SyncMode = pDCB->SyncMode;
- }
- pDCBTemp = pDCBTemp->pNextDCB;
+ pDCBTemp = pACB->pLinkDCB;
+ cnt = pACB->DeviceCnt;
+ bval = pDCB->TargetID;
+ for (i = 0; i < cnt; i++) {
+ if (pDCBTemp->TargetID == bval) {
+ pDCBTemp->SyncPeriod = pDCB->SyncPeriod;
+ pDCBTemp->SyncOffset = pDCB->SyncOffset;
+ pDCBTemp->SyncMode = pDCB->SyncMode;
}
+ pDCBTemp = pDCBTemp->pNextDCB;
}
}
return;
@@ -2164,14 +2347,11 @@ trm_Disconnect(PACB pACB)
{
PDCB pDCB;
PSRB pSRB, psrb;
- int intflag;
u_int16_t i,j, cnt;
- u_int8_t bval;
u_int target_id,target_lun;
TRM_DPRINTF("trm_Disconnect...............\n ");
- intflag = splcam();
pDCB = pACB->pActiveDCB;
if (!pDCB) {
TRM_DPRINTF(" Exception Disconnect DCB=NULL..............\n ");
@@ -2196,7 +2376,6 @@ trm_Disconnect(PACB pACB)
pSRB->SRBState = 0;
trm_DoWaitingSRB(pACB);
} else if (pSRB->SRBState & SRB_ABORT_SENT) {
- pDCB->TagMask = 0;
pDCB->DCBFlag = 0;
cnt = pDCB->GoingSRBCnt;
pDCB->GoingSRBCnt = 0;
@@ -2213,7 +2392,9 @@ trm_Disconnect(PACB pACB)
if ((pSRB->SRBState & (SRB_START_+SRB_MSGOUT)) ||
!(pSRB->SRBState & (SRB_DISCONNECT+SRB_COMPLETED))) {
/* Selection time out */
- if (!(pACB->scan_devices[target_id][target_lun])) {
+ if (!(pACB->scan_devices[target_id][target_lun]) &&
+ pSRB->CmdBlock[0] != 0x00 && /* TEST UNIT READY */
+ pSRB->CmdBlock[0] != INQUIRY) {
pSRB->SRBState = SRB_READY;
trm_RewaitSRB(pDCB, pSRB);
} else {
@@ -2230,17 +2411,11 @@ disc1:
/*
* SRB_COMPLETED
*/
- if (pDCB->MaxCommand > 1) {
- bval = pSRB->TagNumber;
- pDCB->TagMask &= (~(1 << bval));
- /* free tag mask */
- }
pDCB->pActiveSRB = 0;
pSRB->SRBState = SRB_FREE;
trm_SRBdone(pACB, pDCB, pSRB);
}
}
- splx(intflag);
return;
}
@@ -2269,7 +2444,7 @@ trm_Reselect(PACB pACB)
pACB->pActiveDCB = pDCB;
if (pDCB->SyncMode & EN_TAG_QUEUING) {
- pSRB = pACB->pTmpSRB;
+ pSRB = &pACB->TmpSRB;
pDCB->pActiveSRB = pSRB;
} else {
pSRB = pDCB->pActiveSRB;
@@ -2277,7 +2452,7 @@ trm_Reselect(PACB pACB)
/*
* abort command
*/
- pSRB = pACB->pTmpSRB;
+ pSRB = &pACB->TmpSRB;
pSRB->SRBState = SRB_UNEXPECT_RESEL;
pDCB->pActiveSRB = pSRB;
trm_EnableMsgOutAbort1(pACB, pSRB);
@@ -2361,10 +2536,13 @@ trm_SRBdone(PACB pACB, PDCB pDCB, PSRB pSRB)
*((u_long *) &(pSRB->CmdBlock[0])) = pSRB->Segment0[0];
*((u_long *) &(pSRB->CmdBlock[4])) = pSRB->Segment0[1];
pSRB->SRBTotalXferLength = pSRB->Segment1[1];
- pSRB->SegmentX[0].address = pSRB->SgSenseTemp.address;
- pSRB->SegmentX[0].length = pSRB->SgSenseTemp.length;
+ pSRB->pSRBSGL->address = pSRB->SgSenseTemp.address;
+ pSRB->pSRBSGL->length = pSRB->SgSenseTemp.length;
pcsio->scsi_status = SCSI_STATUS_CHECK_COND;
- pccb->ccb_h.status = CAM_AUTOSNS_VALID;
+ bcopy(trm_get_sense_buf(pACB, pSRB), &pcsio->sense_data,
+ pcsio->sense_len);
+ pcsio->ccb_h.status = CAM_SCSI_STATUS_ERROR
+ | CAM_AUTOSNS_VALID;
goto ckc_e;
}
/*
@@ -2378,19 +2556,16 @@ trm_SRBdone(PACB pACB, PDCB pDCB, PSRB pSRB)
return;
}
pcsio->scsi_status = SCSI_STATUS_CHECK_COND;
- pccb->ccb_h.status = CAM_AUTOSNS_VALID |
- CAM_SCSI_STATUS_ERROR;
+ pccb->ccb_h.status = CAM_SCSI_STATUS_ERROR;
goto ckc_e;
} else if (status == SCSI_STAT_QUEUEFULL) {
bval = (u_int8_t) pDCB->GoingSRBCnt;
bval--;
- pDCB->MaxCommand = bval;
+ pDCB->MaxActiveCommandCnt = bval;
trm_RewaitSRB(pDCB, pSRB);
pSRB->AdaptStatus = 0;
pSRB->TargetStatus = 0;
- pcsio->scsi_status = SCSI_STAT_QUEUEFULL;
- pccb->ccb_h.status = CAM_SCSI_STATUS_ERROR;
- goto ckc_e;
+ return;
} else if (status == SCSI_STAT_SEL_TIMEOUT) {
pSRB->AdaptStatus = H_SEL_TIMEOUT;
pSRB->TargetStatus = 0;
@@ -2401,20 +2576,20 @@ trm_SRBdone(PACB pACB, PDCB pDCB, PSRB pSRB)
__FILE__, __LINE__);
pcsio->scsi_status = SCSI_STAT_BUSY;
pccb->ccb_h.status = CAM_SCSI_BUSY;
+ return;
/* The device busy, try again later? */
} else if (status == SCSI_STAT_RESCONFLICT) {
TRM_DPRINTF("trm: target reserved at %s %d\n",
__FILE__, __LINE__);
pcsio->scsi_status = SCSI_STAT_RESCONFLICT;
pccb->ccb_h.status = CAM_SCSI_STATUS_ERROR; /*XXX*/
+ return;
} else {
pSRB->AdaptStatus = 0;
if (pSRB->RetryCnt) {
pSRB->RetryCnt--;
pSRB->TargetStatus = 0;
pSRB->SRBSGIndex = 0;
- pSRB->SRBSGListPointer = (PSEG)
- &pSRB->SegmentX[0];
if (trm_StartSCSI(pACB, pDCB, pSRB)) {
/*
* If trm_StartSCSI return 1 :
@@ -2506,6 +2681,7 @@ NO_DEV:
pACB->pLinkDCB = pTempDCB->pNextDCB;
if (pACB->pDCBRunRobin == pDCB)
pACB->pDCBRunRobin = pTempDCB->pNextDCB;
+ pDCB->DCBstatus &= ~DS_IN_QUEUE;
pACB->DeviceCnt--;
if (pACB->DeviceCnt == 0) {
pACB->pLinkDCB = NULL;
@@ -2530,11 +2706,11 @@ NO_DEV:
(pDCB->DevMode & EN_DISCONNECT_)) {
if (pDCB->DevMode &
TAG_QUEUING_) {
- pDCB->MaxCommand =
+ pDCB->
+ MaxActiveCommandCnt =
pACB->TagMaxNum;
pDCB->SyncMode |=
EN_TAG_QUEUING;
- pDCB->TagMask = 0;
pDCB->tinfo.disc_tag |=
TRM_CUR_TAGENB;
} else {
@@ -2601,7 +2777,6 @@ trm_DoingSRB_Done(PACB pACB)
}
pdcb->GoingSRBCnt = 0;;
pdcb->pGoingSRB = NULL;
- pdcb->TagMask = 0;
pdcb = pdcb->pNextDCB;
}
while (pdcb != pDCB);
@@ -2673,11 +2848,10 @@ trm_RequestSense(PACB pACB, PDCB pDCB, PSRB pSRB)
/* $$$$$$ Status of initiator/target $$$$$$$$ */
pSRB->SRBTotalXferLength = sizeof(pcsio->sense_data);
- pSRB->SgSenseTemp.address = pSRB->SegmentX[0].address;
- pSRB->SgSenseTemp.length = pSRB->SegmentX[0].length;
- pSRB->SegmentX[0].address = (u_long) vtophys(&pcsio->sense_data);
- pSRB->SegmentX[0].length = (u_long) pcsio->sense_len;
- pSRB->SRBSGListPointer = &pSRB->SegmentX[0];
+ pSRB->SgSenseTemp.address = pSRB->pSRBSGL->address;
+ pSRB->SgSenseTemp.length = pSRB->pSRBSGL->length;
+ pSRB->pSRBSGL->address = trm_get_sense_bufaddr(pACB, pSRB);
+ pSRB->pSRBSGL->length = (u_long) sizeof(struct scsi_sense_data);
pSRB->SRBSGCount = 1;
pSRB->SRBSGIndex = 0;
@@ -2723,6 +2897,15 @@ trm_initDCB(PACB pACB, PDCB pDCB, u_int16_t unit,u_int32_t i,u_int32_t j)
target_id = i;
target_lun = j;
+ /*
+ * Using the lun 0 device to init other DCB first, if the device
+ * has been initialized.
+ * I don't want init sync arguments one by one, it is the same.
+ */
+ if (target_lun != 0 &&
+ (pACB->DCBarray[target_id][0].DCBstatus & DS_IN_QUEUE))
+ bcopy(&pACB->DCBarray[target_id][0], pDCB,
+ sizeof(TRM_DCB));
intflag = splcam();
if (pACB->pLinkDCB == 0) {
pACB->pLinkDCB = pDCB;
@@ -2746,16 +2929,15 @@ trm_initDCB(PACB pACB, PDCB pDCB, u_int16_t unit,u_int32_t i,u_int32_t j)
splx(intflag);
pACB->DeviceCnt++;
- pDCB->pDCBACB = pACB;
pDCB->TargetID = target_id;
pDCB->TargetLUN = target_lun;
pDCB->pWaitingSRB = NULL;
pDCB->pGoingSRB = NULL;
pDCB->GoingSRBCnt = 0;
pDCB->pActiveSRB = NULL;
- pDCB->TagMask = 0;
- pDCB->MaxCommand = 1;
+ pDCB->MaxActiveCommandCnt = 1;
pDCB->DCBFlag = 0;
+ pDCB->DCBstatus |= DS_IN_QUEUE;
/* $$$$$$$ */
pEEpromBuf = &trm_eepromBuf[unit];
pDCB->DevMode = pEEpromBuf->NvramTarget[target_id].NvmTarCfg0;
@@ -2773,6 +2955,9 @@ trm_initDCB(PACB pACB, PDCB pDCB, u_int16_t unit,u_int32_t i,u_int32_t j)
}
bval |= target_lun;
pDCB->IdentifyMsg = bval;
+ if (target_lun != 0 &&
+ (pACB->DCBarray[target_id][0].DCBstatus & DS_IN_QUEUE))
+ return;
/* $$$$$$$ */
/*
* tag Qing enable ?
@@ -2788,7 +2973,15 @@ trm_initDCB(PACB pACB, PDCB pDCB, u_int16_t unit,u_int32_t i,u_int32_t j)
pDCB->SyncPeriod = 0;
pDCB->SyncOffset = 0;
PeriodIndex = pEEpromBuf->NvramTarget[target_id].NvmTarPeriod & 0x07;
- pDCB->MaxNegoPeriod = dc395x_trm_clock_period[ PeriodIndex ] ;
+ if (pACB->AdaptType==1) {/* is U2? */
+ pDCB->MaxNegoPeriod=dc395u2x_clock_period[ PeriodIndex ];
+ pDCB->tinfo.user.period=pDCB->MaxNegoPeriod;
+ pDCB->tinfo.user.offset=(pDCB->SyncMode & SYNC_NEGO_ENABLE) ? 31 : 0;
+ } else {
+ pDCB->MaxNegoPeriod=dc395x_clock_period[ PeriodIndex ];
+ pDCB->tinfo.user.period=pDCB->MaxNegoPeriod;
+ pDCB->tinfo.user.offset=(pDCB->SyncMode & SYNC_NEGO_ENABLE) ? 15 : 0;
+ }
pDCB->SyncMode = 0;
if ((pDCB->DevMode & NTC_DO_WIDE_NEGO) &&
(pACB->Config & HCC_WIDE_CARD))
@@ -2801,8 +2994,6 @@ trm_initDCB(PACB pACB, PDCB pDCB, u_int16_t unit,u_int32_t i,u_int32_t j)
/*
* Fill in tinfo structure.
*/
- pDCB->tinfo.user.period = pDCB->MaxNegoPeriod;
- pDCB->tinfo.user.offset = (pDCB->SyncMode & SYNC_NEGO_ENABLE) ? 15 : 0;
pDCB->tinfo.user.width = (pDCB->SyncMode & WIDE_NEGO_ENABLE) ?
MSG_EXT_WDTR_BUS_16_BIT : MSG_EXT_WDTR_BUS_8_BIT;
@@ -2811,42 +3002,83 @@ trm_initDCB(PACB pACB, PDCB pDCB, u_int16_t unit,u_int32_t i,u_int32_t j)
pDCB->tinfo.current.width = MSG_EXT_WDTR_BUS_8_BIT;
}
-static void
-trm_initSRB(PSRB psrb)
+static void
+trm_srbmapSG(void *arg, bus_dma_segment_t *segs, int nseg, int error)
{
-
- psrb->PhysSRB = vtophys(psrb);
+ PSRB pSRB;
+
+ pSRB=(PSRB) arg;
+ pSRB->SRBSGPhyAddr=segs->ds_addr;
+ return;
}
static void
-trm_linkSRB(PACB pACB)
+trm_destroySRB(PACB pACB)
{
- u_int16_t i;
+ PSRB pSRB;
+
+ pSRB = pACB->pFreeSRB;
+ while (pSRB) {
+ if (pSRB->sg_dmamap) {
+ bus_dmamap_unload(pACB->sg_dmat, pSRB->sg_dmamap);
+ bus_dmamem_free(pACB->sg_dmat, pSRB->pSRBSGL,
+ pSRB->sg_dmamap);
+ bus_dmamap_destroy(pACB->sg_dmat, pSRB->sg_dmamap);
+ }
+ if (pSRB->dmamap)
+ bus_dmamap_destroy(pACB->buffer_dmat, pSRB->dmamap);
+ pSRB = pSRB->pNextSRB;
+ }
+}
+
+static int
+trm_initSRB(PACB pACB)
+{
+ u_int16_t i;
+ PSRB pSRB;
+ int error;
+
+ for (i = 0; i < TRM_MAX_SRB_CNT; i++) {
+ pSRB = (PSRB)&pACB->pFreeSRB[i];
- for (i = 0; i < MAX_SRB_CNT; i++) {
- if (i != MAX_SRB_CNT - 1)
+ if (bus_dmamem_alloc(pACB->sg_dmat, (void **)&pSRB->pSRBSGL,
+ BUS_DMA_NOWAIT, &pSRB->sg_dmamap) !=0 ) {
+ return ENXIO;
+ }
+ bus_dmamap_load(pACB->sg_dmat, pSRB->sg_dmamap, pSRB->pSRBSGL,
+ TRM_MAX_SG_LISTENTRY * sizeof(SGentry),
+ trm_srbmapSG, pSRB, /*flags*/0);
+ if (i != TRM_MAX_SRB_CNT - 1) {
/*
* link all SRB
*/
- pACB->SRB_array[i].pNextSRB = &pACB->SRB_array[i+1];
- else
+ pSRB->pNextSRB = &pACB->pFreeSRB[i+1];
+ } else {
/*
* load NULL to NextSRB of the last SRB
*/
- pACB->SRB_array[i].pNextSRB = NULL;
- /*
- * convert and save physical address of SRB to pSRB->PhysSRB
- */
- trm_initSRB((PSRB) &pACB->SRB_array[i]);
+ pSRB->pNextSRB = NULL;
+ }
+ pSRB->TagNumber = i;
+
+ /*
+ * Create the dmamap. This is no longer optional!
+ */
+ if ((error = bus_dmamap_create(pACB->buffer_dmat, 0,
+ &pSRB->dmamap)) != 0)
+ return (error);
+
}
+ return (0);
}
+
+
static void
-trm_initACB(PACB pACB, u_int16_t unit)
+trm_initACB(PACB pACB, u_int8_t adaptType, u_int16_t unit)
{
PNVRAMTYPE pEEpromBuf;
- u_int16_t i,j;
pEEpromBuf = &trm_eepromBuf[unit];
pACB->max_id = 15;
@@ -2858,50 +3090,21 @@ trm_initACB(PACB pACB, u_int16_t unit)
TRM_DPRINTF("trm: pACB->max_id= %d pACB->max_lun= %d \n",
pACB->max_id, pACB->max_lun);
-
pACB->pLinkDCB = NULL;
pACB->pDCBRunRobin = NULL;
pACB->pActiveDCB = NULL;
- pACB->pFreeSRB = pACB->SRB_array;
- pACB->AdapterUnit = unit;
+ pACB->AdapterUnit = (u_int8_t)unit;
pACB->AdaptSCSIID = pEEpromBuf->NvramScsiId;
pACB->AdaptSCSILUN = 0;
pACB->DeviceCnt = 0;
- pACB->TagMaxNum = 2 << pEEpromBuf->NvramMaxTag ;
+ pACB->AdaptType = adaptType;
+ pACB->TagMaxNum = 2 << pEEpromBuf->NvramMaxTag;
pACB->ACBFlag = 0;
- /*
- * link all device's SRB Q of this adapter
- */
- trm_linkSRB(pACB);
- /*
- * temp SRB for Q tag used or abord command used
- */
- pACB->pTmpSRB = &pACB->TmpSRB;
- /*
- * convert and save physical address of SRB to pSRB->PhysSRB
- */
- trm_initSRB(pACB->pTmpSRB);
- /* allocate DCB array for scan device */
- for (i = 0; i < (pACB->max_id +1); i++) {
- if (pACB->AdaptSCSIID != i) {
- for (j = 0; j < (pACB->max_lun +1); j++) {
- pACB->scan_devices[i][j] = 1;
- pACB->pDCB[i][j]= (PDCB) malloc (
- sizeof (struct _DCB), M_DEVBUF, M_WAITOK);
- trm_initDCB(pACB,
- pACB->pDCB[i][j], unit, i, j);
- TRM_DPRINTF("pDCB= %8x \n",
- (u_int)pACB->pDCB[i][j]);
- }
- }
- }
- TRM_DPRINTF("sizeof(struct _DCB)= %8x \n",sizeof(struct _DCB));
- TRM_DPRINTF("sizeof(struct _ACB)= %8x \n",sizeof(struct _ACB));
- TRM_DPRINTF("sizeof(struct _SRB)= %8x \n",sizeof(struct _SRB));
+ return;
}
static void
-TRM_write_all(PNVRAMTYPE pEEpromBuf,PACB pACB)
+NVRAM_trm_write_all(PNVRAMTYPE pEEpromBuf,PACB pACB)
{
u_int8_t *bpEeprom = (u_int8_t *) pEEpromBuf;
u_int8_t bAddr;
@@ -2912,18 +3115,18 @@ TRM_write_all(PNVRAMTYPE pEEpromBuf,PACB pACB)
/*
* Write enable
*/
- TRM_write_cmd(pACB, 0x04, 0xFF);
+ NVRAM_trm_write_cmd(pACB, 0x04, 0xFF);
trm_reg_write8(0, TRMREG_GEN_NVRAM);
- TRM_wait_30us(pACB);
+ NVRAM_trm_wait_30us(pACB);
for (bAddr = 0; bAddr < 128; bAddr++, bpEeprom++) {
- TRM_set_data(pACB, bAddr, *bpEeprom);
+ NVRAM_trm_set_data(pACB, bAddr, *bpEeprom);
}
/*
* Write disable
*/
- TRM_write_cmd(pACB, 0x04, 0x00);
+ NVRAM_trm_write_cmd(pACB, 0x04, 0x00);
trm_reg_write8(0 , TRMREG_GEN_NVRAM);
- TRM_wait_30us(pACB);
+ NVRAM_trm_wait_30us(pACB);
/* Disable SEEPROM */
trm_reg_write8((trm_reg_read8(TRMREG_GEN_CONTROL) & ~EN_EEPROM),
TRMREG_GEN_CONTROL);
@@ -2931,7 +3134,7 @@ TRM_write_all(PNVRAMTYPE pEEpromBuf,PACB pACB)
}
static void
-TRM_set_data(PACB pACB, u_int8_t bAddr, u_int8_t bData)
+NVRAM_trm_set_data(PACB pACB, u_int8_t bAddr, u_int8_t bData)
{
int i;
u_int8_t bSendData;
@@ -2939,7 +3142,7 @@ TRM_set_data(PACB pACB, u_int8_t bAddr, u_int8_t bData)
* Send write command & address
*/
- TRM_write_cmd(pACB, 0x05, bAddr);
+ NVRAM_trm_write_cmd(pACB, 0x05, bAddr);
/*
* Write data
*/
@@ -2949,27 +3152,27 @@ TRM_set_data(PACB pACB, u_int8_t bAddr, u_int8_t bData)
/* Start from bit 7 */
bSendData |= NVR_BITOUT;
trm_reg_write8(bSendData , TRMREG_GEN_NVRAM);
- TRM_wait_30us(pACB);
+ NVRAM_trm_wait_30us(pACB);
trm_reg_write8((bSendData | NVR_CLOCK), TRMREG_GEN_NVRAM);
- TRM_wait_30us(pACB);
+ NVRAM_trm_wait_30us(pACB);
}
trm_reg_write8(NVR_SELECT , TRMREG_GEN_NVRAM);
- TRM_wait_30us(pACB);
+ NVRAM_trm_wait_30us(pACB);
/*
* Disable chip select
*/
trm_reg_write8(0 , TRMREG_GEN_NVRAM);
- TRM_wait_30us(pACB);
+ NVRAM_trm_wait_30us(pACB);
trm_reg_write8(NVR_SELECT ,TRMREG_GEN_NVRAM);
- TRM_wait_30us(pACB);
+ NVRAM_trm_wait_30us(pACB);
/*
* Wait for write ready
*/
while (1) {
trm_reg_write8((NVR_SELECT | NVR_CLOCK), TRMREG_GEN_NVRAM);
- TRM_wait_30us(pACB);
+ NVRAM_trm_wait_30us(pACB);
trm_reg_write8(NVR_SELECT, TRMREG_GEN_NVRAM);
- TRM_wait_30us(pACB);
+ NVRAM_trm_wait_30us(pACB);
if (trm_reg_read8(TRMREG_GEN_NVRAM) & NVR_BITIN) {
break;
}
@@ -2982,7 +3185,7 @@ TRM_set_data(PACB pACB, u_int8_t bAddr, u_int8_t bData)
}
static void
-TRM_read_all(PNVRAMTYPE pEEpromBuf, PACB pACB)
+NVRAM_trm_read_all(PNVRAMTYPE pEEpromBuf, PACB pACB)
{
u_int8_t *bpEeprom = (u_int8_t*) pEEpromBuf;
u_int8_t bAddr;
@@ -2993,7 +3196,7 @@ TRM_read_all(PNVRAMTYPE pEEpromBuf, PACB pACB)
trm_reg_write8((trm_reg_read8(TRMREG_GEN_CONTROL) | EN_EEPROM),
TRMREG_GEN_CONTROL);
for (bAddr = 0; bAddr < 128; bAddr++, bpEeprom++)
- *bpEeprom = TRM_get_data(pACB, bAddr);
+ *bpEeprom = NVRAM_trm_get_data(pACB, bAddr);
/*
* Disable SEEPROM
*/
@@ -3003,7 +3206,7 @@ TRM_read_all(PNVRAMTYPE pEEpromBuf, PACB pACB)
}
static u_int8_t
-TRM_get_data(PACB pACB, u_int8_t bAddr)
+NVRAM_trm_get_data(PACB pACB, u_int8_t bAddr)
{
int i;
u_int8_t bReadData, bData = 0;
@@ -3011,14 +3214,14 @@ TRM_get_data(PACB pACB, u_int8_t bAddr)
* Send read command & address
*/
- TRM_write_cmd(pACB, 0x06, bAddr);
+ NVRAM_trm_write_cmd(pACB, 0x06, bAddr);
for (i = 0; i < 8; i++) {
/*
* Read data
*/
trm_reg_write8((NVR_SELECT | NVR_CLOCK) , TRMREG_GEN_NVRAM);
- TRM_wait_30us(pACB);
+ NVRAM_trm_wait_30us(pACB);
trm_reg_write8(NVR_SELECT , TRMREG_GEN_NVRAM);
/*
* Get data bit while falling edge
@@ -3028,7 +3231,7 @@ TRM_get_data(PACB pACB, u_int8_t bAddr)
if (bReadData & NVR_BITIN) {
bData |= 1;
}
- TRM_wait_30us(pACB);
+ NVRAM_trm_wait_30us(pACB);
}
/*
* Disable chip select
@@ -3038,7 +3241,7 @@ TRM_get_data(PACB pACB, u_int8_t bAddr)
}
static void
-TRM_wait_30us(PACB pACB)
+NVRAM_trm_wait_30us(PACB pACB)
{
/* ScsiPortStallExecution(30); wait 30 us */
@@ -3048,7 +3251,7 @@ TRM_wait_30us(PACB pACB)
}
static void
-TRM_write_cmd(PACB pACB, u_int8_t bCmd, u_int8_t bAddr)
+NVRAM_trm_write_cmd(PACB pACB, u_int8_t bCmd, u_int8_t bAddr)
{
int i;
u_int8_t bSendData;
@@ -3062,9 +3265,9 @@ TRM_write_cmd(PACB pACB, u_int8_t bCmd, u_int8_t bAddr)
bSendData |= NVR_BITOUT;
/* start from bit 2 */
trm_reg_write8(bSendData, TRMREG_GEN_NVRAM);
- TRM_wait_30us(pACB);
+ NVRAM_trm_wait_30us(pACB);
trm_reg_write8((bSendData | NVR_CLOCK), TRMREG_GEN_NVRAM);
- TRM_wait_30us(pACB);
+ NVRAM_trm_wait_30us(pACB);
}
for (i = 0; i < 7; i++, bAddr <<= 1) {
/*
@@ -3075,12 +3278,12 @@ TRM_write_cmd(PACB pACB, u_int8_t bCmd, u_int8_t bAddr)
/* Start from bit 6 */
bSendData |= NVR_BITOUT;
trm_reg_write8(bSendData , TRMREG_GEN_NVRAM);
- TRM_wait_30us(pACB);
+ NVRAM_trm_wait_30us(pACB);
trm_reg_write8((bSendData | NVR_CLOCK), TRMREG_GEN_NVRAM);
- TRM_wait_30us(pACB);
+ NVRAM_trm_wait_30us(pACB);
}
trm_reg_write8(NVR_SELECT, TRMREG_GEN_NVRAM);
- TRM_wait_30us(pACB);
+ NVRAM_trm_wait_30us(pACB);
}
static void
@@ -3090,7 +3293,7 @@ trm_check_eeprom(PNVRAMTYPE pEEpromBuf, PACB pACB)
u_int16_t wAddr, wCheckSum;
u_long dAddr, *dpEeprom;
- TRM_read_all(pEEpromBuf,pACB);
+ NVRAM_trm_read_all(pEEpromBuf,pACB);
wCheckSum = 0;
for (wAddr = 0, wpEeprom = (u_int16_t *) pEEpromBuf;
wAddr < 64; wAddr++, wpEeprom++) {
@@ -3132,12 +3335,12 @@ trm_check_eeprom(PNVRAMTYPE pEEpromBuf, PACB pACB)
wAddr < 63; wAddr++, wpEeprom++)
wCheckSum += *wpEeprom;
*wpEeprom = 0x1234 - wCheckSum;
- TRM_write_all(pEEpromBuf,pACB);
+ NVRAM_trm_write_all(pEEpromBuf,pACB);
}
return;
}
static int
-trm_initAdapter(PACB pACB, u_int16_t unit, device_t pci_config_id)
+trm_initAdapter(PACB pACB, u_int16_t unit)
{
PNVRAMTYPE pEEpromBuf;
u_int16_t wval;
@@ -3184,76 +3387,203 @@ trm_initAdapter(PACB pACB, u_int16_t unit, device_t pci_config_id)
return (0);
}
+static void
+trm_mapSRB(void *arg, bus_dma_segment_t *segs, int nseg, int error)
+{
+ PACB pACB;
+
+ pACB = (PACB)arg;
+ pACB->srb_physbase = segs->ds_addr;
+}
+
+static void
+trm_dmamap_cb(void *arg, bus_dma_segment_t *segs, int nseg, int error)
+{
+ bus_addr_t *baddr;
+
+ baddr = (bus_addr_t *)arg;
+ *baddr = segs->ds_addr;
+}
+
static PACB
-trm_init(u_int16_t unit, device_t pci_config_id)
+trm_init(u_int16_t unit, device_t dev)
{
PACB pACB;
- int rid = PCIR_MAPS;
+ int rid = PCIR_BAR(0), i = 0, j = 0;
+ u_int16_t adaptType = 0;
- pACB = (PACB) device_get_softc(pci_config_id);
+ pACB = (PACB) device_get_softc(dev);
if (!pACB) {
printf("trm%d: cannot allocate ACB !\n", unit);
return (NULL);
}
- bzero (pACB, sizeof (struct _ACB));
- pACB->iores = bus_alloc_resource(pci_config_id, SYS_RES_IOPORT,
- &rid, 0, ~0, 1, RF_ACTIVE);
+ pACB->iores = bus_alloc_resource_any(dev, SYS_RES_IOPORT,
+ &rid, RF_ACTIVE);
if (pACB->iores == NULL) {
printf("trm_init: bus_alloc_resource failed!\n");
return (NULL);
}
+ switch (pci_get_devid(dev)) {
+ case PCI_DEVICEID_TRMS1040:
+ adaptType = 0;
+ break;
+ case PCI_DEVICEID_TRMS2080:
+ adaptType = 1;
+ break;
+ default:
+ printf("trm_init %d: unknown adapter type!\n", unit);
+ goto bad;
+ }
+ pACB->dev = dev;
pACB->tag = rman_get_bustag(pACB->iores);
pACB->bsh = rman_get_bushandle(pACB->iores);
- if (bus_dma_tag_create(/*parent_dmat*/ NULL,
- /*alignment*/ 1,
- /*boundary*/ 0,
- /*lowaddr*/ BUS_SPACE_MAXADDR_32BIT,
- /*highaddr*/ BUS_SPACE_MAXADDR,
- /*filter*/ NULL,
- /*filterarg*/ NULL,
- /*maxsize*/ MAXBSIZE,
- /*nsegments*/ TRM_NSEG,
- /*maxsegsz*/ TRM_MAXTRANSFER_SIZE,
- /*flags*/ BUS_DMA_ALLOCNOW,
- &pACB->buffer_dmat) != 0)
+ if (bus_dma_tag_create(
+ /*parent_dmat*/ pACB->parent_dmat,
+ /*alignment*/ 1,
+ /*boundary*/ 0,
+ /*lowaddr*/ BUS_SPACE_MAXADDR,
+ /*highaddr*/ BUS_SPACE_MAXADDR,
+ /*filter*/ NULL,
+ /*filterarg*/ NULL,
+ /*maxsize*/ MAXBSIZE,
+ /*nsegments*/ TRM_NSEG,
+ /*maxsegsz*/ TRM_MAXTRANSFER_SIZE,
+ /*flags*/ BUS_DMA_ALLOCNOW,
+ /* dmat */ &pACB->buffer_dmat) != 0)
+ goto bad;
+ /* DMA tag for our ccb structures */
+ if (bus_dma_tag_create(
+ /*parent_dmat*/pACB->parent_dmat,
+ /*alignment*/ 1,
+ /*boundary*/ 0,
+ /*lowaddr*/ BUS_SPACE_MAXADDR,
+ /*highaddr*/ BUS_SPACE_MAXADDR,
+ /*filter*/ NULL,
+ /*filterarg*/ NULL,
+ /*maxsize*/ TRM_MAX_SRB_CNT * sizeof(TRM_SRB),
+ /*nsegments*/ 1,
+ /*maxsegsz*/ TRM_MAXTRANSFER_SIZE,
+ /*flags*/ 0,
+ /*dmat*/ &pACB->srb_dmat) != 0) {
+ printf("trm_init %d: bus_dma_tag_create SRB failure\n", unit);
+ goto bad;
+ }
+ if (bus_dmamem_alloc(pACB->srb_dmat, (void **)&pACB->pFreeSRB,
+ BUS_DMA_NOWAIT, &pACB->srb_dmamap) != 0) {
+ printf("trm_init %d: bus_dmamem_alloc SRB failure\n", unit);
goto bad;
+ }
+ bus_dmamap_load(pACB->srb_dmat, pACB->srb_dmamap, pACB->pFreeSRB,
+ TRM_MAX_SRB_CNT * sizeof(TRM_SRB), trm_mapSRB, pACB,
+ /* flags */0);
+ /* Create, allocate, and map DMA buffers for autosense data */
+ if (bus_dma_tag_create(/*parent_dmat*/NULL, /*alignment*/1,
+ /*boundary*/0,
+ /*lowaddr*/BUS_SPACE_MAXADDR_32BIT,
+ /*highaddr*/BUS_SPACE_MAXADDR,
+ /*filter*/NULL, /*filterarg*/NULL,
+ sizeof(struct scsi_sense_data) * TRM_MAX_SRB_CNT,
+ /*nsegments*/1,
+ /*maxsegsz*/TRM_MAXTRANSFER_SIZE,
+ /*flags*/0,
+ &pACB->sense_dmat) != 0) {
+ if (bootverbose)
+ device_printf(dev, "cannot create sense buffer dmat\n");
+ goto bad;
+ }
+
+ if (bus_dmamem_alloc(pACB->sense_dmat, (void **)&pACB->sense_buffers,
+ BUS_DMA_NOWAIT, &pACB->sense_dmamap) != 0)
+ goto bad;
+
+ bus_dmamap_load(pACB->sense_dmat, pACB->sense_dmamap,
+ pACB->sense_buffers,
+ sizeof(struct scsi_sense_data) * TRM_MAX_SRB_CNT,
+ trm_dmamap_cb, &pACB->sense_busaddr, /*flags*/0);
+
trm_check_eeprom(&trm_eepromBuf[unit],pACB);
- trm_initACB(pACB, unit);
- if (trm_initAdapter(pACB, unit, pci_config_id)) {
+ trm_initACB(pACB, adaptType, unit);
+ for (i = 0; i < (pACB->max_id + 1); i++) {
+ if (pACB->AdaptSCSIID == i)
+ continue;
+ for(j = 0; j < (pACB->max_lun + 1); j++) {
+ pACB->scan_devices[i][j] = 1;
+ /* we assume we need to scan all devices */
+ trm_initDCB(pACB, &pACB->DCBarray[i][j], unit, i, j);
+ }
+ }
+ bzero(pACB->pFreeSRB, TRM_MAX_SRB_CNT * sizeof(TRM_SRB));
+ if (bus_dma_tag_create(
+ /*parent_dmat*/NULL,
+ /*alignment*/ 1,
+ /*boundary*/ 0,
+ /*lowaddr*/ BUS_SPACE_MAXADDR,
+ /*highaddr*/ BUS_SPACE_MAXADDR,
+ /*filter*/ NULL,
+ /*filterarg*/ NULL,
+ /*maxsize*/ TRM_MAX_SG_LISTENTRY * sizeof(SGentry),
+ /*nsegments*/ 1,
+ /*maxsegsz*/ TRM_MAXTRANSFER_SIZE,
+ /*flags*/ 0,
+ /*dmat*/ &pACB->sg_dmat) != 0)
+ goto bad;
+
+ if (trm_initSRB(pACB)) {
+ printf("trm_initSRB: error\n");
+ goto bad;
+ }
+ if (trm_initAdapter(pACB, unit)) {
printf("trm_initAdapter: initial ERROR\n");
goto bad;
}
return (pACB);
bad:
if (pACB->iores)
- bus_release_resource(pci_config_id, SYS_RES_IOPORT, PCIR_MAPS,
+ bus_release_resource(dev, SYS_RES_IOPORT, PCIR_BAR(0),
pACB->iores);
+ if (pACB->sense_dmamap) {
+ bus_dmamap_unload(pACB->sense_dmat, pACB->sense_dmamap);
+ bus_dmamem_free(pACB->sense_dmat, pACB->sense_buffers,
+ pACB->sense_dmamap);
+ bus_dmamap_destroy(pACB->sense_dmat, pACB->sense_dmamap);
+ }
+ if (pACB->sense_dmat)
+ bus_dma_tag_destroy(pACB->sense_dmat);
+ if (pACB->sg_dmat) {
+ trm_destroySRB(pACB);
+ bus_dma_tag_destroy(pACB->sg_dmat);
+ }
+ if (pACB->srb_dmamap) {
+ bus_dmamap_unload(pACB->srb_dmat, pACB->srb_dmamap);
+ bus_dmamem_free(pACB->srb_dmat, pACB->pFreeSRB,
+ pACB->srb_dmamap);
+ bus_dmamap_destroy(pACB->srb_dmat, pACB->srb_dmamap);
+ }
+ if (pACB->srb_dmat)
+ bus_dma_tag_destroy(pACB->srb_dmat);
if (pACB->buffer_dmat)
bus_dma_tag_destroy(pACB->buffer_dmat);
return (NULL);
}
static int
-trm_attach(device_t pci_config_id)
+trm_attach(device_t dev)
{
struct cam_devq *device_Q;
u_long device_id;
PACB pACB = 0;
int rid = 0;
- int unit = device_get_unit(pci_config_id);
+ int unit = device_get_unit(dev);
- device_id = pci_get_devid(pci_config_id);
+ device_id = pci_get_devid(dev);
/*
* These cards do not allow memory mapped accesses
*/
- if (device_id == PCI_DEVICEID_TRMS1040) {
- if ((pACB=trm_init((u_int16_t) unit,
- pci_config_id)) == NULL) {
- printf("trm%d: trm_init error!\n",unit);
- return (ENXIO);
- }
- } else
+ if ((pACB = trm_init((u_int16_t) unit,
+ dev)) == NULL) {
+ printf("trm%d: trm_init error!\n",unit);
return (ENXIO);
+ }
/* After setting up the adapter, map our interrupt */
/*
* Now let the CAM generic SCSI layer find the SCSI devices on the bus
@@ -3261,15 +3591,15 @@ trm_attach(device_t pci_config_id)
* Create device queue of SIM(s)
* (MAX_START_JOB - 1) : max_sim_transactions
*/
- pACB->irq = bus_alloc_resource(pci_config_id, SYS_RES_IRQ, &rid, 0,
- ~0, 1, RF_SHAREABLE | RF_ACTIVE);
+ pACB->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
+ RF_SHAREABLE | RF_ACTIVE);
if (pACB->irq == NULL ||
- bus_setup_intr(pci_config_id, pACB->irq,
+ bus_setup_intr(dev, pACB->irq,
INTR_TYPE_CAM, trm_Interrupt, pACB, &pACB->ih)) {
printf("trm%d: register Interrupt handler error!\n", unit);
goto bad;
}
- device_Q = cam_simq_alloc(MAX_START_JOB);
+ device_Q = cam_simq_alloc(TRM_MAX_START_JOB);
if (device_Q == NULL){
printf("trm%d: device_Q == NULL !\n",unit);
goto bad;
@@ -3306,7 +3636,7 @@ trm_attach(device_t pci_config_id)
pACB,
unit,
1,
- MAX_TAGS_CMD_QUEUE,
+ TRM_MAX_TAGS_CMD_QUEUE,
device_Q);
if (pACB->psim == NULL) {
printf("trm%d: SIM allocate fault !\n",unit);
@@ -3325,23 +3655,39 @@ trm_attach(device_t pci_config_id)
printf("trm%d: xpt_create_path fault !\n",unit);
xpt_bus_deregister(cam_sim_path(pACB->psim));
goto bad;
- /*
- * cam_sim_free(pACB->psim, TRUE); free_devq
- * pACB->psim = NULL;
- */
- return (ENXIO);
}
return (0);
bad:
if (pACB->iores)
- bus_release_resource(pci_config_id, SYS_RES_IOPORT, PCIR_MAPS,
+ bus_release_resource(dev, SYS_RES_IOPORT, PCIR_BAR(0),
pACB->iores);
+ if (pACB->sg_dmat) {
+ trm_destroySRB(pACB);
+ bus_dma_tag_destroy(pACB->sg_dmat);
+ }
+
+ if (pACB->srb_dmamap) {
+ bus_dmamap_unload(pACB->srb_dmat, pACB->srb_dmamap);
+ bus_dmamem_free(pACB->srb_dmat, pACB->pFreeSRB,
+ pACB->srb_dmamap);
+ bus_dmamap_destroy(pACB->srb_dmat, pACB->srb_dmamap);
+ }
+ if (pACB->srb_dmat)
+ bus_dma_tag_destroy(pACB->srb_dmat);
+ if (pACB->sense_dmamap) {
+ bus_dmamap_unload(pACB->sense_dmat, pACB->sense_dmamap);
+ bus_dmamem_free(pACB->sense_dmat, pACB->sense_buffers,
+ pACB->sense_dmamap);
+ bus_dmamap_destroy(pACB->sense_dmat, pACB->sense_dmamap);
+ }
+ if (pACB->sense_dmat)
+ bus_dma_tag_destroy(pACB->sense_dmat);
if (pACB->buffer_dmat)
bus_dma_tag_destroy(pACB->buffer_dmat);
if (pACB->ih)
- bus_teardown_intr(pci_config_id, pACB->irq, pACB->ih);
+ bus_teardown_intr(dev, pACB->irq, pACB->ih);
if (pACB->irq)
- bus_release_resource(pci_config_id, SYS_RES_IRQ, 0, pACB->irq);
+ bus_release_resource(dev, SYS_RES_IRQ, 0, pACB->irq);
if (pACB->psim)
cam_sim_free(pACB->psim, TRUE);
@@ -3355,15 +3701,20 @@ bad:
*
*/
static int
-trm_probe(device_t tag)
+trm_probe(device_t dev)
{
-
- if (pci_get_devid(tag) == PCI_DEVICEID_TRMS1040) {
- device_set_desc(tag,
+ switch (pci_get_devid(dev)) {
+ case PCI_DEVICEID_TRMS1040:
+ device_set_desc(dev,
"Tekram DC395U/UW/F DC315/U Fast20 Wide SCSI Adapter");
return (0);
- } else
+ case PCI_DEVICEID_TRMS2080:
+ device_set_desc(dev,
+ "Tekram DC395U2D/U2W Fast40 Wide SCSI Adapter");
+ return 0;
+ default:
return (ENXIO);
+ }
}
static int
@@ -3371,8 +3722,20 @@ trm_detach(device_t dev)
{
PACB pACB = device_get_softc(dev);
- bus_release_resource(dev, SYS_RES_IOPORT, PCIR_MAPS, pACB->iores);
- bus_dma_tag_destroy(pACB->buffer_dmat);
+ bus_release_resource(dev, SYS_RES_IOPORT, PCIR_BAR(0), pACB->iores);
+ trm_destroySRB(pACB);
+ bus_dma_tag_destroy(pACB->sg_dmat);
+ bus_dmamap_unload(pACB->srb_dmat, pACB->srb_dmamap);
+ bus_dmamem_free(pACB->srb_dmat, pACB->pFreeSRB,
+ pACB->srb_dmamap);
+ bus_dmamap_destroy(pACB->srb_dmat, pACB->srb_dmamap);
+ bus_dma_tag_destroy(pACB->srb_dmat);
+ bus_dmamap_unload(pACB->sense_dmat, pACB->sense_dmamap);
+ bus_dmamem_free(pACB->sense_dmat, pACB->sense_buffers,
+ pACB->sense_dmamap);
+ bus_dmamap_destroy(pACB->sense_dmat, pACB->sense_dmamap);
+ bus_dma_tag_destroy(pACB->sense_dmat);
+ bus_dma_tag_destroy(pACB->buffer_dmat);
bus_teardown_intr(dev, pACB->irq, pACB->ih);
bus_release_resource(dev, SYS_RES_IRQ, 0, pACB->irq);
xpt_async(AC_LOST_DEVICE, pACB->ppath, NULL);
@@ -3395,3 +3758,4 @@ static driver_t trm_driver = {
static devclass_t trm_devclass;
DRIVER_MODULE(trm, pci, trm_driver, trm_devclass, 0, 0);
+MODULE_DEPEND(trm, cam, 1, 1, 1);
diff --git a/sys/dev/trm/trm.h b/sys/dev/trm/trm.h
index 1013db3cc0ab..e9eadbea8181 100644
--- a/sys/dev/trm/trm.h
+++ b/sys/dev/trm/trm.h
@@ -75,8 +75,8 @@ struct trm_target_info {
/*;----------------------Segment Entry------------------------------------*/
typedef struct _SGentry {
- u_long address;
- u_long length;
+ u_int32_t address;
+ u_int32_t length;
} SGentry, *PSEG;
/*
*-----------------------------------------------------------------------
@@ -84,14 +84,14 @@ typedef struct _SGentry {
*-----------------------------------------------------------------------
*/
-#define MAX_ADAPTER_NUM 4
-#define MAX_DEVICES 16
-#define MAX_SG_LISTENTRY 32
-#define MAX_TARGETS 16
-#define MAX_TAGS_CMD_QUEUE 32 /* MAX_CMD_QUEUE 20*/
-#define MAX_CMD_PER_LUN 32
-#define MAX_SRB_CNT MAX_CMD_PER_LUN*4
-#define MAX_START_JOB MAX_CMD_PER_LUN*4
+#define TRM_MAX_ADAPTER_NUM 4
+#define TRM_MAX_DEVICES 16
+#define TRM_MAX_SG_LISTENTRY 32
+#define TRM_MAX_TARGETS 16
+#define TRM_MAX_TAGS_CMD_QUEUE 256 /* MAX_CMD_QUEUE 20*/
+#define TRM_MAX_CMD_PER_LUN 32
+#define TRM_MAX_SRB_CNT 256
+#define TRM_MAX_START_JOB 256
#define TRM_NSEG (btoc(MAXPHYS) + 1)
#define TRM_MAXTRANSFER_SIZE 0xFFFFFF /* restricted by 24 bit counter */
#define PAGELEN 4096
@@ -142,19 +142,21 @@ struct _SRB {
u_int8_t CmdBlock[12];
u_long Segment0[2];
u_long Segment1[2];
- u_long PhysSRB;
struct _SRB *pNextSRB;
struct _DCB *pSRBDCB;
- SGentry SegmentX[MAX_SG_LISTENTRY];
SGentry SgSenseTemp;
+
+ PSEG pSRBSGL; /* scatter gather list */
+
+ u_int32_t SRBSGPhyAddr; /* a segment starting address */
+ u_int32_t SRBTotalXferLength;
+
/*
* CAM ccb
*/
- union ccb *pccb;
+ union ccb *pccb;
+ bus_dmamap_t sg_dmamap;
bus_dmamap_t dmamap;
- PSEG SRBSGListPointer; /* scatter gather list */
- u_long SRBTotalXferLength;
- u_long SRBSGPhyAddr; /* a segment starting address */
u_int16_t SRBState;
u_int8_t * pMsgPtr;
@@ -170,8 +172,6 @@ struct _SRB {
u_int8_t SRBStatus;
u_int8_t RetryCnt;
- /* b0-AutoReqSense,b6-Read,b7-write */
- /* b4-settimeout,b5-Residual valid */
u_int8_t SRBFlag;
u_int8_t ScsiCmdLen;
u_int8_t ScsiPhase;
@@ -186,25 +186,19 @@ typedef struct _SRB TRM_SRB, *PSRB;
*/
struct _DCB
{
- struct _DCB *pNextDCB;
- struct _ACB *pDCBACB;
-
PSRB pWaitingSRB;
- PSRB pWaitLastSRB;
+ PSRB pWaitingLastSRB;
PSRB pGoingSRB;
PSRB pGoingLastSRB;
PSRB pActiveSRB;
- PSRB RevSRB;
-
- u_long TagMask;
u_int16_t GoingSRBCnt;
- u_int16_t WaitSRBCnt;
+ u_int16_t MaxActiveCommandCnt;
- u_int8_t TargetID; /*; SCSI Target ID (SCSI Only) */
- u_int8_t TargetLUN; /*; SCSI Log. Unit (SCSI Only) */
+ u_int8_t TargetID; /*; SCSI Target ID (SCSI Only) */
+ u_int8_t TargetLUN; /*; SCSI Log. Unit (SCSI Only) */
u_int8_t DCBFlag;
u_int8_t DevType;
@@ -213,14 +207,14 @@ struct _DCB
u_int8_t SyncPeriod; /* for reg. */
u_int8_t SyncOffset; /* for reg. and nego.(low nibble) */
- struct trm_target_info tinfo; /* 10 bytes */
-
- u_int16_t MaxCommand;
u_int8_t DevMode;
u_int8_t AdpMode;
u_int8_t IdentifyMsg;
- u_int8_t Reserved[3]; /*for dword alignment */
+ u_int8_t DCBstatus; /* DCB status */
+ /*u_int8_t Reserved[3]; for dword alignment */
+ struct trm_target_info tinfo; /* 10 bytes */
+ struct _DCB *pNextDCB;
};
typedef struct _DCB TRM_DCB, *PDCB;
@@ -231,11 +225,19 @@ typedef struct _DCB TRM_DCB, *PDCB;
*/
struct _ACB
{
+ device_t dev;
+
bus_space_tag_t tag;
bus_space_handle_t bsh;
+ bus_dma_tag_t parent_dmat;
bus_dma_tag_t buffer_dmat; /* dmat for buffer I/O */
- struct _ACB *pNextACB;
-
+ bus_dma_tag_t srb_dmat;
+ bus_dma_tag_t sense_dmat; /* dmat for sense buffer */
+ bus_dma_tag_t sg_dmat;
+ bus_dmamap_t sense_dmamap;
+ bus_dmamap_t srb_dmamap;
+ bus_addr_t sense_busaddr;
+ struct scsi_sense_data *sense_buffers;
struct resource *iores, *irq;
void *ih;
/*
@@ -244,27 +246,20 @@ struct _ACB
struct cam_sim *psim;
struct cam_path *ppath;
- TRM_SRB SRB_array[MAX_SRB_CNT]; /* */
-
- TRM_SRB TmpSRB;
-
- PSRB pTmpSRB;
- PSRB RevSRB;
+ TRM_SRB TmpSRB;
+ TRM_DCB DCBarray[16][8];
+ u_int32_t srb_physbase;
+
PSRB pFreeSRB;
PDCB pActiveDCB;
PDCB pLinkDCB;
PDCB pDCBRunRobin;
- PDCB pDCB[16][8];
-
u_int16_t max_id;
u_int16_t max_lun;
- u_int16_t IOPortBase;
- u_int16_t AdapterUnit; /*; nth Adapter this driver */
-
u_int8_t msgin123[4];
u_int8_t scan_devices[16][8];
@@ -276,7 +271,8 @@ struct _ACB
u_int8_t TagMaxNum;
u_int8_t Config;
- u_int8_t Reserved[2]; /* for dword alignment */
+ u_int8_t AdaptType;
+ u_int8_t AdapterUnit; /* nth Adapter this driver */
};
typedef struct _ACB TRM_ACB, *PACB;
/*
@@ -323,6 +319,11 @@ typedef struct _ACB TRM_ACB, *PACB;
#define ABORT_DEV_ 0x00000001
/*
+ * ---DCB status
+ */
+#define DS_IN_QUEUE 0x00000001
+
+/*
* ---SRB status
*/
#define SRB_OK 0x00000001
@@ -414,12 +415,12 @@ typedef struct _ACB TRM_ACB, *PACB;
#define MSG_LINK_CMD_COMPL 0x0A
#define MSG_LINK_CMD_COMPL_FLG 0x0B
#define MSG_BUS_RESET 0x0C
-#define MSG_ABORT_TAG 0x0D
+/* #define MSG_ABORT_TAG 0x0D */
#define MSG_SIMPLE_QTAG 0x20
#define MSG_HEAD_QTAG 0x21
#define MSG_ORDER_QTAG 0x22
#define MSG_IGNOREWIDE 0x23
-#define MSG_IDENTIFY 0x80
+/* #define MSG_IDENTIFY 0x80 */
#define MSG_HOST_ID 0xC0
/* bus wide length */
#define MSG_EXT_WDTR_BUS_8_BIT 0x00
@@ -716,6 +717,7 @@ typedef struct _EEprom {
#define ACTIVE_NEGPLUS 0x10 /* Enhance active negation */
#define FILTER_DISABLE 0x08 /* Disable SCSI data filter */
#define ACTIVE_NEG 0x02 /* Enable active negation */
+#define ACTIVE_HISLEW 0x01 /* Enable high slew rate (3/6 ns) */
/*
***************************************
*/
@@ -778,19 +780,23 @@ typedef struct _EEprom {
/*
***************************************
*/
-#define TRMREG_SCSI_TCR0 0x9C /* SCSI Target Control 0 (R/W) */
+#define TRMREG_SCSI_TCR00 0x9C /* SCSI Target Control 0 (R/W) */
/* ######### */
-#define TCR0_WIDE_NEGO_DONE 0x8000 /* Wide nego done */
-#define TCR0_SYNC_NEGO_DONE 0x4000 /* Synchronous nego done*/
-#define TCR0_ENABLE_LVDS 0x2000 /* Enable LVDS synchronous*/
-#define TCR0_ENABLE_WIDE 0x1000 /* Enable WIDE synchronous*/
-#define TCR0_ENABLE_ALT 0x0800 /* Enable alternate synchronous */
-#define TCR0_PERIOD_MASK 0x0700 /* Transfer rate */
-
-#define TCR0_DO_WIDE_NEGO 0x0080 /* Do wide NEGO */
-#define TCR0_DO_SYNC_NEGO 0x0040 /* Do sync NEGO */
-#define TCR0_DISCONNECT_EN 0x0020 /* Disconnection enable */
-#define TCR0_OFFSET_MASK 0x001F /* Offset number */
+#define TCR0_DO_WIDE_NEGO 0x80 /* Do wide NEGO */
+#define TCR0_DO_SYNC_NEGO 0x40 /* Do sync NEGO */
+#define TCR0_DISCONNECT_EN 0x20 /* Disconnection enable */
+#define TCR0_OFFSET_MASK 0x1F /* Offset number */
+/*
+ ***************************************
+ */
+#define TRMREG_SCSI_TCR01 0x9D /* SCSI Target Control 0 (R/W) */
+/* ######### */
+#define TCR0_ENABLE_LVDS 0xF8 /* LVD */
+#define TCR0_ENABLE_WIDE 0xF9 /* SE */
+/*
+****************************************
+*/
+
/*
***************************************
*/
@@ -932,7 +938,7 @@ typedef struct NVRAM_STRUC {
u_int8_t NvramVendorID[2]; /*5,6 Vendor ID */
u_int8_t NvramDeviceID[2]; /*7,8 Device ID */
u_int8_t NvramReserved; /*9 Reserved */
- NVRAMTARGETTYPE NvramTarget[MAX_TARGETS];/* *10,11,12,13
+ NVRAMTARGETTYPE NvramTarget[TRM_MAX_TARGETS];/* *10,11,12,13
*14,15,16,17 * ....
* ....
*70,71,72,73
@@ -956,7 +962,7 @@ typedef struct NVRAM_STRUC {
#define NO_SEEK 0x00000010
#define LUN_CHECK 0x00000020
-/* Nvram Adapter Cfg bits definition */
+/* Nvram Adapter NvramChannelCfg bits definition */
#define NAC_SCANLUN 0x20 /* Include LUN as BIOS device*/
#define NAC_POWERON_SCSI_RESET 0x04 /* Power on reset enable */
#define NAC_GREATER_1G 0x02 /* > 1G support enable */