Index: trm.c =================================================================== RCS file: /home/ncvs/src/sys/dev/trm/trm.c,v retrieving revision 1.3 diff -u -p -r1.3 trm.c --- trm.c 16 Dec 2002 13:38:22 -0000 1.3 +++ trm.c 14 Jan 2003 18:20:18 -0000 @@ -1,12 +1,14 @@ /* - * 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. */ /* @@ -17,6 +19,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. */ /* @@ -89,6 +94,7 @@ __FBSDID("$FreeBSD: src/sys/dev/trm/trm. #include #include +#include #include @@ -105,6 +111,7 @@ __FBSDID("$FreeBSD: src/sys/dev/trm/trm. #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 +120,40 @@ __FBSDID("$FreeBSD: src/sys/dev/trm/trm. #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 +172,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 +212,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 +233,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 +244,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 +287,7 @@ trm_RewaitSRB0(PDCB pDCB, PSRB pSRB) } else { pSRB->pNextSRB = NULL; pDCB->pWaitingSRB = pSRB; - pDCB->pWaitLastSRB = pSRB; + pDCB->pWaitingLastSRB = pSRB; } splx(intflag); } @@ -289,14 +297,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 +319,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 +352,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 +365,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,12 +390,12 @@ 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; } } @@ -390,6 +408,7 @@ trm_ExecuteSRB(void *arg, bus_dma_segmen union ccb *ccb; u_long totalxferlen=0; + flags = splcam(); pSRB = (PSRB)arg; ccb = pSRB->pccb; pACB = (PACB)ccb->ccb_h.ccb_trmacb_ptr; @@ -401,8 +420,7 @@ trm_ExecuteSRB(void *arg, bus_dma_segmen /* 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; @@ -419,7 +437,7 @@ trm_ExecuteSRB(void *arg, bus_dma_segmen 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 +448,6 @@ trm_ExecuteSRB(void *arg, bus_dma_segmen 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 +470,12 @@ trm_ExecuteSRB(void *arg, bus_dma_segmen 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 +513,6 @@ trm_SendSRB(PACB pACB, PSRB pSRB) trm_RewaitSRB0(pDCB, pSRB); } SND_EXIT: - splx(intflag); - /* - * enable interrupt - */ return; } @@ -510,10 +521,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 +552,17 @@ trm_action(struct cam_sim *psim, union c 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 +571,7 @@ trm_action(struct cam_sim *psim, union c /* Freeze SIMQ */ pccb->ccb_h.status = CAM_RESRC_UNAVAIL; xpt_done(pccb); + splx(actionflags); return; } pSRB->pSRBDCB = pDCB; @@ -559,18 +583,31 @@ trm_action(struct cam_sim *psim, union c * 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 +623,7 @@ trm_action(struct cam_sim *psim, union c pccb->ccb_h.status |= CAM_RELEASE_SIMQ; } - splx(flags); + splx(vmflags); } else { struct bus_dma_segment seg; @@ -610,6 +647,7 @@ trm_action(struct cam_sim *psim, union c pccb->ccb_h.status = CAM_PROVIDE_FAIL; xpt_done(pccb); + splx(actionflags); return; } @@ -652,6 +690,7 @@ trm_action(struct cam_sim *psim, union c 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 +820,7 @@ trm_action(struct cam_sim *psim, union c 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 +886,7 @@ trm_action(struct cam_sim *psim, union c 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 */ @@ -1043,12 +1082,13 @@ trm_action(struct cam_sim *psim, union c xpt_done(pccb); break; } + splx(actionflags); } static void trm_poll(struct cam_sim *psim) { - + } static void @@ -1072,7 +1112,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 +1146,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 +1194,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 +1216,7 @@ trm_StartSCSI(PACB pACB, PDCB pDCB, 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 +1242,9 @@ trm_StartSCSI(PACB pACB, PDCB pDCB, 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 +1273,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 +1302,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......"); @@ -1332,7 +1352,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 +1361,7 @@ trm_MsgOutPhase0(PACB pACB, PSRB pSRB, u } 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 +1429,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 +1444,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 +1490,7 @@ trm_CommandPhase1(PACB pACB, PSRB pSRB, } 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 +1510,7 @@ trm_DataOutPhase0(PACB pACB, PSRB pSRB, * 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 +1563,7 @@ trm_DataOutPhase0(PACB pACB, PSRB pSRB, * 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 +1599,7 @@ trm_DataOutPhase0(PACB pACB, PSRB pSRB, 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 +1611,9 @@ trm_DataOutPhase1(PACB pACB, PSRB pSRB, } 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 +1624,9 @@ trm_DataInPhase0(PACB pACB, PSRB pSRB, u 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 +1650,7 @@ trm_DataInPhase0(PACB pACB, PSRB pSRB, u /* * 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 +1678,7 @@ trm_DataInPhase0(PACB pACB, PSRB pSRB, u } 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 +1698,19 @@ trm_DataIO_transfer(PACB pACB, PSRB pSRB 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 +1769,7 @@ trm_DataIO_transfer(PACB pACB, PSRB pSRB } 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 +1787,7 @@ trm_StatusPhase0(PACB pACB, PSRB pSRB, u 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 +1829,7 @@ trm_StatusPhase1(PACB pACB, PSRB pSRB, u */ 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 +1841,23 @@ trm_MsgInPhase0(PACB pACB, PSRB pSRB, u_ 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 +1867,14 @@ trm_MsgInPhase0(PACB pACB, PSRB pSRB, u_ 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 +1906,50 @@ trm_MsgInPhase0(PACB pACB, PSRB pSRB, u_ ~(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 +1996,15 @@ trm_MsgInPhase0(PACB pACB, PSRB pSRB, u_ 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 +2013,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 +2043,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 +2063,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 +2101,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 +2129,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 +2152,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 +2178,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 +2222,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 +2239,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 +2261,13 @@ trm_MsgInPhase1(PACB pACB, PSRB pSRB, u_ } 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 +2275,33 @@ trm_Nop1(PACB pACB, PSRB pSRB, u_int8_t 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 +2329,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 +2358,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 +2374,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 +2393,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 +2426,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 +2434,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 +2518,11 @@ trm_SRBdone(PACB pACB, PDCB pDCB, PSRB p *((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; + pcsio->ccb_h.status = CAM_SCSI_STATUS_ERROR + | CAM_AUTOSNS_VALID; goto ckc_e; } /* @@ -2378,19 +2536,16 @@ trm_SRBdone(PACB pACB, PDCB pDCB, PSRB p 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 +2556,20 @@ trm_SRBdone(PACB pACB, PDCB pDCB, PSRB p __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 +2661,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 +2686,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 +2757,6 @@ trm_DoingSRB_Done(PACB pACB) } pdcb->GoingSRBCnt = 0;; pdcb->pGoingSRB = NULL; - pdcb->TagMask = 0; pdcb = pdcb->pNextDCB; } while (pdcb != pDCB); @@ -2673,11 +2828,10 @@ trm_RequestSense(PACB pACB, PDCB pDCB, P /* $$$$$$ 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 = (u_long) vtophys(&pcsio->sense_data); + pSRB->pSRBSGL->length = (u_long) pcsio->sense_len; pSRB->SRBSGCount = 1; pSRB->SRBSGIndex = 0; @@ -2723,6 +2877,15 @@ trm_initDCB(PACB pACB, PDCB pDCB, u_int1 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 +2909,15 @@ trm_initDCB(PACB pACB, PDCB pDCB, u_int1 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 +2935,9 @@ trm_initDCB(PACB pACB, PDCB pDCB, u_int1 } 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 +2953,15 @@ trm_initDCB(PACB pACB, PDCB pDCB, u_int1 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 +2974,6 @@ trm_initDCB(PACB pACB, PDCB pDCB, u_int1 /* * 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 +2982,71 @@ trm_initDCB(PACB pACB, PDCB pDCB, u_int1 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) +static int +trm_initSRB(PACB pACB) { - u_int16_t i; + u_int16_t i; + PSRB pSRB; - for (i = 0; i < MAX_SRB_CNT; i++) { - if (i != MAX_SRB_CNT - 1) - /* - * link all SRB - */ - pACB->SRB_array[i].pNextSRB = &pACB->SRB_array[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]); + for(i = 0; i < TRM_MAX_SRB_CNT; i++) { + pSRB = (PSRB)&pACB->pFreeSRB[i]; + + /* DMA tag for our S/G structures */ + if(bus_dma_tag_create( + /*parent_dmat*/pSRB->parent_dmat, + /*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*/ &pSRB->sg_dmat) != 0) { + return ENXIO; + } + if(bus_dmamem_alloc(pSRB->sg_dmat, (void **)&pSRB->pSRBSGL, + BUS_DMA_NOWAIT, &pSRB->sg_dmamap) !=0 ) { + return ENXIO; + } + bus_dmamap_load(pSRB->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 + */ + pSRB->pNextSRB = &pACB->pFreeSRB[i+1]; + } else { + /* + ** load NULL to NextSRB of the last SRB + */ + pSRB->pNextSRB = NULL; } + pSRB->TagNumber = i; + } + 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 +3058,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 +3083,18 @@ TRM_write_all(PNVRAMTYPE pEEpromBuf,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 +3102,7 @@ TRM_write_all(PNVRAMTYPE pEEpromBuf,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 +3110,7 @@ TRM_set_data(PACB pACB, u_int8_t bAddr, * Send write command & address */ - TRM_write_cmd(pACB, 0x05, bAddr); + NVRAM_trm_write_cmd(pACB, 0x05, bAddr); /* * Write data */ @@ -2949,27 +3120,27 @@ TRM_set_data(PACB pACB, u_int8_t bAddr, /* 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 +3153,7 @@ TRM_set_data(PACB pACB, u_int8_t bAddr, } 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 +3164,7 @@ TRM_read_all(PNVRAMTYPE pEEpromBuf, 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 +3174,7 @@ TRM_read_all(PNVRAMTYPE pEEpromBuf, 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 +3182,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 +3199,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 +3209,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 +3219,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 +3233,9 @@ TRM_write_cmd(PACB pACB, u_int8_t bCmd, 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 +3246,12 @@ TRM_write_cmd(PACB pACB, u_int8_t bCmd, /* 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 +3261,7 @@ trm_check_eeprom(PNVRAMTYPE pEEpromBuf, 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 +3303,12 @@ trm_check_eeprom(PNVRAMTYPE pEEpromBuf, 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,30 +3355,51 @@ trm_initAdapter(PACB pACB, u_int16_t uni 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 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_MAPS, 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, + pACB->iores = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, 1, 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, + if (bus_dma_tag_create(/*parent_dmat*/ pACB->parent_dmat, /*alignment*/ 1, /*boundary*/ 0, - /*lowaddr*/ BUS_SPACE_MAXADDR_32BIT, + /*lowaddr*/ BUS_SPACE_MAXADDR, /*highaddr*/ BUS_SPACE_MAXADDR, /*filter*/ NULL, /*filterarg*/ NULL, @@ -3217,43 +3409,88 @@ trm_init(u_int16_t unit, device_t pci_co /*flags*/ BUS_DMA_ALLOCNOW, &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); + 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 (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_MAPS, pACB->iores); + 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 +3498,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, + pACB->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1, 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 +3543,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 +3562,26 @@ 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_MAPS, pACB->iores); + 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); 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 +3595,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 @@ -3372,6 +3617,11 @@ trm_detach(device_t dev) PACB pACB = device_get_softc(dev); bus_release_resource(dev, SYS_RES_IOPORT, PCIR_MAPS, pACB->iores); + 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_dma_tag_destroy(pACB->buffer_dmat); bus_teardown_intr(dev, pACB->irq, pACB->ih); bus_release_resource(dev, SYS_RES_IRQ, 0, pACB->irq); Index: trm.h =================================================================== RCS file: /home/ncvs/src/sys/dev/trm/trm.h,v retrieving revision 1.2 diff -u -p -r1.2 trm.h --- trm.h 16 Dec 2002 13:38:22 -0000 1.2 +++ trm.h 14 Jan 2003 18:20:19 -0000 @@ -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,23 @@ 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_dma_tag_t parent_dmat; + bus_dma_tag_t sg_dmat; + 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 +174,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 +188,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 +209,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 +227,14 @@ 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_dmamap_t srb_dmamap; struct resource *iores, *irq; void *ih; /* @@ -244,27 +243,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 +268,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 +316,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 +412,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 +714,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 +777,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 +935,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 +959,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 */