summaryrefslogtreecommitdiffstats
path: root/sys/dev
diff options
context:
space:
mode:
authormarius <marius@FreeBSD.org>2011-11-25 19:29:21 +0000
committermarius <marius@FreeBSD.org>2011-11-25 19:29:21 +0000
commit2f543fefda2636e391589aa9c133f78b3fbe31aa (patch)
treeb57208a1161542e0122560444dba9f5ed4c1451b /sys/dev
parent8483c392336a7405581e508516b5914e80b0c095 (diff)
downloadFreeBSD-src-2f543fefda2636e391589aa9c133f78b3fbe31aa.zip
FreeBSD-src-2f543fefda2636e391589aa9c133f78b3fbe31aa.tar.gz
Deorbit the broken amd(4) (see PR 124667), which was superseded by esp(4)
as of r227006.
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/amd/amd.c2539
-rw-r--r--sys/dev/amd/amd.h585
2 files changed, 0 insertions, 3124 deletions
diff --git a/sys/dev/amd/amd.c b/sys/dev/amd/amd.c
deleted file mode 100644
index f4b3d80..0000000
--- a/sys/dev/amd/amd.c
+++ /dev/null
@@ -1,2539 +0,0 @@
-/*-
- *********************************************************************
- * FILE NAME : amd.c
- * BY : C.L. Huang (ching@tekram.com.tw)
- * Erich Chen (erich@tekram.com.tw)
- * Description: Device Driver for the amd53c974 PCI Bus Master
- * SCSI Host adapter found on cards such as
- * the Tekram DC-390(T).
- * (C)Copyright 1995-1999 Tekram Technology Co., Ltd.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *********************************************************************
- * $FreeBSD$
- */
-
-/*
- *********************************************************************
- * HISTORY:
- *
- * REV# DATE NAME DESCRIPTION
- * 1.00 07/02/96 CLH First release for RELEASE-2.1.0
- * 1.01 08/20/96 CLH Update for RELEASE-2.1.5
- * 1.02 11/06/96 CLH Fixed more than 1 LUN scanning
- * 1.03 12/20/96 CLH Modify to support 2.2-ALPHA
- * 1.04 12/26/97 CLH Modify to support RELEASE-2.2.5
- * 1.05 01/01/99 ERICH CHEN Modify to support RELEASE-3.0.x (CAM)
- *********************************************************************
- */
-
-/* #define AMD_DEBUG0 */
-/* #define AMD_DEBUG_SCSI_PHASE */
-
-#include <sys/param.h>
-
-#include <sys/systm.h>
-#include <sys/queue.h>
-#include <sys/kernel.h>
-#include <sys/module.h>
-#include <sys/lock.h>
-#include <sys/mutex.h>
-#include <sys/malloc.h>
-
-#include <vm/vm.h>
-#include <vm/pmap.h>
-
-#include <machine/bus.h>
-#include <machine/resource.h>
-#include <sys/bus.h>
-#include <sys/rman.h>
-
-#include <cam/cam.h>
-#include <cam/cam_ccb.h>
-#include <cam/cam_sim.h>
-#include <cam/cam_xpt_sim.h>
-#include <cam/cam_debug.h>
-
-#include <cam/scsi/scsi_all.h>
-#include <cam/scsi/scsi_message.h>
-
-#include <dev/pci/pcivar.h>
-#include <dev/pci/pcireg.h>
-#include <dev/amd/amd.h>
-
-#define PCI_DEVICE_ID_AMD53C974 0x20201022ul
-#define PCI_BASE_ADDR0 0x10
-
-typedef u_int (phase_handler_t)(struct amd_softc *, struct amd_srb *, u_int);
-typedef phase_handler_t *phase_handler_func_t;
-
-static void amd_intr(void *vamd);
-static int amdstart(struct amd_softc *amd, struct amd_srb * pSRB);
-static phase_handler_t amd_NopPhase;
-
-static phase_handler_t amd_DataOutPhase0;
-static phase_handler_t amd_DataInPhase0;
-#define amd_CommandPhase0 amd_NopPhase
-static phase_handler_t amd_StatusPhase0;
-static phase_handler_t amd_MsgOutPhase0;
-static phase_handler_t amd_MsgInPhase0;
-static phase_handler_t amd_DataOutPhase1;
-static phase_handler_t amd_DataInPhase1;
-static phase_handler_t amd_CommandPhase1;
-static phase_handler_t amd_StatusPhase1;
-static phase_handler_t amd_MsgOutPhase1;
-static phase_handler_t amd_MsgInPhase1;
-
-static void amdsetupcommand(struct amd_softc *amd, struct amd_srb *srb);
-static int amdparsemsg(struct amd_softc *amd);
-static int amdhandlemsgreject(struct amd_softc *amd);
-static void amdconstructsdtr(struct amd_softc *amd,
- u_int period, u_int offset);
-static u_int amdfindclockrate(struct amd_softc *amd, u_int *period);
-static int amdsentmsg(struct amd_softc *amd, u_int msgtype, int full);
-
-static void DataIO_Comm(struct amd_softc *amd, struct amd_srb *pSRB, u_int dir);
-static void amd_Disconnect(struct amd_softc *amd);
-static void amd_Reselect(struct amd_softc *amd);
-static void SRBdone(struct amd_softc *amd, struct amd_srb *pSRB);
-static void amd_ScsiRstDetect(struct amd_softc *amd);
-static void amd_ResetSCSIBus(struct amd_softc *amd);
-static void RequestSense(struct amd_softc *amd, struct amd_srb *pSRB);
-static void amd_InvalidCmd(struct amd_softc *amd);
-
-static void amd_dmamap_cb(void *arg, bus_dma_segment_t *segs, int nsegs,
- int error);
-
-#if 0
-static void amd_timeout(void *arg1);
-static void amd_reset(struct amd_softc *amd);
-#endif
-static u_int8_t * phystovirt(struct amd_srb *pSRB, u_int32_t xferCnt);
-
-void amd_linkSRB(struct amd_softc *amd);
-static int amd_init(device_t);
-static void amd_load_defaults(struct amd_softc *amd);
-static void amd_load_eeprom_or_defaults(struct amd_softc *amd);
-static int amd_EEpromInDO(struct amd_softc *amd);
-static u_int16_t EEpromGetData1(struct amd_softc *amd);
-static void amd_EnDisableCE(struct amd_softc *amd, int mode, int *regval);
-static void amd_EEpromOutDI(struct amd_softc *amd, int *regval, int Carry);
-static void amd_Prepare(struct amd_softc *amd, int *regval, u_int8_t EEpromCmd);
-static void amd_ReadEEprom(struct amd_softc *amd);
-
-static int amd_probe(device_t);
-static int amd_attach(device_t);
-static void amdcompletematch(struct amd_softc *amd, target_id_t target,
- lun_id_t lun, u_int tag, struct srb_queue *queue,
- cam_status status);
-static void amdsetsync(struct amd_softc *amd, u_int target, u_int clockrate,
- u_int period, u_int offset, u_int type);
-static void amdsettags(struct amd_softc *amd, u_int target, int tagenb);
-
-static __inline void amd_clear_msg_state(struct amd_softc *amd);
-
-static __inline void
-amd_clear_msg_state(struct amd_softc *amd)
-{
- amd->msgout_len = 0;
- amd->msgout_index = 0;
- amd->msgin_index = 0;
-}
-
-static __inline uint32_t
-amd_get_sense_bufaddr(struct amd_softc *amd, struct amd_srb *pSRB)
-{
- int offset;
-
- offset = pSRB->TagNumber;
- return (amd->sense_busaddr + (offset * sizeof(struct scsi_sense_data)));
-}
-
-static __inline struct scsi_sense_data *
-amd_get_sense_buf(struct amd_softc *amd, struct amd_srb *pSRB)
-{
- int offset;
-
- offset = pSRB->TagNumber;
- return (&amd->sense_buffers[offset]);
-}
-
-static __inline uint32_t
-amd_get_sense_bufsize(struct amd_softc *amd, struct amd_srb *pSRB)
-{
- return (sizeof(struct scsi_sense_data));
-}
-
-/* CAM SIM entry points */
-#define ccb_srb_ptr spriv_ptr0
-#define ccb_amd_ptr spriv_ptr1
-static void amd_action(struct cam_sim *sim, union ccb *ccb);
-static void amd_poll(struct cam_sim *sim);
-
-/*
- * State engine function tables indexed by SCSI phase number
- */
-phase_handler_func_t amd_SCSI_phase0[] = {
- amd_DataOutPhase0,
- amd_DataInPhase0,
- amd_CommandPhase0,
- amd_StatusPhase0,
- amd_NopPhase,
- amd_NopPhase,
- amd_MsgOutPhase0,
- amd_MsgInPhase0
-};
-
-phase_handler_func_t amd_SCSI_phase1[] = {
- amd_DataOutPhase1,
- amd_DataInPhase1,
- amd_CommandPhase1,
- amd_StatusPhase1,
- amd_NopPhase,
- amd_NopPhase,
- amd_MsgOutPhase1,
- amd_MsgInPhase1
-};
-
-/*
- * EEProm/BIOS negotiation periods
- */
-u_int8_t eeprom_period[] = {
- 25, /* 10.0MHz */
- 32, /* 8.0MHz */
- 38, /* 6.6MHz */
- 44, /* 5.7MHz */
- 50, /* 5.0MHz */
- 63, /* 4.0MHz */
- 83, /* 3.0MHz */
- 125 /* 2.0MHz */
-};
-
-/*
- * chip clock setting to SCSI specified sync parameter table.
- */
-u_int8_t tinfo_sync_period[] = {
- 25, /* 10.0 */
- 32, /* 8.0 */
- 38, /* 6.6 */
- 44, /* 5.7 */
- 50, /* 5.0 */
- 57, /* 4.4 */
- 63, /* 4.0 */
- 70, /* 3.6 */
- 76, /* 3.3 */
- 83 /* 3.0 */
-};
-
-static __inline struct amd_srb *
-amdgetsrb(struct amd_softc * amd)
-{
- int intflag;
- struct amd_srb * pSRB;
-
- intflag = splcam();
- pSRB = TAILQ_FIRST(&amd->free_srbs);
- if (pSRB)
- TAILQ_REMOVE(&amd->free_srbs, pSRB, links);
- splx(intflag);
- return (pSRB);
-}
-
-static void
-amdsetupcommand(struct amd_softc *amd, struct amd_srb *srb)
-{
- struct scsi_request_sense sense_cmd;
- u_int8_t *cdb;
- u_int cdb_len;
-
- if (srb->SRBFlag & AUTO_REQSENSE) {
- sense_cmd.opcode = REQUEST_SENSE;
- sense_cmd.byte2 = srb->pccb->ccb_h.target_lun << 5;
- sense_cmd.unused[0] = 0;
- sense_cmd.unused[1] = 0;
- sense_cmd.length = sizeof(struct scsi_sense_data);
- sense_cmd.control = 0;
- cdb = &sense_cmd.opcode;
- cdb_len = sizeof(sense_cmd);
- } else {
- cdb = &srb->CmdBlock[0];
- cdb_len = srb->ScsiCmdLen;
- }
- amd_write8_multi(amd, SCSIFIFOREG, cdb, cdb_len);
-}
-
-/*
- * Attempt to start a waiting transaction. Interrupts must be disabled
- * upon entry to this function.
- */
-static void
-amdrunwaiting(struct amd_softc *amd) {
- struct amd_srb *srb;
-
- if (amd->last_phase != SCSI_BUS_FREE)
- return;
-
- srb = TAILQ_FIRST(&amd->waiting_srbs);
- if (srb == NULL)
- return;
-
- if (amdstart(amd, srb) == 0) {
- TAILQ_REMOVE(&amd->waiting_srbs, srb, links);
- TAILQ_INSERT_HEAD(&amd->running_srbs, srb, links);
- }
-}
-
-static void
-amdexecutesrb(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
-{
- struct amd_srb *srb;
- union ccb *ccb;
- struct amd_softc *amd;
- int s;
-
- srb = (struct amd_srb *)arg;
- ccb = srb->pccb;
- amd = (struct amd_softc *)ccb->ccb_h.ccb_amd_ptr;
-
- if (error != 0) {
- if (error != EFBIG)
- printf("amd%d: Unexepected error 0x%x returned from "
- "bus_dmamap_load\n", amd->unit, error);
- if (ccb->ccb_h.status == CAM_REQ_INPROG) {
- xpt_freeze_devq(ccb->ccb_h.path, /*count*/1);
- ccb->ccb_h.status = CAM_REQ_TOO_BIG|CAM_DEV_QFRZN;
- }
- TAILQ_INSERT_HEAD(&amd->free_srbs, srb, links);
- xpt_done(ccb);
- return;
- }
-
- if (nseg != 0) {
- struct amd_sg *sg;
- bus_dma_segment_t *end_seg;
- bus_dmasync_op_t op;
-
- end_seg = dm_segs + nseg;
-
- /* Copy the segments into our SG list */
- srb->pSGlist = &srb->SGsegment[0];
- sg = srb->pSGlist;
- while (dm_segs < end_seg) {
- sg->SGXLen = dm_segs->ds_len;
- sg->SGXPtr = dm_segs->ds_addr;
- sg++;
- dm_segs++;
- }
-
- if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN)
- op = BUS_DMASYNC_PREREAD;
- else
- op = BUS_DMASYNC_PREWRITE;
-
- bus_dmamap_sync(amd->buffer_dmat, srb->dmamap, op);
-
- }
- srb->SGcount = nseg;
- srb->SGIndex = 0;
- srb->AdaptStatus = 0;
- srb->TargetStatus = 0;
- srb->MsgCnt = 0;
- srb->SRBStatus = 0;
- srb->SRBFlag = 0;
- srb->SRBState = 0;
- srb->TotalXferredLen = 0;
- srb->SGPhysAddr = 0;
- srb->SGToBeXferLen = 0;
- srb->EndMessage = 0;
-
- s = splcam();
-
- /*
- * Last time we need to check if this CCB needs to
- * be aborted.
- */
- if (ccb->ccb_h.status != CAM_REQ_INPROG) {
- if (nseg != 0)
- bus_dmamap_unload(amd->buffer_dmat, srb->dmamap);
- TAILQ_INSERT_HEAD(&amd->free_srbs, srb, links);
- xpt_done(ccb);
- splx(s);
- return;
- }
- ccb->ccb_h.status |= CAM_SIM_QUEUED;
-#if 0
- /* XXX Need a timeout handler */
- ccb->ccb_h.timeout_ch =
- timeout(amdtimeout, (caddr_t)srb,
- (ccb->ccb_h.timeout * hz) / 1000);
-#endif
- TAILQ_INSERT_TAIL(&amd->waiting_srbs, srb, links);
- amdrunwaiting(amd);
- splx(s);
-}
-
-static void
-amd_action(struct cam_sim * psim, union ccb * pccb)
-{
- struct amd_softc * amd;
- u_int target_id;
-
- CAM_DEBUG(pccb->ccb_h.path, CAM_DEBUG_TRACE, ("amd_action\n"));
-
- amd = (struct amd_softc *) cam_sim_softc(psim);
- target_id = pccb->ccb_h.target_id;
-
- switch (pccb->ccb_h.func_code) {
- case XPT_SCSI_IO:
- {
- struct amd_srb * pSRB;
- struct ccb_scsiio *pcsio;
-
- pcsio = &pccb->csio;
-
- /*
- * Assign an SRB and connect it with this ccb.
- */
- pSRB = amdgetsrb(amd);
-
- if (!pSRB) {
- /* Freeze SIMQ */
- pccb->ccb_h.status = CAM_RESRC_UNAVAIL;
- xpt_done(pccb);
- return;
- }
- pSRB->pccb = pccb;
- pccb->ccb_h.ccb_srb_ptr = pSRB;
- pccb->ccb_h.ccb_amd_ptr = amd;
- pSRB->ScsiCmdLen = pcsio->cdb_len;
- 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) {
- /*
- * We've been given a pointer
- * to a single buffer.
- */
- if ((pccb->ccb_h.flags & CAM_DATA_PHYS) == 0) {
- int s;
- int error;
-
- s = splsoftvm();
- error =
- bus_dmamap_load(amd->buffer_dmat,
- pSRB->dmamap,
- pcsio->data_ptr,
- pcsio->dxfer_len,
- amdexecutesrb,
- pSRB, /*flags*/0);
- if (error == EINPROGRESS) {
- /*
- * So as to maintain
- * ordering, freeze the
- * controller queue
- * until our mapping is
- * returned.
- */
- xpt_freeze_simq(amd->psim, 1);
- pccb->ccb_h.status |=
- CAM_RELEASE_SIMQ;
- }
- splx(s);
- } else {
- struct bus_dma_segment seg;
-
- /* Pointer to physical buffer */
- seg.ds_addr =
- (bus_addr_t)pcsio->data_ptr;
- seg.ds_len = pcsio->dxfer_len;
- amdexecutesrb(pSRB, &seg, 1, 0);
- }
- } else {
- struct bus_dma_segment *segs;
-
- if ((pccb->ccb_h.flags & CAM_SG_LIST_PHYS) == 0
- || (pccb->ccb_h.flags & CAM_DATA_PHYS) != 0) {
- TAILQ_INSERT_HEAD(&amd->free_srbs,
- pSRB, links);
- pccb->ccb_h.status = CAM_PROVIDE_FAIL;
- xpt_done(pccb);
- return;
- }
-
- /* Just use the segments provided */
- segs =
- (struct bus_dma_segment *)pcsio->data_ptr;
- amdexecutesrb(pSRB, segs, pcsio->sglist_cnt, 0);
- }
- } else
- amdexecutesrb(pSRB, NULL, 0, 0);
- break;
- }
- case XPT_PATH_INQ:
- {
- struct ccb_pathinq *cpi = &pccb->cpi;
-
- cpi->version_num = 1;
- cpi->hba_inquiry = PI_SDTR_ABLE | PI_TAG_ABLE;
- cpi->target_sprt = 0;
- cpi->hba_misc = 0;
- cpi->hba_eng_cnt = 0;
- cpi->max_target = 7;
- cpi->max_lun = amd->max_lun; /* 7 or 0 */
- cpi->initiator_id = amd->AdaptSCSIID;
- cpi->bus_id = cam_sim_bus(psim);
- strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
- strncpy(cpi->hba_vid, "TRM-AMD", HBA_IDLEN);
- strncpy(cpi->dev_name, cam_sim_name(psim), DEV_IDLEN);
- cpi->unit_number = cam_sim_unit(psim);
- cpi->transport = XPORT_SPI;
- cpi->transport_version = 2;
- cpi->protocol = PROTO_SCSI;
- cpi->protocol_version = SCSI_REV_2;
- cpi->ccb_h.status = CAM_REQ_CMP;
- xpt_done(pccb);
- break;
- }
- case XPT_ABORT:
- pccb->ccb_h.status = CAM_REQ_INVALID;
- xpt_done(pccb);
- break;
- case XPT_RESET_BUS:
- {
-
- int i;
-
- amd_ResetSCSIBus(amd);
- amd->ACBFlag = 0;
-
- for (i = 0; i < 500; i++) {
- DELAY(1000); /* Wait until our interrupt
- * handler sees it */
- }
-
- pccb->ccb_h.status = CAM_REQ_CMP;
- xpt_done(pccb);
- break;
- }
- case XPT_RESET_DEV:
- pccb->ccb_h.status = CAM_REQ_INVALID;
- xpt_done(pccb);
- break;
- case XPT_TERM_IO:
- pccb->ccb_h.status = CAM_REQ_INVALID;
- xpt_done(pccb);
- break;
- case XPT_GET_TRAN_SETTINGS:
- {
- struct ccb_trans_settings *cts = &pccb->cts;
- struct amd_target_info *targ_info = &amd->tinfo[target_id];
- struct amd_transinfo *tinfo;
- int intflag;
- struct ccb_trans_settings_scsi *scsi =
- &cts->proto_specific.scsi;
- struct ccb_trans_settings_spi *spi =
- &cts->xport_specific.spi;
-
- cts->protocol = PROTO_SCSI;
- cts->protocol_version = SCSI_REV_2;
- cts->transport = XPORT_SPI;
- cts->transport_version = 2;
-
- intflag = splcam();
- if (cts->type == CTS_TYPE_CURRENT_SETTINGS) {
- /* current transfer settings */
- if (targ_info->disc_tag & AMD_CUR_DISCENB) {
- spi->flags = CTS_SPI_FLAGS_DISC_ENB;
- } else {
- spi->flags = 0;
- }
- if (targ_info->disc_tag & AMD_CUR_TAGENB) {
- scsi->flags = CTS_SCSI_FLAGS_TAG_ENB;
- } else {
- scsi->flags = 0;
- }
- tinfo = &targ_info->current;
- } else {
- /* default(user) transfer settings */
- if (targ_info->disc_tag & AMD_USR_DISCENB) {
- spi->flags = CTS_SPI_FLAGS_DISC_ENB;
- } else {
- spi->flags = 0;
- }
- if (targ_info->disc_tag & AMD_USR_TAGENB) {
- scsi->flags = CTS_SCSI_FLAGS_TAG_ENB;
- } else {
- scsi->flags = 0;
- }
- tinfo = &targ_info->user;
- }
- spi->sync_period = tinfo->period;
- spi->sync_offset = tinfo->offset;
- splx(intflag);
-
- spi->bus_width = MSG_EXT_WDTR_BUS_8_BIT;
- spi->valid = CTS_SPI_VALID_SYNC_RATE
- | CTS_SPI_VALID_SYNC_OFFSET
- | CTS_SPI_VALID_BUS_WIDTH
- | CTS_SPI_VALID_DISC;
- scsi->valid = CTS_SCSI_VALID_TQ;
- pccb->ccb_h.status = CAM_REQ_CMP;
- xpt_done(pccb);
- break;
- }
-#define IS_CURRENT_SETTINGS(c) (c->type == CTS_TYPE_CURRENT_SETTINGS)
-#define IS_USER_SETTINGS(c) (c->type == CTS_TYPE_USER_SETTINGS)
- case XPT_SET_TRAN_SETTINGS:
- {
- struct ccb_trans_settings *cts = &pccb->cts;
- struct amd_target_info *targ_info;
- u_int update_type = 0;
- int intflag;
- int last_entry;
- struct ccb_trans_settings_scsi *scsi =
- &cts->proto_specific.scsi;
- struct ccb_trans_settings_spi *spi =
- &cts->xport_specific.spi;
- if (IS_CURRENT_SETTINGS(cts)) {
- update_type |= AMD_TRANS_GOAL;
- } else if (IS_USER_SETTINGS(cts)) {
- update_type |= AMD_TRANS_USER;
- }
- if (update_type == 0
- || update_type == (AMD_TRANS_USER|AMD_TRANS_GOAL)) {
- cts->ccb_h.status = CAM_REQ_INVALID;
- xpt_done(pccb);
- }
-
- intflag = splcam();
- targ_info = &amd->tinfo[target_id];
-
- if ((spi->valid & CTS_SPI_VALID_DISC) != 0) {
- if (update_type & AMD_TRANS_GOAL) {
- if ((spi->flags & CTS_SPI_FLAGS_DISC_ENB)
- != 0) {
- targ_info->disc_tag |= AMD_CUR_DISCENB;
- } else {
- targ_info->disc_tag &= ~AMD_CUR_DISCENB;
- }
- }
- if (update_type & AMD_TRANS_USER) {
- if ((spi->flags & CTS_SPI_FLAGS_DISC_ENB)
- != 0) {
- targ_info->disc_tag |= AMD_USR_DISCENB;
- } else {
- targ_info->disc_tag &= ~AMD_USR_DISCENB;
- }
- }
- }
- if ((scsi->valid & CTS_SCSI_VALID_TQ) != 0) {
- if (update_type & AMD_TRANS_GOAL) {
- if ((scsi->flags & CTS_SCSI_FLAGS_TAG_ENB)
- != 0) {
- targ_info->disc_tag |= AMD_CUR_TAGENB;
- } else {
- targ_info->disc_tag &= ~AMD_CUR_TAGENB;
- }
- }
- if (update_type & AMD_TRANS_USER) {
- if ((scsi->flags & CTS_SCSI_FLAGS_TAG_ENB)
- != 0) {
- targ_info->disc_tag |= AMD_USR_TAGENB;
- } else {
- targ_info->disc_tag &= ~AMD_USR_TAGENB;
- }
- }
- }
-
- if ((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) == 0) {
- if (update_type & AMD_TRANS_GOAL)
- spi->sync_offset = targ_info->goal.offset;
- else
- spi->sync_offset = targ_info->user.offset;
- }
-
- if (spi->sync_offset > AMD_MAX_SYNC_OFFSET)
- spi->sync_offset = AMD_MAX_SYNC_OFFSET;
-
- if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) == 0) {
- if (update_type & AMD_TRANS_GOAL)
- spi->sync_period = targ_info->goal.period;
- else
- spi->sync_period = targ_info->user.period;
- }
-
- last_entry = sizeof(tinfo_sync_period) - 1;
- if ((spi->sync_period != 0)
- && (spi->sync_period < tinfo_sync_period[0]))
- spi->sync_period = tinfo_sync_period[0];
- if (spi->sync_period > tinfo_sync_period[last_entry])
- spi->sync_period = 0;
- if (spi->sync_offset == 0)
- spi->sync_period = 0;
-
- if ((update_type & AMD_TRANS_USER) != 0) {
- targ_info->user.period = spi->sync_period;
- targ_info->user.offset = spi->sync_offset;
- }
- if ((update_type & AMD_TRANS_GOAL) != 0) {
- targ_info->goal.period = spi->sync_period;
- targ_info->goal.offset = spi->sync_offset;
- }
- splx(intflag);
- pccb->ccb_h.status = CAM_REQ_CMP;
- xpt_done(pccb);
- break;
- }
- case XPT_CALC_GEOMETRY:
- {
- int extended;
-
- extended = (amd->eepromBuf[EE_MODE2] & GREATER_1G) != 0;
- cam_calc_geometry(&pccb->ccg, extended);
- xpt_done(pccb);
- break;
- }
- default:
- pccb->ccb_h.status = CAM_REQ_INVALID;
- xpt_done(pccb);
- break;
- }
-}
-
-static void
-amd_poll(struct cam_sim * psim)
-{
- amd_intr(cam_sim_softc(psim));
-}
-
-static u_int8_t *
-phystovirt(struct amd_srb * pSRB, u_int32_t xferCnt)
-{
- intptr_t dataPtr;
- struct ccb_scsiio *pcsio;
- u_int8_t i;
- struct amd_sg * pseg;
-
- dataPtr = 0;
- pcsio = &pSRB->pccb->csio;
-
- dataPtr = (intptr_t) pcsio->data_ptr;
- pseg = pSRB->SGsegment;
- for (i = 0; i < pSRB->SGIndex; i++) {
- dataPtr += (int) pseg->SGXLen;
- pseg++;
- }
- dataPtr += (int) xferCnt;
- return ((u_int8_t *) dataPtr);
-}
-
-static void
-amd_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 void
-ResetDevParam(struct amd_softc * amd)
-{
- u_int target;
-
- for (target = 0; target <= amd->max_id; target++) {
- if (amd->AdaptSCSIID != target) {
- amdsetsync(amd, target, /*clockrate*/0,
- /*period*/0, /*offset*/0, AMD_TRANS_CUR);
- }
- }
-}
-
-static void
-amdcompletematch(struct amd_softc *amd, target_id_t target, lun_id_t lun,
- u_int tag, struct srb_queue *queue, cam_status status)
-{
- struct amd_srb *srb;
- struct amd_srb *next_srb;
-
- for (srb = TAILQ_FIRST(queue); srb != NULL; srb = next_srb) {
- union ccb *ccb;
-
- next_srb = TAILQ_NEXT(srb, links);
- if (srb->pccb->ccb_h.target_id != target
- && target != CAM_TARGET_WILDCARD)
- continue;
-
- if (srb->pccb->ccb_h.target_lun != lun
- && lun != CAM_LUN_WILDCARD)
- continue;
-
- if (srb->TagNumber != tag
- && tag != AMD_TAG_WILDCARD)
- continue;
-
- ccb = srb->pccb;
- TAILQ_REMOVE(queue, srb, links);
- TAILQ_INSERT_HEAD(&amd->free_srbs, srb, links);
- if ((ccb->ccb_h.status & CAM_DEV_QFRZN) == 0
- && (status & CAM_DEV_QFRZN) != 0)
- xpt_freeze_devq(ccb->ccb_h.path, /*count*/1);
- ccb->ccb_h.status = status;
- xpt_done(ccb);
- }
-
-}
-
-static void
-amdsetsync(struct amd_softc *amd, u_int target, u_int clockrate,
- u_int period, u_int offset, u_int type)
-{
- struct amd_target_info *tinfo;
- u_int old_period;
- u_int old_offset;
-
- tinfo = &amd->tinfo[target];
- old_period = tinfo->current.period;
- old_offset = tinfo->current.offset;
- if ((type & AMD_TRANS_CUR) != 0
- && (old_period != period || old_offset != offset)) {
- struct cam_path *path;
-
- tinfo->current.period = period;
- tinfo->current.offset = offset;
- tinfo->sync_period_reg = clockrate;
- tinfo->sync_offset_reg = offset;
- tinfo->CtrlR3 &= ~FAST_SCSI;
- tinfo->CtrlR4 &= ~EATER_25NS;
- if (clockrate > 7)
- tinfo->CtrlR4 |= EATER_25NS;
- else
- tinfo->CtrlR3 |= FAST_SCSI;
-
- if ((type & AMD_TRANS_ACTIVE) == AMD_TRANS_ACTIVE) {
- amd_write8(amd, SYNCPERIOREG, tinfo->sync_period_reg);
- amd_write8(amd, SYNCOFFREG, tinfo->sync_offset_reg);
- amd_write8(amd, CNTLREG3, tinfo->CtrlR3);
- amd_write8(amd, CNTLREG4, tinfo->CtrlR4);
- }
- /* If possible, update the XPT's notion of our transfer rate */
- if (xpt_create_path(&path, /*periph*/NULL,
- cam_sim_path(amd->psim), target,
- CAM_LUN_WILDCARD) == CAM_REQ_CMP) {
- struct ccb_trans_settings neg;
- struct ccb_trans_settings_spi *spi =
- &neg.xport_specific.spi;
- xpt_setup_ccb(&neg.ccb_h, path, /*priority*/1);
- memset(&neg, 0, sizeof (neg));
- spi->sync_period = period;
- spi->sync_offset = offset;
- spi->valid = CTS_SPI_VALID_SYNC_RATE
- | CTS_SPI_VALID_SYNC_OFFSET;
- xpt_async(AC_TRANSFER_NEG, path, &neg);
- xpt_free_path(path);
- }
- }
- if ((type & AMD_TRANS_GOAL) != 0) {
- tinfo->goal.period = period;
- tinfo->goal.offset = offset;
- }
-
- if ((type & AMD_TRANS_USER) != 0) {
- tinfo->user.period = period;
- tinfo->user.offset = offset;
- }
-}
-
-static void
-amdsettags(struct amd_softc *amd, u_int target, int tagenb)
-{
- panic("Implement me!\n");
-}
-
-
-#if 0
-/*
- **********************************************************************
- * Function : amd_reset (struct amd_softc * amd)
- * Purpose : perform a hard reset on the SCSI bus( and AMD chip).
- * Inputs : cmd - command which caused the SCSI RESET
- **********************************************************************
- */
-static void
-amd_reset(struct amd_softc * amd)
-{
- int intflag;
- u_int8_t bval;
- u_int16_t i;
-
-
-#ifdef AMD_DEBUG0
- printf("DC390: RESET");
-#endif
-
- intflag = splcam();
- bval = amd_read8(amd, CNTLREG1);
- bval |= DIS_INT_ON_SCSI_RST;
- amd_write8(amd, CNTLREG1, bval); /* disable interrupt */
- amd_ResetSCSIBus(amd);
-
- for (i = 0; i < 500; i++) {
- DELAY(1000);
- }
-
- bval = amd_read8(amd, CNTLREG1);
- bval &= ~DIS_INT_ON_SCSI_RST;
- amd_write8(amd, CNTLREG1, bval); /* re-enable interrupt */
-
- amd_write8(amd, DMA_Cmd, DMA_IDLE_CMD);
- amd_write8(amd, SCSICMDREG, CLEAR_FIFO_CMD);
-
- ResetDevParam(amd);
- amdcompletematch(amd, CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD,
- AMD_TAG_WILDCARD, &amd->running_srbs,
- CAM_DEV_QFRZN|CAM_SCSI_BUS_RESET);
- amdcompletematch(amd, CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD,
- AMD_TAG_WILDCARD, &amd->waiting_srbs,
- CAM_DEV_QFRZN|CAM_SCSI_BUS_RESET);
- amd->active_srb = NULL;
- amd->ACBFlag = 0;
- splx(intflag);
- return;
-}
-
-void
-amd_timeout(void *arg1)
-{
- struct amd_srb * pSRB;
-
- pSRB = (struct amd_srb *) arg1;
-}
-#endif
-
-static int
-amdstart(struct amd_softc *amd, struct amd_srb *pSRB)
-{
- union ccb *pccb;
- struct ccb_scsiio *pcsio;
- struct amd_target_info *targ_info;
- u_int identify_msg;
- u_int command;
- u_int target;
- u_int lun;
-
- pccb = pSRB->pccb;
- pcsio = &pccb->csio;
- target = pccb->ccb_h.target_id;
- lun = pccb->ccb_h.target_lun;
- targ_info = &amd->tinfo[target];
-
- amd_clear_msg_state(amd);
- amd_write8(amd, SCSIDESTIDREG, target);
- amd_write8(amd, SYNCPERIOREG, targ_info->sync_period_reg);
- amd_write8(amd, SYNCOFFREG, targ_info->sync_offset_reg);
- amd_write8(amd, CNTLREG1, targ_info->CtrlR1);
- amd_write8(amd, CNTLREG3, targ_info->CtrlR3);
- amd_write8(amd, CNTLREG4, targ_info->CtrlR4);
- amd_write8(amd, SCSICMDREG, CLEAR_FIFO_CMD);
-
- identify_msg = MSG_IDENTIFYFLAG | lun;
- if ((targ_info->disc_tag & AMD_CUR_DISCENB) != 0
- && (pccb->ccb_h.flags & CAM_DIS_DISCONNECT) == 0
- && (pSRB->CmdBlock[0] != REQUEST_SENSE)
- && (pSRB->SRBFlag & AUTO_REQSENSE) == 0)
- identify_msg |= MSG_IDENTIFY_DISCFLAG;
-
- amd_write8(amd, SCSIFIFOREG, identify_msg);
- if ((targ_info->disc_tag & AMD_CUR_TAGENB) == 0
- || (identify_msg & MSG_IDENTIFY_DISCFLAG) == 0)
- pccb->ccb_h.flags &= ~CAM_TAG_ACTION_VALID;
- if (targ_info->current.period != targ_info->goal.period
- || targ_info->current.offset != targ_info->goal.offset) {
- command = SEL_W_ATN_STOP;
- amdconstructsdtr(amd, targ_info->goal.period,
- targ_info->goal.offset);
- } else if ((pccb->ccb_h.flags & CAM_TAG_ACTION_VALID) != 0) {
- command = SEL_W_ATN2;
- pSRB->SRBState = SRB_START;
- amd_write8(amd, SCSIFIFOREG, pcsio->tag_action);
- amd_write8(amd, SCSIFIFOREG, pSRB->TagNumber);
- } else {
- command = SEL_W_ATN;
- pSRB->SRBState = SRB_START;
- }
- if (command != SEL_W_ATN_STOP)
- amdsetupcommand(amd, pSRB);
-
- if (amd_read8(amd, SCSISTATREG) & INTERRUPT) {
- pSRB->SRBState = SRB_READY;
- return (1);
- } else {
- amd->last_phase = SCSI_ARBITRATING;
- amd_write8(amd, SCSICMDREG, command);
- amd->active_srb = pSRB;
- amd->cur_target = target;
- amd->cur_lun = lun;
- return (0);
- }
-}
-
-/*
- * Catch an interrupt from the adapter.
- * Process pending device interrupts.
- */
-static void
-amd_intr(void *arg)
-{
- struct amd_softc *amd;
- struct amd_srb *pSRB;
- u_int internstat = 0;
- u_int scsistat;
- u_int intstat;
-
- amd = (struct amd_softc *)arg;
-
- if (amd == NULL) {
-#ifdef AMD_DEBUG0
- printf("amd_intr: amd NULL return......");
-#endif
- return;
- }
-
- scsistat = amd_read8(amd, SCSISTATREG);
- if (!(scsistat & INTERRUPT)) {
-#ifdef AMD_DEBUG0
- printf("amd_intr: scsistat = NULL ,return......");
-#endif
- return;
- }
-#ifdef AMD_DEBUG_SCSI_PHASE
- printf("scsistat=%2x,", scsistat);
-#endif
-
- internstat = amd_read8(amd, INTERNSTATREG);
- intstat = amd_read8(amd, INTSTATREG);
-
-#ifdef AMD_DEBUG_SCSI_PHASE
- printf("intstat=%2x,", intstat);
-#endif
-
- if (intstat & DISCONNECTED) {
- amd_Disconnect(amd);
- return;
- }
- if (intstat & RESELECTED) {
- amd_Reselect(amd);
- return;
- }
- if (intstat & INVALID_CMD) {
- amd_InvalidCmd(amd);
- return;
- }
- if (intstat & SCSI_RESET_) {
- amd_ScsiRstDetect(amd);
- return;
- }
- if (intstat & (SUCCESSFUL_OP + SERVICE_REQUEST)) {
- pSRB = amd->active_srb;
- /*
- * Run our state engine. First perform
- * post processing for the last phase we
- * were in, followed by any processing
- * required to handle the current phase.
- */
- scsistat =
- amd_SCSI_phase0[amd->last_phase](amd, pSRB, scsistat);
- amd->last_phase = scsistat & SCSI_PHASE_MASK;
- (void)amd_SCSI_phase1[amd->last_phase](amd, pSRB, scsistat);
- }
-}
-
-static u_int
-amd_DataOutPhase0(struct amd_softc *amd, struct amd_srb *pSRB, u_int scsistat)
-{
- struct amd_sg *psgl;
- u_int32_t ResidCnt, xferCnt;
-
- if (!(pSRB->SRBState & SRB_XFERPAD)) {
- if (scsistat & PARITY_ERR) {
- pSRB->SRBStatus |= PARITY_ERROR;
- }
- if (scsistat & COUNT_2_ZERO) {
- while ((amd_read8(amd, DMA_Status)&DMA_XFER_DONE) == 0)
- ;
- pSRB->TotalXferredLen += pSRB->SGToBeXferLen;
- pSRB->SGIndex++;
- if (pSRB->SGIndex < pSRB->SGcount) {
- pSRB->pSGlist++;
- psgl = pSRB->pSGlist;
- pSRB->SGPhysAddr = psgl->SGXPtr;
- pSRB->SGToBeXferLen = psgl->SGXLen;
- } else {
- pSRB->SGToBeXferLen = 0;
- }
- } else {
- ResidCnt = amd_read8(amd, CURRENTFIFOREG) & 0x1f;
- ResidCnt += amd_read8(amd, CTCREG_LOW)
- | (amd_read8(amd, CTCREG_MID) << 8)
- | (amd_read8(amd, CURTXTCNTREG) << 16);
-
- xferCnt = pSRB->SGToBeXferLen - ResidCnt;
- pSRB->SGPhysAddr += xferCnt;
- pSRB->TotalXferredLen += xferCnt;
- pSRB->SGToBeXferLen = ResidCnt;
- }
- }
- amd_write8(amd, DMA_Cmd, WRITE_DIRECTION | DMA_IDLE_CMD);
- return (scsistat);
-}
-
-static u_int
-amd_DataInPhase0(struct amd_softc *amd, struct amd_srb *pSRB, u_int scsistat)
-{
- u_int8_t bval;
- u_int16_t i, residual;
- struct amd_sg *psgl;
- u_int32_t ResidCnt, xferCnt;
- u_int8_t * ptr;
-
- if (!(pSRB->SRBState & SRB_XFERPAD)) {
- if (scsistat & PARITY_ERR) {
- pSRB->SRBStatus |= PARITY_ERROR;
- }
- if (scsistat & COUNT_2_ZERO) {
- while (1) {
- bval = amd_read8(amd, DMA_Status);
- if ((bval & DMA_XFER_DONE) != 0)
- break;
- }
- amd_write8(amd, DMA_Cmd, READ_DIRECTION|DMA_IDLE_CMD);
-
- pSRB->TotalXferredLen += pSRB->SGToBeXferLen;
- pSRB->SGIndex++;
- if (pSRB->SGIndex < pSRB->SGcount) {
- pSRB->pSGlist++;
- psgl = pSRB->pSGlist;
- pSRB->SGPhysAddr = psgl->SGXPtr;
- pSRB->SGToBeXferLen = psgl->SGXLen;
- } else {
- pSRB->SGToBeXferLen = 0;
- }
- } else { /* phase changed */
- residual = 0;
- bval = amd_read8(amd, CURRENTFIFOREG);
- while (bval & 0x1f) {
- if ((bval & 0x1f) == 1) {
- for (i = 0; i < 0x100; i++) {
- bval = amd_read8(amd, CURRENTFIFOREG);
- if (!(bval & 0x1f)) {
- goto din_1;
- } else if (i == 0x0ff) {
- residual = 1;
- goto din_1;
- }
- }
- } else {
- bval = amd_read8(amd, CURRENTFIFOREG);
- }
- }
- din_1:
- amd_write8(amd, DMA_Cmd, READ_DIRECTION|DMA_BLAST_CMD);
- for (i = 0; i < 0x8000; i++) {
- if ((amd_read8(amd, DMA_Status)&BLAST_COMPLETE))
- break;
- }
- amd_write8(amd, DMA_Cmd, READ_DIRECTION|DMA_IDLE_CMD);
-
- ResidCnt = amd_read8(amd, CTCREG_LOW)
- | (amd_read8(amd, CTCREG_MID) << 8)
- | (amd_read8(amd, CURTXTCNTREG) << 16);
- xferCnt = pSRB->SGToBeXferLen - ResidCnt;
- pSRB->SGPhysAddr += xferCnt;
- pSRB->TotalXferredLen += xferCnt;
- pSRB->SGToBeXferLen = ResidCnt;
- if (residual) {
- /* get residual byte */
- bval = amd_read8(amd, SCSIFIFOREG);
- ptr = phystovirt(pSRB, xferCnt);
- *ptr = bval;
- pSRB->SGPhysAddr++;
- pSRB->TotalXferredLen++;
- pSRB->SGToBeXferLen--;
- }
- }
- }
- return (scsistat);
-}
-
-static u_int
-amd_StatusPhase0(struct amd_softc *amd, struct amd_srb *pSRB, u_int scsistat)
-{
- pSRB->TargetStatus = amd_read8(amd, SCSIFIFOREG);
- /* get message */
- pSRB->EndMessage = amd_read8(amd, SCSIFIFOREG);
- pSRB->SRBState = SRB_COMPLETED;
- amd_write8(amd, SCSICMDREG, MSG_ACCEPTED_CMD);
- return (SCSI_NOP0);
-}
-
-static u_int
-amd_MsgOutPhase0(struct amd_softc *amd, struct amd_srb *pSRB, u_int scsistat)
-{
- if (pSRB->SRBState & (SRB_UNEXPECT_RESEL + SRB_ABORT_SENT)) {
- scsistat = SCSI_NOP0;
- }
- return (scsistat);
-}
-
-static u_int
-amd_MsgInPhase0(struct amd_softc *amd, struct amd_srb *pSRB, u_int scsistat)
-{
- int done;
-
- amd->msgin_buf[amd->msgin_index] = amd_read8(amd, SCSIFIFOREG);
-
- done = amdparsemsg(amd);
- if (done)
- amd->msgin_index = 0;
- else
- amd->msgin_index++;
- return (SCSI_NOP0);
-}
-
-static int
-amdparsemsg(struct amd_softc *amd)
-{
- int reject;
- int done;
- int response;
-
- done = FALSE;
- response = FALSE;
- reject = FALSE;
-
- /*
- * Parse as much of the message as is availible,
- * rejecting it if we don't support it. When
- * the entire message is availible and has been
- * handled, return TRUE indicating that we have
- * parsed an entire message.
- */
- switch (amd->msgin_buf[0]) {
- case MSG_DISCONNECT:
- amd->active_srb->SRBState = SRB_DISCONNECT;
- amd->disc_count[amd->cur_target][amd->cur_lun]++;
- done = TRUE;
- break;
- case MSG_SIMPLE_Q_TAG:
- {
- struct amd_srb *disc_srb;
-
- if (amd->msgin_index < 1)
- break;
- disc_srb = &amd->SRB_array[amd->msgin_buf[1]];
- if (amd->active_srb != NULL
- || disc_srb->SRBState != SRB_DISCONNECT
- || disc_srb->pccb->ccb_h.target_id != amd->cur_target
- || disc_srb->pccb->ccb_h.target_lun != amd->cur_lun) {
- printf("amd%d: Unexpected tagged reselection "
- "for target %d, Issuing Abort\n", amd->unit,
- amd->cur_target);
- amd->msgout_buf[0] = MSG_ABORT;
- amd->msgout_len = 1;
- response = TRUE;
- break;
- }
- amd->active_srb = disc_srb;
- amd->disc_count[amd->cur_target][amd->cur_lun]--;
- done = TRUE;
- break;
- }
- case MSG_MESSAGE_REJECT:
- response = amdhandlemsgreject(amd);
- if (response == FALSE)
- amd_write8(amd, SCSICMDREG, RESET_ATN_CMD);
- /* FALLTHROUGH */
- case MSG_NOOP:
- done = TRUE;
- break;
- case MSG_EXTENDED:
- {
- u_int clockrate;
- u_int period;
- u_int offset;
- u_int saved_offset;
-
- /* Wait for enough of the message to begin validation */
- if (amd->msgin_index < 1)
- break;
- if (amd->msgin_buf[1] != MSG_EXT_SDTR_LEN) {
- reject = TRUE;
- break;
- }
-
- /* Wait for opcode */
- if (amd->msgin_index < 2)
- break;
-
- if (amd->msgin_buf[2] != MSG_EXT_SDTR) {
- reject = TRUE;
- break;
- }
-
- /*
- * Wait until we have both args before validating
- * and acting on this message.
- *
- * Add one to MSG_EXT_SDTR_LEN to account for
- * the extended message preamble.
- */
- if (amd->msgin_index < (MSG_EXT_SDTR_LEN + 1))
- break;
-
- period = amd->msgin_buf[3];
- saved_offset = offset = amd->msgin_buf[4];
- clockrate = amdfindclockrate(amd, &period);
- if (offset > AMD_MAX_SYNC_OFFSET)
- offset = AMD_MAX_SYNC_OFFSET;
- if (period == 0 || offset == 0) {
- offset = 0;
- period = 0;
- clockrate = 0;
- }
- amdsetsync(amd, amd->cur_target, clockrate, period, offset,
- AMD_TRANS_ACTIVE|AMD_TRANS_GOAL);
-
- /*
- * See if we initiated Sync Negotiation
- * and didn't have to fall down to async
- * transfers.
- */
- if (amdsentmsg(amd, MSG_EXT_SDTR, /*full*/TRUE)) {
- /* We started it */
- if (saved_offset != offset) {
- /* Went too low - force async */
- reject = TRUE;
- }
- } else {
- /*
- * Send our own SDTR in reply
- */
- if (bootverbose)
- printf("Sending SDTR!\n");
- amd->msgout_index = 0;
- amd->msgout_len = 0;
- amdconstructsdtr(amd, period, offset);
- amd->msgout_index = 0;
- response = TRUE;
- }
- done = TRUE;
- break;
- }
- case MSG_SAVEDATAPOINTER:
- case MSG_RESTOREPOINTERS:
- /* XXX Implement!!! */
- done = TRUE;
- break;
- default:
- reject = TRUE;
- break;
- }
-
- if (reject) {
- amd->msgout_index = 0;
- amd->msgout_len = 1;
- amd->msgout_buf[0] = MSG_MESSAGE_REJECT;
- done = TRUE;
- response = TRUE;
- }
-
- if (response)
- amd_write8(amd, SCSICMDREG, SET_ATN_CMD);
-
- if (done && !response)
- /* Clear the outgoing message buffer */
- amd->msgout_len = 0;
-
- /* Drop Ack */
- amd_write8(amd, SCSICMDREG, MSG_ACCEPTED_CMD);
-
- return (done);
-}
-
-static u_int
-amdfindclockrate(struct amd_softc *amd, u_int *period)
-{
- u_int i;
- u_int clockrate;
-
- for (i = 0; i < sizeof(tinfo_sync_period); i++) {
- u_int8_t *table_entry;
-
- table_entry = &tinfo_sync_period[i];
- if (*period <= *table_entry) {
- /*
- * When responding to a target that requests
- * sync, the requested rate may fall between
- * two rates that we can output, but still be
- * a rate that we can receive. Because of this,
- * we want to respond to the target with
- * the same rate that it sent to us even
- * if the period we use to send data to it
- * is lower. Only lower the response period
- * if we must.
- */
- if (i == 0) {
- *period = *table_entry;
- }
- break;
- }
- }
-
- if (i == sizeof(tinfo_sync_period)) {
- /* Too slow for us. Use asnyc transfers. */
- *period = 0;
- clockrate = 0;
- } else
- clockrate = i + 4;
-
- return (clockrate);
-}
-
-/*
- * See if we sent a particular extended message to the target.
- * If "full" is true, the target saw the full message.
- * If "full" is false, the target saw at least the first
- * byte of the message.
- */
-static int
-amdsentmsg(struct amd_softc *amd, u_int msgtype, int full)
-{
- int found;
- int index;
-
- found = FALSE;
- index = 0;
-
- while (index < amd->msgout_len) {
- if ((amd->msgout_buf[index] & MSG_IDENTIFYFLAG) != 0
- || amd->msgout_buf[index] == MSG_MESSAGE_REJECT)
- index++;
- else if (amd->msgout_buf[index] >= MSG_SIMPLE_Q_TAG
- && amd->msgout_buf[index] < MSG_IGN_WIDE_RESIDUE) {
- /* Skip tag type and tag id */
- index += 2;
- } else if (amd->msgout_buf[index] == MSG_EXTENDED) {
- /* Found a candidate */
- if (amd->msgout_buf[index+2] == msgtype) {
- u_int end_index;
-
- end_index = index + 1
- + amd->msgout_buf[index + 1];
- if (full) {
- if (amd->msgout_index > end_index)
- found = TRUE;
- } else if (amd->msgout_index > index)
- found = TRUE;
- }
- break;
- } else {
- panic("amdsentmsg: Inconsistent msg buffer");
- }
- }
- return (found);
-}
-
-static void
-amdconstructsdtr(struct amd_softc *amd, u_int period, u_int offset)
-{
- amd->msgout_buf[amd->msgout_index++] = MSG_EXTENDED;
- amd->msgout_buf[amd->msgout_index++] = MSG_EXT_SDTR_LEN;
- amd->msgout_buf[amd->msgout_index++] = MSG_EXT_SDTR;
- amd->msgout_buf[amd->msgout_index++] = period;
- amd->msgout_buf[amd->msgout_index++] = offset;
- amd->msgout_len += 5;
-}
-
-static int
-amdhandlemsgreject(struct amd_softc *amd)
-{
- /*
- * If we had an outstanding SDTR for this
- * target, this is a signal that the target
- * is refusing negotiation. Also watch out
- * for rejected tag messages.
- */
- struct amd_srb *srb;
- struct amd_target_info *targ_info;
- int response = FALSE;
-
- srb = amd->active_srb;
- targ_info = &amd->tinfo[amd->cur_target];
- if (amdsentmsg(amd, MSG_EXT_SDTR, /*full*/FALSE)) {
- /* note asynch xfers and clear flag */
- amdsetsync(amd, amd->cur_target, /*clockrate*/0,
- /*period*/0, /*offset*/0,
- AMD_TRANS_ACTIVE|AMD_TRANS_GOAL);
- printf("amd%d:%d: refuses synchronous negotiation. "
- "Using asynchronous transfers\n",
- amd->unit, amd->cur_target);
- } else if ((srb != NULL)
- && (srb->pccb->ccb_h.flags & CAM_TAG_ACTION_VALID) != 0) {
- struct ccb_trans_settings neg;
- struct ccb_trans_settings_scsi *scsi = &neg.proto_specific.scsi;
-
- printf("amd%d:%d: refuses tagged commands. Performing "
- "non-tagged I/O\n", amd->unit, amd->cur_target);
-
- amdsettags(amd, amd->cur_target, FALSE);
- memset(&neg, 0, sizeof (neg));
- scsi->valid = CTS_SCSI_VALID_TQ;
- xpt_setup_ccb(&neg.ccb_h, srb->pccb->ccb_h.path, /*priority*/1);
- xpt_async(AC_TRANSFER_NEG, srb->pccb->ccb_h.path, &neg);
-
- /*
- * Resend the identify for this CCB as the target
- * may believe that the selection is invalid otherwise.
- */
- if (amd->msgout_len != 0)
- bcopy(&amd->msgout_buf[0], &amd->msgout_buf[1],
- amd->msgout_len);
- amd->msgout_buf[0] = MSG_IDENTIFYFLAG
- | srb->pccb->ccb_h.target_lun;
- amd->msgout_len++;
- if ((targ_info->disc_tag & AMD_CUR_DISCENB) != 0
- && (srb->pccb->ccb_h.flags & CAM_DIS_DISCONNECT) == 0)
- amd->msgout_buf[0] |= MSG_IDENTIFY_DISCFLAG;
-
- srb->pccb->ccb_h.flags &= ~CAM_TAG_ACTION_VALID;
-
- /*
- * Requeue all tagged commands for this target
- * currently in our posession so they can be
- * converted to untagged commands.
- */
- amdcompletematch(amd, amd->cur_target, amd->cur_lun,
- AMD_TAG_WILDCARD, &amd->waiting_srbs,
- CAM_DEV_QFRZN|CAM_REQUEUE_REQ);
- } else {
- /*
- * Otherwise, we ignore it.
- */
- printf("amd%d:%d: Message reject received -- ignored\n",
- amd->unit, amd->cur_target);
- }
- return (response);
-}
-
-#if 0
- if (!(pSRB->SRBState & SRB_MSGIN_MULTI)) {
- if (bval == MSG_DISCONNECT) {
- pSRB->SRBState = SRB_DISCONNECT;
- } else if (bval == MSG_SAVEDATAPOINTER) {
- goto min6;
- } else if ((bval == MSG_EXTENDED)
- || ((bval >= MSG_SIMPLE_Q_TAG)
- && (bval <= MSG_ORDERED_Q_TAG))) {
- pSRB->SRBState |= SRB_MSGIN_MULTI;
- pSRB->MsgInBuf[0] = bval;
- pSRB->MsgCnt = 1;
- pSRB->pMsgPtr = &pSRB->MsgInBuf[1];
- } else if (bval == MSG_MESSAGE_REJECT) {
- amd_write8(amd, SCSICMDREG, RESET_ATN_CMD);
-
- if (pSRB->SRBState & DO_SYNC_NEGO) {
- goto set_async;
- }
- } else if (bval == MSG_RESTOREPOINTERS) {
- goto min6;
- } else {
- goto min6;
- }
- } else { /* minx: */
- *pSRB->pMsgPtr = bval;
- pSRB->MsgCnt++;
- pSRB->pMsgPtr++;
- if ((pSRB->MsgInBuf[0] >= MSG_SIMPLE_Q_TAG)
- && (pSRB->MsgInBuf[0] <= MSG_ORDERED_Q_TAG)) {
- if (pSRB->MsgCnt == 2) {
- pSRB->SRBState = 0;
- pSRB = &amd->SRB_array[pSRB->MsgInBuf[1]];
- if (pSRB->SRBState & SRB_DISCONNECT) == 0) {
- pSRB = amd->pTmpSRB;
- pSRB->SRBState = SRB_UNEXPECT_RESEL;
- pDCB->pActiveSRB = pSRB;
- pSRB->MsgOutBuf[0] = MSG_ABORT_TAG;
- EnableMsgOut2(amd, pSRB);
- } else {
- if (pDCB->DCBFlag & ABORT_DEV_) {
- pSRB->SRBState = SRB_ABORT_SENT;
- EnableMsgOut1(amd, pSRB);
- }
- pDCB->pActiveSRB = pSRB;
- pSRB->SRBState = SRB_DATA_XFER;
- }
- }
- } else if ((pSRB->MsgInBuf[0] == MSG_EXTENDED)
- && (pSRB->MsgCnt == 5)) {
- pSRB->SRBState &= ~(SRB_MSGIN_MULTI + DO_SYNC_NEGO);
- if ((pSRB->MsgInBuf[1] != 3)
- || (pSRB->MsgInBuf[2] != 1)) { /* reject_msg: */
- pSRB->MsgCnt = 1;
- pSRB->MsgInBuf[0] = MSG_MESSAGE_REJECT;
- amd_write8(amd, SCSICMDREG, SET_ATN_CMD);
- } else if (!(pSRB->MsgInBuf[3])
- || !(pSRB->MsgInBuf[4])) {
- set_async: /* set async */
-
- pDCB = pSRB->pSRBDCB;
- /* disable sync & sync nego */
- pDCB->SyncMode &= ~(SYNC_ENABLE|SYNC_NEGO_DONE);
- pDCB->SyncPeriod = 0;
- pDCB->SyncOffset = 0;
-
- pDCB->tinfo.goal.period = 0;
- pDCB->tinfo.goal.offset = 0;
-
- pDCB->tinfo.current.period = 0;
- pDCB->tinfo.current.offset = 0;
- pDCB->tinfo.current.width =
- MSG_EXT_WDTR_BUS_8_BIT;
-
- pDCB->CtrlR3 = FAST_CLK; /* non_fast */
- pDCB->CtrlR4 &= 0x3f;
- pDCB->CtrlR4 |= EATER_25NS;
- goto re_prog;
- } else {/* set sync */
-
- pDCB = pSRB->pSRBDCB;
- /* enable sync & sync nego */
- pDCB->SyncMode |= SYNC_ENABLE|SYNC_NEGO_DONE;
-
- /* set sync offset */
- pDCB->SyncOffset &= 0x0f0;
- pDCB->SyncOffset |= pSRB->MsgInBuf[4];
-
- /* set sync period */
- pDCB->MaxNegoPeriod = pSRB->MsgInBuf[3];
-
- wval = (u_int16_t) pSRB->MsgInBuf[3];
- wval = wval << 2;
- wval--;
- wval1 = wval / 25;
- if ((wval1 * 25) != wval) {
- wval1++;
- }
- bval = FAST_CLK|FAST_SCSI;
- pDCB->CtrlR4 &= 0x3f;
- if (wval1 >= 8) {
- /* Fast SCSI */
- wval1--;
- bval = FAST_CLK;
- pDCB->CtrlR4 |= EATER_25NS;
- }
- pDCB->CtrlR3 = bval;
- pDCB->SyncPeriod = (u_int8_t) wval1;
-
- pDCB->tinfo.goal.period =
- tinfo_sync_period[pDCB->SyncPeriod - 4];
- pDCB->tinfo.goal.offset = pDCB->SyncOffset;
- pDCB->tinfo.current.period =
- tinfo_sync_period[pDCB->SyncPeriod - 4];
- pDCB->tinfo.current.offset = pDCB->SyncOffset;
-
- /*
- * program SCSI control register
- */
- re_prog:
- amd_write8(amd, SYNCPERIOREG, pDCB->SyncPeriod);
- amd_write8(amd, SYNCOFFREG, pDCB->SyncOffset);
- amd_write8(amd, CNTLREG3, pDCB->CtrlR3);
- amd_write8(amd, CNTLREG4, pDCB->CtrlR4);
- }
- }
- }
-min6:
- amd_write8(amd, SCSICMDREG, MSG_ACCEPTED_CMD);
- return (SCSI_NOP0);
-}
-#endif
-
-static u_int
-amd_DataOutPhase1(struct amd_softc *amd, struct amd_srb *pSRB, u_int scsistat)
-{
- DataIO_Comm(amd, pSRB, WRITE_DIRECTION);
- return (scsistat);
-}
-
-static u_int
-amd_DataInPhase1(struct amd_softc *amd, struct amd_srb *pSRB, u_int scsistat)
-{
- DataIO_Comm(amd, pSRB, READ_DIRECTION);
- return (scsistat);
-}
-
-static void
-DataIO_Comm(struct amd_softc *amd, struct amd_srb *pSRB, u_int ioDir)
-{
- struct amd_sg * psgl;
- u_int32_t lval;
-
- if (pSRB->SGIndex < pSRB->SGcount) {
- amd_write8(amd, DMA_Cmd, DMA_IDLE_CMD|ioDir);/* |EN_DMA_INT */
-
- if (!pSRB->SGToBeXferLen) {
- psgl = pSRB->pSGlist;
- pSRB->SGPhysAddr = psgl->SGXPtr;
- pSRB->SGToBeXferLen = psgl->SGXLen;
- }
- lval = pSRB->SGToBeXferLen;
- amd_write8(amd, CTCREG_LOW, lval);
- amd_write8(amd, CTCREG_MID, lval >> 8);
- amd_write8(amd, CURTXTCNTREG, lval >> 16);
-
- amd_write32(amd, DMA_XferCnt, pSRB->SGToBeXferLen);
-
- amd_write32(amd, DMA_XferAddr, pSRB->SGPhysAddr);
-
- pSRB->SRBState = SRB_DATA_XFER;
-
- amd_write8(amd, SCSICMDREG, DMA_COMMAND|INFO_XFER_CMD);
-
- amd_write8(amd, DMA_Cmd, DMA_IDLE_CMD|ioDir); /* |EN_DMA_INT */
-
- amd_write8(amd, DMA_Cmd, DMA_START_CMD|ioDir);/* |EN_DMA_INT */
- } else { /* xfer pad */
- if (pSRB->SGcount) {
- pSRB->AdaptStatus = H_OVER_UNDER_RUN;
- pSRB->SRBStatus |= OVER_RUN;
- }
- amd_write8(amd, CTCREG_LOW, 0);
- amd_write8(amd, CTCREG_MID, 0);
- amd_write8(amd, CURTXTCNTREG, 0);
-
- pSRB->SRBState |= SRB_XFERPAD;
- amd_write8(amd, SCSICMDREG, DMA_COMMAND|XFER_PAD_BYTE);
- }
-}
-
-static u_int
-amd_CommandPhase1(struct amd_softc *amd, struct amd_srb *srb, u_int scsistat)
-{
- amd_write8(amd, SCSICMDREG, RESET_ATN_CMD);
- amd_write8(amd, SCSICMDREG, CLEAR_FIFO_CMD);
-
- amdsetupcommand(amd, srb);
-
- srb->SRBState = SRB_COMMAND;
- amd_write8(amd, SCSICMDREG, INFO_XFER_CMD);
- return (scsistat);
-}
-
-static u_int
-amd_StatusPhase1(struct amd_softc *amd, struct amd_srb *pSRB, u_int scsistat)
-{
- amd_write8(amd, SCSICMDREG, CLEAR_FIFO_CMD);
- pSRB->SRBState = SRB_STATUS;
- amd_write8(amd, SCSICMDREG, INITIATOR_CMD_CMPLTE);
- return (scsistat);
-}
-
-static u_int
-amd_MsgOutPhase1(struct amd_softc *amd, struct amd_srb *pSRB, u_int scsistat)
-{
- amd_write8(amd, SCSICMDREG, CLEAR_FIFO_CMD);
-
- if (amd->msgout_len == 0) {
- amd->msgout_buf[0] = MSG_NOOP;
- amd->msgout_len = 1;
- }
- amd_write8_multi(amd, SCSIFIFOREG, amd->msgout_buf, amd->msgout_len);
- amd_write8(amd, SCSICMDREG, INFO_XFER_CMD);
- return (scsistat);
-}
-
-static u_int
-amd_MsgInPhase1(struct amd_softc *amd, struct amd_srb *pSRB, u_int scsistat)
-{
- amd_write8(amd, SCSICMDREG, CLEAR_FIFO_CMD);
- amd_write8(amd, SCSICMDREG, INFO_XFER_CMD);
- return (scsistat);
-}
-
-static u_int
-amd_NopPhase(struct amd_softc *amd, struct amd_srb *pSRB, u_int scsistat)
-{
- return (scsistat);
-}
-
-static void
-amd_Disconnect(struct amd_softc * amd)
-{
- struct amd_srb *srb;
- int target;
- int lun;
-
- srb = amd->active_srb;
- amd->active_srb = NULL;
- amd->last_phase = SCSI_BUS_FREE;
- amd_write8(amd, SCSICMDREG, EN_SEL_RESEL);
- target = amd->cur_target;
- lun = amd->cur_lun;
-
- if (srb == NULL) {
- /* Invalid reselection */
- amdrunwaiting(amd);
- } else if (srb->SRBState & SRB_ABORT_SENT) {
- /* Clean up and done this srb */
-#if 0
- while (( = TAILQ_FIRST(&amd->running_srbs)) != NULL) {
- /* XXX What about "done'ing" these srbs??? */
- if (pSRB->pSRBDCB == pDCB) {
- TAILQ_REMOVE(&amd->running_srbs, pSRB, links);
- TAILQ_INSERT_HEAD(&amd->free_srbs, pSRB, links);
- }
- }
- amdrunwaiting(amd);
-#endif
- } else {
- if ((srb->SRBState & (SRB_START | SRB_MSGOUT))
- || !(srb->SRBState & (SRB_DISCONNECT | SRB_COMPLETED))) {
- srb->TargetStatus = AMD_SCSI_STAT_SEL_TIMEOUT;
- goto disc1;
- } else if (srb->SRBState & SRB_DISCONNECT) {
- if (!(srb->pccb->ccb_h.flags & CAM_TAG_ACTION_VALID))
- amd->untagged_srbs[target][lun] = srb;
- amdrunwaiting(amd);
- } else if (srb->SRBState & SRB_COMPLETED) {
- disc1:
- srb->SRBState = SRB_FREE;
- SRBdone(amd, srb);
- }
- }
- return;
-}
-
-static void
-amd_Reselect(struct amd_softc *amd)
-{
- struct amd_target_info *tinfo;
- u_int16_t disc_count;
-
- amd_clear_msg_state(amd);
- if (amd->active_srb != NULL) {
- /* Requeue the SRB for our attempted Selection */
- TAILQ_REMOVE(&amd->running_srbs, amd->active_srb, links);
- TAILQ_INSERT_HEAD(&amd->waiting_srbs, amd->active_srb, links);
- amd->active_srb = NULL;
- }
- /* get ID */
- amd->cur_target = amd_read8(amd, SCSIFIFOREG);
- amd->cur_target ^= amd->HostID_Bit;
- amd->cur_target = ffs(amd->cur_target) - 1;
- amd->cur_lun = amd_read8(amd, SCSIFIFOREG) & 7;
- tinfo = &amd->tinfo[amd->cur_target];
- amd->active_srb = amd->untagged_srbs[amd->cur_target][amd->cur_lun];
- disc_count = amd->disc_count[amd->cur_target][amd->cur_lun];
- if (disc_count == 0) {
- printf("amd%d: Unexpected reselection for target %d, "
- "Issuing Abort\n", amd->unit, amd->cur_target);
- amd->msgout_buf[0] = MSG_ABORT;
- amd->msgout_len = 1;
- amd_write8(amd, SCSICMDREG, SET_ATN_CMD);
- }
- if (amd->active_srb != NULL) {
- amd->disc_count[amd->cur_target][amd->cur_lun]--;
- amd->untagged_srbs[amd->cur_target][amd->cur_lun] = NULL;
- }
-
- amd_write8(amd, SCSIDESTIDREG, amd->cur_target);
- amd_write8(amd, SYNCPERIOREG, tinfo->sync_period_reg);
- amd_write8(amd, SYNCOFFREG, tinfo->sync_offset_reg);
- amd_write8(amd, CNTLREG1, tinfo->CtrlR1);
- amd_write8(amd, CNTLREG3, tinfo->CtrlR3);
- amd_write8(amd, CNTLREG4, tinfo->CtrlR4);
- amd_write8(amd, SCSICMDREG, MSG_ACCEPTED_CMD);/* drop /ACK */
- amd->last_phase = SCSI_NOP0;
-}
-
-static void
-SRBdone(struct amd_softc *amd, struct amd_srb *pSRB)
-{
- u_int8_t bval, i, status;
- union ccb *pccb;
- struct ccb_scsiio *pcsio;
- int intflag;
- struct amd_sg *ptr2;
- u_int32_t swlval;
-
- pccb = pSRB->pccb;
- pcsio = &pccb->csio;
-
- CAM_DEBUG(pccb->ccb_h.path, CAM_DEBUG_TRACE,
- ("SRBdone - TagNumber %d\n", pSRB->TagNumber));
-
- if ((pccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) {
- bus_dmasync_op_t op;
-
- if ((pccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN)
- op = BUS_DMASYNC_POSTREAD;
- else
- op = BUS_DMASYNC_POSTWRITE;
- bus_dmamap_sync(amd->buffer_dmat, pSRB->dmamap, op);
- bus_dmamap_unload(amd->buffer_dmat, pSRB->dmamap);
- }
-
- status = pSRB->TargetStatus;
- pccb->ccb_h.status = CAM_REQ_CMP;
- if (pSRB->SRBFlag & AUTO_REQSENSE) {
- pSRB->SRBFlag &= ~AUTO_REQSENSE;
- pSRB->AdaptStatus = 0;
- pSRB->TargetStatus = SCSI_STATUS_CHECK_COND;
-
- if (status == SCSI_STATUS_CHECK_COND) {
- pccb->ccb_h.status = CAM_AUTOSENSE_FAIL;
- goto ckc_e;
- }
- *((u_int32_t *)&(pSRB->CmdBlock[0])) = pSRB->Segment0[0];
-
- pcsio->sense_resid = pcsio->sense_len
- - pSRB->TotalXferredLen;
- pSRB->TotalXferredLen = pSRB->Segment1[1];
- if (pSRB->TotalXferredLen) {
- /* ???? */
- pcsio->resid = pcsio->dxfer_len
- - pSRB->TotalXferredLen;
- /* The resid field contains valid data */
- /* Flush resid bytes on complete */
- } else {
- pcsio->scsi_status = SCSI_STATUS_CHECK_COND;
- }
- bzero(&pcsio->sense_data, pcsio->sense_len);
- bcopy(amd_get_sense_buf(amd, pSRB), &pcsio->sense_data,
- pcsio->sense_len);
- pccb->ccb_h.status = CAM_AUTOSNS_VALID;
- goto ckc_e;
- }
- if (status) {
- if (status == SCSI_STATUS_CHECK_COND) {
-
- if ((pSRB->SGIndex < pSRB->SGcount)
- && (pSRB->SGcount) && (pSRB->SGToBeXferLen)) {
- bval = pSRB->SGcount;
- swlval = pSRB->SGToBeXferLen;
- ptr2 = pSRB->pSGlist;
- ptr2++;
- for (i = pSRB->SGIndex + 1; i < bval; i++) {
- swlval += ptr2->SGXLen;
- ptr2++;
- }
- /* ??????? */
- pcsio->resid = (u_int32_t) swlval;
-
-#ifdef AMD_DEBUG0
- printf("XferredLen=%8x,NotYetXferLen=%8x,",
- pSRB->TotalXferredLen, swlval);
-#endif
- }
- if ((pcsio->ccb_h.flags & CAM_DIS_AUTOSENSE) == 0) {
-#ifdef AMD_DEBUG0
- printf("RequestSense..................\n");
-#endif
- RequestSense(amd, pSRB);
- return;
- }
- pcsio->scsi_status = SCSI_STATUS_CHECK_COND;
- pccb->ccb_h.status = CAM_SCSI_STATUS_ERROR;
- goto ckc_e;
- } else if (status == SCSI_STATUS_QUEUE_FULL) {
- pSRB->AdaptStatus = 0;
- pSRB->TargetStatus = 0;
- pcsio->scsi_status = SCSI_STATUS_QUEUE_FULL;
- pccb->ccb_h.status = CAM_SCSI_STATUS_ERROR;
- goto ckc_e;
- } else if (status == AMD_SCSI_STAT_SEL_TIMEOUT) {
- pSRB->AdaptStatus = H_SEL_TIMEOUT;
- pSRB->TargetStatus = 0;
-
- pcsio->scsi_status = AMD_SCSI_STAT_SEL_TIMEOUT;
- pccb->ccb_h.status = CAM_SEL_TIMEOUT;
- } else if (status == SCSI_STATUS_BUSY) {
-#ifdef AMD_DEBUG0
- printf("DC390: target busy at %s %d\n",
- __FILE__, __LINE__);
-#endif
- pcsio->scsi_status = SCSI_STATUS_BUSY;
- pccb->ccb_h.status = CAM_SCSI_BUSY;
- } else if (status == SCSI_STATUS_RESERV_CONFLICT) {
-#ifdef AMD_DEBUG0
- printf("DC390: target reserved at %s %d\n",
- __FILE__, __LINE__);
-#endif
- pcsio->scsi_status = SCSI_STATUS_RESERV_CONFLICT;
- pccb->ccb_h.status = CAM_SCSI_STATUS_ERROR; /* XXX */
- } else {
- pSRB->AdaptStatus = 0;
-#ifdef AMD_DEBUG0
- printf("DC390: driver stuffup at %s %d\n",
- __FILE__, __LINE__);
-#endif
- pccb->ccb_h.status = CAM_SCSI_STATUS_ERROR;
- }
- } else {
- status = pSRB->AdaptStatus;
- if (status & H_OVER_UNDER_RUN) {
- pSRB->TargetStatus = 0;
-
- pccb->ccb_h.status = CAM_DATA_RUN_ERR;
- } else if (pSRB->SRBStatus & PARITY_ERROR) {
-#ifdef AMD_DEBUG0
- printf("DC390: driver stuffup %s %d\n",
- __FILE__, __LINE__);
-#endif
- /* Driver failed to perform operation */
- pccb->ccb_h.status = CAM_UNCOR_PARITY;
- } else { /* No error */
- pSRB->AdaptStatus = 0;
- pSRB->TargetStatus = 0;
- pcsio->resid = 0;
- /* there is no error, (sense is invalid) */
- }
- }
-ckc_e:
- intflag = splcam();
- if ((pccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
- /* CAM request not yet complete =>device_Q frozen */
- xpt_freeze_devq(pccb->ccb_h.path, 1);
- pccb->ccb_h.status |= CAM_DEV_QFRZN;
- }
- TAILQ_REMOVE(&amd->running_srbs, pSRB, links);
- TAILQ_INSERT_HEAD(&amd->free_srbs, pSRB, links);
- amdrunwaiting(amd);
- splx(intflag);
- xpt_done(pccb);
-
-}
-
-static void
-amd_ResetSCSIBus(struct amd_softc * amd)
-{
- int intflag;
-
- intflag = splcam();
- amd->ACBFlag |= RESET_DEV;
- amd_write8(amd, DMA_Cmd, DMA_IDLE_CMD);
- amd_write8(amd, SCSICMDREG, RST_SCSI_BUS_CMD);
- splx(intflag);
- return;
-}
-
-static void
-amd_ScsiRstDetect(struct amd_softc * amd)
-{
- int intflag;
- u_int32_t wlval;
-
-#ifdef AMD_DEBUG0
- printf("amd_ScsiRstDetect \n");
-#endif
-
- wlval = 1000;
- while (--wlval) { /* delay 1 sec */
- DELAY(1000);
- }
- intflag = splcam();
-
- amd_write8(amd, DMA_Cmd, DMA_IDLE_CMD);
- amd_write8(amd, SCSICMDREG, CLEAR_FIFO_CMD);
-
- if (amd->ACBFlag & RESET_DEV) {
- amd->ACBFlag |= RESET_DONE;
- } else {
- amd->ACBFlag |= RESET_DETECT;
- ResetDevParam(amd);
- amdcompletematch(amd, CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD,
- AMD_TAG_WILDCARD, &amd->running_srbs,
- CAM_DEV_QFRZN|CAM_SCSI_BUS_RESET);
- amdcompletematch(amd, CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD,
- AMD_TAG_WILDCARD, &amd->waiting_srbs,
- CAM_DEV_QFRZN|CAM_SCSI_BUS_RESET);
- amd->active_srb = NULL;
- amd->ACBFlag = 0;
- amdrunwaiting(amd);
- }
- splx(intflag);
- return;
-}
-
-static void
-RequestSense(struct amd_softc *amd, struct amd_srb *pSRB)
-{
- union ccb *pccb;
- struct ccb_scsiio *pcsio;
-
- pccb = pSRB->pccb;
- pcsio = &pccb->csio;
-
- pSRB->SRBFlag |= AUTO_REQSENSE;
- pSRB->Segment0[0] = *((u_int32_t *) & (pSRB->CmdBlock[0]));
- pSRB->Segment0[1] = *((u_int32_t *) & (pSRB->CmdBlock[4]));
- pSRB->Segment1[0] = (pSRB->ScsiCmdLen << 8) + pSRB->SGcount;
- pSRB->Segment1[1] = pSRB->TotalXferredLen;
-
- pSRB->AdaptStatus = 0;
- pSRB->TargetStatus = 0;
-
- pSRB->Segmentx.SGXPtr = amd_get_sense_bufaddr(amd, pSRB);
- pSRB->Segmentx.SGXLen = amd_get_sense_bufsize(amd, pSRB);
-
- pSRB->pSGlist = &pSRB->Segmentx;
- pSRB->SGcount = 1;
- pSRB->SGIndex = 0;
-
- pSRB->CmdBlock[0] = REQUEST_SENSE;
- pSRB->CmdBlock[1] = pSRB->pccb->ccb_h.target_lun << 5;
- pSRB->CmdBlock[2] = 0;
- pSRB->CmdBlock[3] = 0;
- pSRB->CmdBlock[4] = pcsio->sense_len;
- pSRB->CmdBlock[5] = 0;
- pSRB->ScsiCmdLen = 6;
-
- pSRB->TotalXferredLen = 0;
- pSRB->SGToBeXferLen = 0;
- if (amdstart(amd, pSRB) != 0) {
- TAILQ_REMOVE(&amd->running_srbs, pSRB, links);
- TAILQ_INSERT_HEAD(&amd->waiting_srbs, pSRB, links);
- }
-}
-
-static void
-amd_InvalidCmd(struct amd_softc * amd)
-{
- struct amd_srb *srb;
-
- srb = amd->active_srb;
- if (srb->SRBState & (SRB_START|SRB_MSGOUT))
- amd_write8(amd, SCSICMDREG, CLEAR_FIFO_CMD);
-}
-
-void
-amd_linkSRB(struct amd_softc *amd)
-{
- u_int16_t count, i;
- struct amd_srb *psrb;
- int error;
-
- count = amd->SRBCount;
-
- for (i = 0; i < count; i++) {
- psrb = (struct amd_srb *)&amd->SRB_array[i];
- psrb->TagNumber = i;
-
- /*
- * Create the dmamap. This is no longer optional!
- *
- * XXX Since there is no detach method in this driver,
- * this does not get freed!
- */
- if ((error = bus_dmamap_create(amd->buffer_dmat, 0,
- &psrb->dmamap)) != 0) {
- device_printf(amd->dev, "Error %d creating buffer "
- "dmamap!\n", error);
- return;
- }
- TAILQ_INSERT_TAIL(&amd->free_srbs, psrb, links);
- }
-}
-
-static void
-amd_EnDisableCE(struct amd_softc *amd, int mode, int *regval)
-{
- if (mode == ENABLE_CE) {
- *regval = 0xc0;
- } else {
- *regval = 0x80;
- }
- pci_write_config(amd->dev, *regval, 0, /*bytes*/1);
- if (mode == DISABLE_CE) {
- pci_write_config(amd->dev, *regval, 0, /*bytes*/1);
- }
- DELAY(160);
-}
-
-static void
-amd_EEpromOutDI(struct amd_softc *amd, int *regval, int Carry)
-{
- u_int bval;
-
- bval = 0;
- if (Carry) {
- bval = 0x40;
- *regval = 0x80;
- pci_write_config(amd->dev, *regval, bval, /*bytes*/1);
- }
- DELAY(160);
- bval |= 0x80;
- pci_write_config(amd->dev, *regval, bval, /*bytes*/1);
- DELAY(160);
- pci_write_config(amd->dev, *regval, 0, /*bytes*/1);
- DELAY(160);
-}
-
-static int
-amd_EEpromInDO(struct amd_softc *amd)
-{
- pci_write_config(amd->dev, 0x80, 0x80, /*bytes*/1);
- DELAY(160);
- pci_write_config(amd->dev, 0x80, 0x40, /*bytes*/1);
- DELAY(160);
- if (pci_read_config(amd->dev, 0, /*bytes*/1) == 0x22)
- return (1);
- return (0);
-}
-
-static u_int16_t
-EEpromGetData1(struct amd_softc *amd)
-{
- u_int i;
- u_int carryFlag;
- u_int16_t wval;
-
- wval = 0;
- for (i = 0; i < 16; i++) {
- wval <<= 1;
- carryFlag = amd_EEpromInDO(amd);
- wval |= carryFlag;
- }
- return (wval);
-}
-
-static void
-amd_Prepare(struct amd_softc *amd, int *regval, u_int8_t EEpromCmd)
-{
- u_int i, j;
- int carryFlag;
-
- carryFlag = 1;
- j = 0x80;
- for (i = 0; i < 9; i++) {
- amd_EEpromOutDI(amd, regval, carryFlag);
- carryFlag = (EEpromCmd & j) ? 1 : 0;
- j >>= 1;
- }
-}
-
-static void
-amd_ReadEEprom(struct amd_softc *amd)
-{
- int regval;
- u_int i;
- u_int16_t *ptr;
- u_int8_t cmd;
-
- ptr = (u_int16_t *)&amd->eepromBuf[0];
- cmd = EEPROM_READ;
- for (i = 0; i < 0x40; i++) {
- amd_EnDisableCE(amd, ENABLE_CE, &regval);
- amd_Prepare(amd, &regval, cmd);
- *ptr = EEpromGetData1(amd);
- ptr++;
- cmd++;
- amd_EnDisableCE(amd, DISABLE_CE, &regval);
- }
-}
-
-static void
-amd_load_defaults(struct amd_softc *amd)
-{
- int target;
-
- bzero(&amd->eepromBuf, sizeof amd->eepromBuf);
- for (target = 0; target < MAX_SCSI_ID; target++)
- amd->eepromBuf[target << 2] =
- (TAG_QUEUING|EN_DISCONNECT|SYNC_NEGO|PARITY_CHK);
- amd->eepromBuf[EE_ADAPT_SCSI_ID] = 7;
- amd->eepromBuf[EE_MODE2] = ACTIVE_NEGATION|LUN_CHECK|GREATER_1G;
- amd->eepromBuf[EE_TAG_CMD_NUM] = 4;
-}
-
-static void
-amd_load_eeprom_or_defaults(struct amd_softc *amd)
-{
- u_int16_t wval, *ptr;
- u_int8_t i;
-
- amd_ReadEEprom(amd);
- wval = 0;
- ptr = (u_int16_t *) & amd->eepromBuf[0];
- for (i = 0; i < EE_DATA_SIZE; i += 2, ptr++)
- wval += *ptr;
-
- if (wval != EE_CHECKSUM) {
- if (bootverbose)
- printf("amd%d: SEEPROM data unavailable. "
- "Using default device parameters.\n",
- amd->unit);
- amd_load_defaults(amd);
- }
-}
-
-/*
- **********************************************************************
- * Function : static int amd_init (struct Scsi_Host *host)
- * Purpose : initialize the internal structures for a given SCSI host
- * Inputs : host - pointer to this host adapter's structure/
- **********************************************************************
- */
-static int
-amd_init(device_t dev)
-{
- struct amd_softc *amd = device_get_softc(dev);
- struct resource *iores;
- int i, rid;
- u_int bval;
-
- rid = PCI_BASE_ADDR0;
- iores = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid, RF_ACTIVE);
- if (iores == NULL) {
- if (bootverbose)
- printf("amd_init: bus_alloc_resource failure!\n");
- return ENXIO;
- }
- amd->tag = rman_get_bustag(iores);
- amd->bsh = rman_get_bushandle(iores);
-
- /* DMA tag for mapping buffers into device visible space. */
- 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*/AMD_NSEG,
- /*maxsegsz*/AMD_MAXTRANSFER_SIZE,
- /*flags*/BUS_DMA_ALLOCNOW,
- /*lockfunc*/busdma_lock_mutex,
- /*lockarg*/&Giant,
- &amd->buffer_dmat) != 0) {
- if (bootverbose)
- printf("amd_init: bus_dma_tag_create failure!\n");
- return ENXIO;
- }
-
- /* 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) * MAX_SRB_CNT,
- /*nsegments*/1,
- /*maxsegsz*/AMD_MAXTRANSFER_SIZE,
- /*flags*/0,
- /*lockfunc*/busdma_lock_mutex,
- /*lockarg*/&Giant, &amd->sense_dmat) != 0) {
- if (bootverbose)
- device_printf(dev, "cannot create sense buffer dmat\n");
- return (ENXIO);
- }
-
- if (bus_dmamem_alloc(amd->sense_dmat, (void **)&amd->sense_buffers,
- BUS_DMA_NOWAIT, &amd->sense_dmamap) != 0)
- return (ENOMEM);
-
- bus_dmamap_load(amd->sense_dmat, amd->sense_dmamap,
- amd->sense_buffers,
- sizeof(struct scsi_sense_data) * MAX_SRB_CNT,
- amd_dmamap_cb, &amd->sense_busaddr, /*flags*/0);
-
- TAILQ_INIT(&amd->free_srbs);
- TAILQ_INIT(&amd->running_srbs);
- TAILQ_INIT(&amd->waiting_srbs);
- amd->last_phase = SCSI_BUS_FREE;
- amd->dev = dev;
- amd->unit = device_get_unit(dev);
- amd->SRBCount = MAX_SRB_CNT;
- amd->status = 0;
- amd_load_eeprom_or_defaults(amd);
- amd->max_id = 7;
- if (amd->eepromBuf[EE_MODE2] & LUN_CHECK) {
- amd->max_lun = 7;
- } else {
- amd->max_lun = 0;
- }
- amd->AdaptSCSIID = amd->eepromBuf[EE_ADAPT_SCSI_ID];
- amd->HostID_Bit = (1 << amd->AdaptSCSIID);
- amd->AdaptSCSILUN = 0;
- /* (eepromBuf[EE_TAG_CMD_NUM]) << 2; */
- amd->ACBFlag = 0;
- amd->Gmode2 = amd->eepromBuf[EE_MODE2];
- amd_linkSRB(amd);
- for (i = 0; i <= amd->max_id; i++) {
-
- if (amd->AdaptSCSIID != i) {
- struct amd_target_info *tinfo;
- PEEprom prom;
-
- tinfo = &amd->tinfo[i];
- prom = (PEEprom)&amd->eepromBuf[i << 2];
- if ((prom->EE_MODE1 & EN_DISCONNECT) != 0) {
- tinfo->disc_tag |= AMD_USR_DISCENB;
- if ((prom->EE_MODE1 & TAG_QUEUING) != 0)
- tinfo->disc_tag |= AMD_USR_TAGENB;
- }
- if ((prom->EE_MODE1 & SYNC_NEGO) != 0) {
- tinfo->user.period =
- eeprom_period[prom->EE_SPEED];
- tinfo->user.offset = AMD_MAX_SYNC_OFFSET;
- }
- tinfo->CtrlR1 = amd->AdaptSCSIID;
- if ((prom->EE_MODE1 & PARITY_CHK) != 0)
- tinfo->CtrlR1 |= PARITY_ERR_REPO;
- tinfo->CtrlR3 = FAST_CLK;
- tinfo->CtrlR4 = EATER_25NS;
- if ((amd->eepromBuf[EE_MODE2] & ACTIVE_NEGATION) != 0)
- tinfo->CtrlR4 |= NEGATE_REQACKDATA;
- }
- }
- amd_write8(amd, SCSITIMEOUTREG, 153); /* 250ms selection timeout */
- /* Conversion factor = 0 , 40MHz clock */
- amd_write8(amd, CLKFACTREG, CLK_FREQ_40MHZ);
- /* NOP cmd - clear command register */
- amd_write8(amd, SCSICMDREG, NOP_CMD);
- amd_write8(amd, CNTLREG2, EN_FEATURE|EN_SCSI2_CMD);
- amd_write8(amd, CNTLREG3, FAST_CLK);
- bval = EATER_25NS;
- if (amd->eepromBuf[EE_MODE2] & ACTIVE_NEGATION) {
- bval |= NEGATE_REQACKDATA;
- }
- amd_write8(amd, CNTLREG4, bval);
-
- /* Disable SCSI bus reset interrupt */
- amd_write8(amd, CNTLREG1, DIS_INT_ON_SCSI_RST);
-
- return 0;
-}
-
-/*
- * attach and init a host adapter
- */
-static int
-amd_attach(device_t dev)
-{
- struct cam_devq *devq; /* Device Queue to use for this SIM */
- u_int8_t intstat;
- struct amd_softc *amd = device_get_softc(dev);
- int unit = device_get_unit(dev);
- int rid;
- void *ih;
- struct resource *irqres;
-
- if (amd_init(dev)) {
- if (bootverbose)
- printf("amd_attach: amd_init failure!\n");
- return ENXIO;
- }
-
- /* Reset Pending INT */
- intstat = amd_read8(amd, INTSTATREG);
-
- /* After setting up the adapter, map our interrupt */
- rid = 0;
- irqres = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
- RF_SHAREABLE | RF_ACTIVE);
- if (irqres == NULL ||
- bus_setup_intr(dev, irqres, INTR_TYPE_CAM | INTR_ENTROPY,
- NULL, amd_intr, amd, &ih)) {
- if (bootverbose)
- printf("amd%d: unable to register interrupt handler!\n",
- unit);
- return ENXIO;
- }
-
- /*
- * Now let the CAM generic SCSI layer find the SCSI devices on
- * the bus * start queue to reset to the idle loop. *
- * Create device queue of SIM(s) * (MAX_START_JOB - 1) :
- * max_sim_transactions
- */
- devq = cam_simq_alloc(MAX_START_JOB);
- if (devq == NULL) {
- if (bootverbose)
- printf("amd_attach: cam_simq_alloc failure!\n");
- return ENXIO;
- }
-
- amd->psim = cam_sim_alloc(amd_action, amd_poll, "amd",
- amd, amd->unit, &Giant,
- 1, MAX_TAGS_CMD_QUEUE, devq);
- if (amd->psim == NULL) {
- cam_simq_free(devq);
- if (bootverbose)
- printf("amd_attach: cam_sim_alloc failure!\n");
- return ENXIO;
- }
-
- if (xpt_bus_register(amd->psim, dev, 0) != CAM_SUCCESS) {
- cam_sim_free(amd->psim, /*free_devq*/TRUE);
- if (bootverbose)
- printf("amd_attach: xpt_bus_register failure!\n");
- return ENXIO;
- }
-
- if (xpt_create_path(&amd->ppath, /* periph */ NULL,
- cam_sim_path(amd->psim), CAM_TARGET_WILDCARD,
- CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
- xpt_bus_deregister(cam_sim_path(amd->psim));
- cam_sim_free(amd->psim, /* free_simq */ TRUE);
- if (bootverbose)
- printf("amd_attach: xpt_create_path failure!\n");
- return ENXIO;
- }
-
- return 0;
-}
-
-static int
-amd_probe(device_t dev)
-{
- if (pci_get_devid(dev) == PCI_DEVICE_ID_AMD53C974) {
- device_set_desc(dev,
- "Tekram DC390(T)/AMD53c974 SCSI Host Adapter");
- return BUS_PROBE_DEFAULT;
- }
- return ENXIO;
-}
-
-static device_method_t amd_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, amd_probe),
- DEVMETHOD(device_attach, amd_attach),
- { 0, 0 }
-};
-
-static driver_t amd_driver = {
- "amd", amd_methods, sizeof(struct amd_softc)
-};
-
-static devclass_t amd_devclass;
-DRIVER_MODULE(amd, pci, amd_driver, amd_devclass, 0, 0);
-MODULE_DEPEND(amd, pci, 1, 1, 1);
-MODULE_DEPEND(amd, cam, 1, 1, 1);
diff --git a/sys/dev/amd/amd.h b/sys/dev/amd/amd.h
deleted file mode 100644
index c671f22..0000000
--- a/sys/dev/amd/amd.h
+++ /dev/null
@@ -1,585 +0,0 @@
-/*-
- *********************************************************************
- * FILE NAME : amd.h
- * BY : C.L. Huang (ching@tekram.com.tw)
- * Erich Chen (erich@tekram.com.tw)
- * Description: Device Driver for the amd53c974 PCI Bus Master
- * SCSI Host adapter found on cards such as
- * the Tekram DC-390(T).
- * (C)Copyright 1995-1999 Tekram Technology Co., Ltd.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *********************************************************************
- * $FreeBSD$
- */
-
-#ifndef AMD_H
-#define AMD_H
-
-#define AMD_TRANS_CUR 0x01 /* Modify current neogtiation status */
-#define AMD_TRANS_ACTIVE 0x03 /* Assume this is the active target */
-#define AMD_TRANS_GOAL 0x04 /* Modify negotiation goal */
-#define AMD_TRANS_USER 0x08 /* Modify user negotiation settings */
-
-/*
- * Per target transfer parameters.
- */
-struct amd_transinfo {
- u_int8_t period;
- u_int8_t offset;
-};
-
-struct amd_target_info {
- /*
- * Records the currently active and user/default settings for
- * tagged queueing and disconnection for each target.
- */
- u_int8_t disc_tag;
-#define AMD_CUR_DISCENB 0x01
-#define AMD_CUR_TAGENB 0x02
-#define AMD_USR_DISCENB 0x04
-#define AMD_USR_TAGENB 0x08
- u_int8_t CtrlR1;
- u_int8_t CtrlR3;
- u_int8_t CtrlR4;
- u_int8_t sync_period_reg;
- u_int8_t sync_offset_reg;
-
- /*
- * Currently active transfer settings.
- */
- struct amd_transinfo current;
- /*
- * Transfer settings we wish to achieve
- * through negotiation.
- */
- struct amd_transinfo goal;
- /*
- * User defined or default transfer settings.
- */
- struct amd_transinfo user;
-};
-
-/*
- * Scatter/Gather Segment entry.
- */
-struct amd_sg {
- u_int32_t SGXLen;
- u_int32_t SGXPtr;
-};
-
-/*
- * Chipset feature limits
- */
-#define MAX_SCSI_ID 8
-#define AMD_MAX_SYNC_OFFSET 15
-#define AMD_TARGET_MAX 7
-#define AMD_LUN_MAX 7
-#define AMD_MAXPHYS (128 * 1024) /* legacy MAXPHYS */
-#define AMD_NSEG (btoc(AMD_MAXPHYS) + 1)
-#define AMD_MAXTRANSFER_SIZE 0xFFFFFF /* restricted by 24 bit counter */
-#define MAX_DEVICES 10
-#define MAX_TAGS_CMD_QUEUE 256
-#define MAX_CMD_PER_LUN 6
-#define MAX_SRB_CNT 256
-#define MAX_START_JOB 256
-
-/*
- * BIT position to integer mapping.
- */
-#define BIT(N) (0x01 << N)
-
-/*
- * EEPROM storage offsets and data structures.
- */
-typedef struct _EEprom {
- u_int8_t EE_MODE1;
- u_int8_t EE_SPEED;
- u_int8_t xx1;
- u_int8_t xx2;
-} EEprom, *PEEprom;
-
-#define EE_ADAPT_SCSI_ID 64
-#define EE_MODE2 65
-#define EE_DELAY 66
-#define EE_TAG_CMD_NUM 67
-#define EE_DATA_SIZE 128
-#define EE_CHECKSUM 0x1234
-
-/*
- * EE_MODE1 bits definition
- */
-#define PARITY_CHK BIT(0)
-#define SYNC_NEGO BIT(1)
-#define EN_DISCONNECT BIT(2)
-#define SEND_START BIT(3)
-#define TAG_QUEUING BIT(4)
-
-/*
- * EE_MODE2 bits definition
- */
-#define MORE2_DRV BIT(0)
-#define GREATER_1G BIT(1)
-#define RST_SCSI_BUS BIT(2)
-#define ACTIVE_NEGATION BIT(3)
-#define NO_SEEK BIT(4)
-#define LUN_CHECK BIT(5)
-
-#define ENABLE_CE 1
-#define DISABLE_CE 0
-#define EEPROM_READ 0x80
-
-#define AMD_TAG_WILDCARD ((u_int)(~0))
-
-/*
- * SCSI Request Block
- */
-struct amd_srb {
- TAILQ_ENTRY(amd_srb) links;
- u_int8_t CmdBlock[12];
- union ccb *pccb;
- bus_dmamap_t dmamap;
- struct amd_sg *pSGlist;
-
- u_int32_t TotalXferredLen;
- u_int32_t SGPhysAddr; /* a segment starting address */
- u_int32_t SGToBeXferLen; /* to be xfer length */
- u_int32_t Segment0[2];
- u_int32_t Segment1[2];
-
- struct amd_sg SGsegment[AMD_NSEG];
- struct amd_sg Segmentx;/* a one entry of S/G list table */
- u_int8_t *pMsgPtr;
- u_int16_t SRBState;
-
- u_int8_t AdaptStatus;
- u_int8_t TargetStatus;
- u_int8_t MsgCnt;
- u_int8_t EndMessage;
- u_int8_t TagNumber;
- u_int8_t SGcount;
- u_int8_t SGIndex;
- u_int8_t IORBFlag; /* ;81h-Reset, 2-retry */
-
- u_int8_t SRBStatus;
- u_int8_t SRBFlag;
- /* ; b0-AutoReqSense,b6-Read,b7-write */
- /* ; b4-settimeout,b5-Residual valid */
- u_int8_t ScsiCmdLen;
-};
-
-TAILQ_HEAD(srb_queue, amd_srb);
-
-/*
- * Per-adapter, software configuration.
- */
-struct amd_softc {
- device_t dev;
- bus_space_tag_t tag;
- bus_space_handle_t bsh;
- bus_dma_tag_t buffer_dmat; /* dmat for buffer I/O */
- bus_dma_tag_t sense_dmat; /* dmat for sense buffer */
- bus_dmamap_t sense_dmamap;
- struct scsi_sense_data *sense_buffers;
- bus_addr_t sense_busaddr;
- int unit;
-
- int last_phase;
- int cur_target;
- int cur_lun;
- struct amd_srb *active_srb;
- struct amd_srb *untagged_srbs[AMD_TARGET_MAX+1][AMD_LUN_MAX+1];
- struct amd_target_info tinfo[AMD_TARGET_MAX+1];
- u_int16_t disc_count[AMD_TARGET_MAX+1][AMD_LUN_MAX+1];
-
- struct srb_queue free_srbs;
- struct srb_queue waiting_srbs;
- struct srb_queue running_srbs;
-
- struct amd_srb *pTmpSRB;
-
- u_int16_t SRBCount;
-
- u_int16_t max_id;
- u_int16_t max_lun;
-
- /* Hooks into the CAM XPT */
- struct cam_sim *psim;
- struct cam_path *ppath;
-
- u_int8_t msgin_buf[6];
- u_int8_t msgout_buf[6];
- u_int msgin_index;
- u_int msgout_index;
- u_int msgout_len;
-
- u_int8_t status;
- u_int8_t AdaptSCSIID; /* ; Adapter SCSI Target ID */
- u_int8_t AdaptSCSILUN; /* ; Adapter SCSI LUN */
-
- u_int8_t ACBFlag;
-
- u_int8_t Gmode2;
-
- u_int8_t HostID_Bit;
-
- u_int8_t InitDCB_flag[8][8]; /* flag of initDCB for device */
- struct amd_srb SRB_array[MAX_SRB_CNT]; /* +45Ch, Len= */
- struct amd_srb TmpSRB;
- /* Setup data stored in an 93c46 serial eeprom */
- u_int8_t eepromBuf[EE_DATA_SIZE];
-};
-
-/*
- * ----SRB State machine definition
- */
-#define SRB_FREE 0
-#define SRB_READY BIT(1)
-#define SRB_MSGOUT BIT(2) /* ;arbitration+msg_out 1st byte */
-#define SRB_MSGIN BIT(3)
-#define SRB_MSGIN_MULTI BIT(4)
-#define SRB_COMMAND BIT(5)
-#define SRB_START BIT(6) /* ;arbitration+msg_out+command_out */
-#define SRB_DISCONNECT BIT(7)
-#define SRB_DATA_XFER BIT(8)
-#define SRB_XFERPAD BIT(9)
-#define SRB_STATUS BIT(10)
-#define SRB_COMPLETED BIT(11)
-#define SRB_ABORT_SENT BIT(12)
-#define DO_SYNC_NEGO BIT(13)
-#define SRB_UNEXPECT_RESEL BIT(14)
-
-/*
- * ---ACB Flag
- */
-#define RESET_DEV BIT(0)
-#define RESET_DETECT BIT(1)
-#define RESET_DONE BIT(2)
-
-/*
- * ---DCB Flag
- */
-#define ABORT_DEV_ BIT(0)
-
-/*
- * ---SRB status
- */
-#define SRB_OK BIT(0)
-#define ABORTION BIT(1)
-#define OVER_RUN BIT(2)
-#define UNDER_RUN BIT(3)
-#define PARITY_ERROR BIT(4)
-#define SRB_ERROR BIT(5)
-
-/*
- * ---SRB Flags
- */
-#define DATAOUT BIT(7)
-#define DATAIN BIT(6)
-#define RESIDUAL_VALID BIT(5)
-#define ENABLE_TIMER BIT(4)
-#define RESET_DEV0 BIT(2)
-#define ABORT_DEV BIT(1)
-#define AUTO_REQSENSE BIT(0)
-
-/*
- * ---Adapter status
- */
-#define H_STATUS_GOOD 0
-#define H_SEL_TIMEOUT 0x11
-#define H_OVER_UNDER_RUN 0x12
-#define H_UNEXP_BUS_FREE 0x13
-#define H_TARGET_PHASE_F 0x14
-#define H_INVALID_CCB_OP 0x16
-#define H_LINK_CCB_BAD 0x17
-#define H_BAD_TARGET_DIR 0x18
-#define H_DUPLICATE_CCB 0x19
-#define H_BAD_CCB_OR_SG 0x1A
-#define H_ABORT 0x0FF
-
-/*
- * AMD specific "status" codes returned in the SCSI status byte.
- */
-#define AMD_SCSI_STAT_UNEXP_BUS_F 0xFD /* ; Unexpect Bus Free */
-#define AMD_SCSI_STAT_BUS_RST_DETECT 0xFE /* ; Scsi Bus Reset detected */
-#define AMD_SCSI_STAT_SEL_TIMEOUT 0xFF /* ; Selection Time out */
-
-/*
- * ---Sync_Mode
- */
-#define SYNC_DISABLE 0
-#define SYNC_ENABLE BIT(0)
-#define SYNC_NEGO_DONE BIT(1)
-#define WIDE_ENABLE BIT(2)
-#define WIDE_NEGO_DONE BIT(3)
-#define EN_TAG_QUEUING BIT(4)
-#define EN_ATN_STOP BIT(5)
-
-#define SYNC_NEGO_OFFSET 15
-
-/*
- * ---SCSI bus phase
- */
-#define SCSI_DATA_OUT 0
-#define SCSI_DATA_IN 1
-#define SCSI_COMMAND 2
-#define SCSI_STATUS 3
-#define SCSI_NOP0 4
-#define SCSI_ARBITRATING 5
-#define SCSI_MSG_OUT 6
-#define SCSI_MSG_IN 7
-#define SCSI_BUS_FREE 8
-
-/*
- *==========================================================
- * AMD 53C974 Registers bit Definition
- *==========================================================
- */
-
-/*
- * ------SCSI Register-------
- * Command Reg.(+0CH)
- */
-#define DMA_COMMAND BIT(7)
-#define NOP_CMD 0
-#define CLEAR_FIFO_CMD 1
-#define RST_DEVICE_CMD 2
-#define RST_SCSI_BUS_CMD 3
-#define INFO_XFER_CMD 0x10
-#define INITIATOR_CMD_CMPLTE 0x11
-#define MSG_ACCEPTED_CMD 0x12
-#define XFER_PAD_BYTE 0x18
-#define SET_ATN_CMD 0x1A
-#define RESET_ATN_CMD 0x1B
-#define SEL_W_ATN 0x42
-#define SEL_W_ATN_STOP 0x43
-#define EN_SEL_RESEL 0x44
-#define SEL_W_ATN2 0x46
-#define DATA_XFER_CMD INFO_XFER_CMD
-
-
-/*
- * ------SCSI Register-------
- * SCSI Status Reg.(+10H)
- */
-#define INTERRUPT BIT(7)
-#define ILLEGAL_OP_ERR BIT(6)
-#define PARITY_ERR BIT(5)
-#define COUNT_2_ZERO BIT(4)
-#define GROUP_CODE_VALID BIT(3)
-#define SCSI_PHASE_MASK (BIT(2)+BIT(1)+BIT(0))
-
-/*
- * ------SCSI Register-------
- * Interrupt Status Reg.(+14H)
- */
-#define SCSI_RESET_ BIT(7)
-#define INVALID_CMD BIT(6)
-#define DISCONNECTED BIT(5)
-#define SERVICE_REQUEST BIT(4)
-#define SUCCESSFUL_OP BIT(3)
-#define RESELECTED BIT(2)
-#define SEL_ATTENTION BIT(1)
-#define SELECTED BIT(0)
-
-/*
- * ------SCSI Register-------
- * Internal State Reg.(+18H)
- */
-#define SYNC_OFFSET_FLAG BIT(3)
-#define INTRN_STATE_MASK (BIT(2)+BIT(1)+BIT(0))
-
-/*
- * ------SCSI Register-------
- * Clock Factor Reg.(+24H)
- */
-#define CLK_FREQ_40MHZ 0
-#define CLK_FREQ_35MHZ (BIT(2)+BIT(1)+BIT(0))
-#define CLK_FREQ_30MHZ (BIT(2)+BIT(1))
-#define CLK_FREQ_25MHZ (BIT(2)+BIT(0))
-#define CLK_FREQ_20MHZ BIT(2)
-#define CLK_FREQ_15MHZ (BIT(1)+BIT(0))
-#define CLK_FREQ_10MHZ BIT(1)
-
-/*
- * ------SCSI Register-------
- * Control Reg. 1(+20H)
- */
-#define EXTENDED_TIMING BIT(7)
-#define DIS_INT_ON_SCSI_RST BIT(6)
-#define PARITY_ERR_REPO BIT(4)
-#define SCSI_ID_ON_BUS (BIT(2)+BIT(1)+BIT(0))
-
-/*
- * ------SCSI Register-------
- * Control Reg. 2(+2CH)
- */
-#define EN_FEATURE BIT(6)
-#define EN_SCSI2_CMD BIT(3)
-
-/*
- * ------SCSI Register-------
- * Control Reg. 3(+30H)
- */
-#define ID_MSG_CHECK BIT(7)
-#define EN_QTAG_MSG BIT(6)
-#define EN_GRP2_CMD BIT(5)
-#define FAST_SCSI BIT(4) /* ;10MB/SEC */
-#define FAST_CLK BIT(3) /* ;25 - 40 MHZ */
-
-/*
- * ------SCSI Register-------
- * Control Reg. 4(+34H)
- */
-#define EATER_12NS 0
-#define EATER_25NS BIT(7)
-#define EATER_35NS BIT(6)
-#define EATER_0NS (BIT(7)+BIT(6))
-#define NEGATE_REQACKDATA BIT(2)
-#define NEGATE_REQACK BIT(3)
-
-/*
- *========================================
- * DMA Register
- *========================================
- */
-
-/*
- * -------DMA Register--------
- * DMA Command Reg.(+40H)
- */
-#define READ_DIRECTION BIT(7)
-#define WRITE_DIRECTION 0
-#define EN_DMA_INT BIT(6)
-#define MAP_TO_MDL BIT(5)
-#define DMA_DIAGNOSTIC BIT(4)
-#define DMA_IDLE_CMD 0
-#define DMA_BLAST_CMD BIT(0)
-#define DMA_ABORT_CMD BIT(1)
-#define DMA_START_CMD (BIT(1)|BIT(0))
-
-/*
- * -------DMA Register--------
- * DMA Status Reg.(+54H)
- */
-#define PCI_MS_ABORT BIT(6)
-#define BLAST_COMPLETE BIT(5)
-#define SCSI_INTERRUPT BIT(4)
-#define DMA_XFER_DONE BIT(3)
-#define DMA_XFER_ABORT BIT(2)
-#define DMA_XFER_ERROR BIT(1)
-#define POWER_DOWN BIT(0)
-
-/*
- * -------DMA Register--------
- * DMA SCSI Bus and Ctrl.(+70H)
- * EN_INT_ON_PCI_ABORT
- */
-
-/*
- *==========================================================
- * SCSI Chip register address offset
- *==========================================================
- */
-#define CTCREG_LOW 0x00 /* (R) current transfer count register low */
-#define STCREG_LOW 0x00 /* (W) start transfer count register low */
-
-#define CTCREG_MID 0x04 /* (R) current transfer count register
- * middle */
-#define STCREG_MID 0x04 /* (W) start transfer count register middle */
-
-#define SCSIFIFOREG 0x08 /* (R/W) SCSI FIFO register */
-
-#define SCSICMDREG 0x0C /* (R/W) SCSI command register */
-
-#define SCSISTATREG 0x10 /* (R) SCSI status register */
-#define SCSIDESTIDREG 0x10 /* (W) SCSI destination ID register */
-
-#define INTSTATREG 0x14 /* (R) interrupt status register */
-#define SCSITIMEOUTREG 0x14 /* (W) SCSI timeout register */
-
-
-#define INTERNSTATREG 0x18 /* (R) internal state register */
-#define SYNCPERIOREG 0x18 /* (W) synchronous transfer period register */
-
-#define CURRENTFIFOREG 0x1C /* (R) current FIFO/internal state register */
-#define SYNCOFFREG 0x1C/* (W) synchronous transfer period register */
-
-#define CNTLREG1 0x20 /* (R/W) control register 1 */
-#define CLKFACTREG 0x24 /* (W) clock factor register */
-#define CNTLREG2 0x2C /* (R/W) control register 2 */
-#define CNTLREG3 0x30 /* (R/W) control register 3 */
-#define CNTLREG4 0x34 /* (R/W) control register 4 */
-
-#define CURTXTCNTREG 0x38 /* (R) current transfer count register
- * high/part-unique ID code */
-#define STCREG_HIGH 0x38 /* (W) Start current transfer count register
- * high */
-
-/*
- *********************************************************
- *
- * SCSI DMA register
- *
- *********************************************************
- */
-#define DMA_Cmd 0x40 /* (R/W) command register */
-#define DMA_XferCnt 0x44 /* (R/W) starting transfer count */
-#define DMA_XferAddr 0x48 /* (R/W) starting Physical address */
-#define DMA_Wk_ByteCntr 0x4C /* ( R ) working byte counter */
-#define DMA_Wk_AddrCntr 0x50 /* ( R ) working address counter */
-#define DMA_Status 0x54 /* ( R ) status register */
-#define DMA_MDL_Addr 0x58 /* (R/W) starting memory descriptor list (MDL)
- * address */
-#define DMA_Wk_MDL_Cntr 0x5C /* ( R ) working MDL counter */
-#define DMA_ScsiBusCtrl 0x70 /* (bits R/W) SCSI BUS and control */
-
-/* ******************************************************* */
-#define am_target SCSISTATREG
-#define am_timeout INTSTATREG
-#define am_seq_step SYNCPERIOREG
-#define am_fifo_count SYNCOFFREG
-
-
-#define amd_read8(amd, port) \
- bus_space_read_1((amd)->tag, (amd)->bsh, port)
-
-#define amd_read16(amd, port) \
- bus_space_read_2((amd)->tag, (amd)->bsh, port)
-
-#define amd_read32(amd, port) \
- bus_space_read_4((amd)->tag, (amd)->bsh, port)
-
-#define amd_write8(amd, port, value) \
- bus_space_write_1((amd)->tag, (amd)->bsh, port, value)
-
-#define amd_write8_multi(amd, port, ptr, len) \
- bus_space_write_multi_1((amd)->tag, (amd)->bsh, port, ptr, len)
-
-#define amd_write16(amd, port, value) \
- bus_space_write_2((amd)->tag, (amd)->bsh, port, value)
-
-#define amd_write32(amd, port, value) \
- bus_space_write_4((amd)->tag, (amd)->bsh, port, value)
-
-#endif /* AMD_H */
OpenPOWER on IntegriCloud