From 075c6d38244abd0b0c8dc9b2974ef574b9180bf5 Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Sat, 7 Jan 2017 23:02:31 -0800 Subject: [PATCH] kernel - CAM cleanup 1/N - Remove ancient scsi pccard drivers ncv, nsp, stg * Remove a number of ancient drivers that nobody could possibly be using any more. * Remove ncv: NCR 53C500 based SCSI host adapters. * Remove nsp: Workbit Ninja SCSI-3 based PC Card SCSI host adapters. * Remove stg: TMC 18C30, 18C50 based PC Card SCSI host adapters. --- sys/bus/cam/Makefile | 2 +- sys/bus/cam/scsi/Makefile | 7 - sys/bus/cam/scsi/scsi_low.c | 4109 ----------------------------------- sys/bus/cam/scsi/scsi_low.h | 808 ------- sys/bus/cam/scsi/scsi_low_pisa.c | 75 - sys/bus/cam/scsi/scsi_low_pisa.h | 40 - sys/conf/files | 12 - sys/config/LINT64 | 6 - sys/config/X86_64_GENERIC | 4 - sys/dev/disk/Makefile | 4 +- sys/dev/disk/ncv/Makefile | 8 - sys/dev/disk/ncv/dvcfg.h | 68 - sys/dev/disk/ncv/ncr53c500.c | 1236 ----------- sys/dev/disk/ncv/ncr53c500_pccard.c | 366 ---- sys/dev/disk/ncv/ncr53c500hw.h | 72 - sys/dev/disk/ncv/ncr53c500hwtab.h | 50 - sys/dev/disk/ncv/ncr53c500reg.h | 188 -- sys/dev/disk/ncv/ncr53c500var.h | 101 - sys/dev/disk/nsp/Makefile | 8 - sys/dev/disk/nsp/nsp.c | 1826 ---------------- sys/dev/disk/nsp/nsp_pccard.c | 338 --- sys/dev/disk/nsp/nspreg.h | 222 -- sys/dev/disk/nsp/nspvar.h | 111 - sys/dev/disk/stg/Makefile | 8 - sys/dev/disk/stg/tmc18c30.c | 1340 ------------ sys/dev/disk/stg/tmc18c30_pccard.c | 324 --- sys/dev/disk/stg/tmc18c30reg.h | 148 -- sys/dev/disk/stg/tmc18c30var.h | 109 - 28 files changed, 3 insertions(+), 11587 deletions(-) delete mode 100644 sys/bus/cam/scsi/Makefile delete mode 100644 sys/bus/cam/scsi/scsi_low.c delete mode 100644 sys/bus/cam/scsi/scsi_low.h delete mode 100644 sys/bus/cam/scsi/scsi_low_pisa.c delete mode 100644 sys/bus/cam/scsi/scsi_low_pisa.h delete mode 100644 sys/dev/disk/ncv/Makefile delete mode 100644 sys/dev/disk/ncv/dvcfg.h delete mode 100644 sys/dev/disk/ncv/ncr53c500.c delete mode 100644 sys/dev/disk/ncv/ncr53c500_pccard.c delete mode 100644 sys/dev/disk/ncv/ncr53c500hw.h delete mode 100644 sys/dev/disk/ncv/ncr53c500hwtab.h delete mode 100644 sys/dev/disk/ncv/ncr53c500reg.h delete mode 100644 sys/dev/disk/ncv/ncr53c500var.h delete mode 100644 sys/dev/disk/nsp/Makefile delete mode 100644 sys/dev/disk/nsp/nsp.c delete mode 100644 sys/dev/disk/nsp/nsp_pccard.c delete mode 100644 sys/dev/disk/nsp/nspreg.h delete mode 100644 sys/dev/disk/nsp/nspvar.h delete mode 100644 sys/dev/disk/stg/Makefile delete mode 100644 sys/dev/disk/stg/tmc18c30.c delete mode 100644 sys/dev/disk/stg/tmc18c30_pccard.c delete mode 100644 sys/dev/disk/stg/tmc18c30reg.h delete mode 100644 sys/dev/disk/stg/tmc18c30var.h diff --git a/sys/bus/cam/Makefile b/sys/bus/cam/Makefile index a47602b9f1..e789f0c335 100644 --- a/sys/bus/cam/Makefile +++ b/sys/bus/cam/Makefile @@ -1,6 +1,6 @@ # $DragonFly: src/sys/bus/cam/Makefile,v 1.2 2007/11/12 07:27:50 pavalos Exp $ # -SUBDIR= cam scsi +SUBDIR= cam .include diff --git a/sys/bus/cam/scsi/Makefile b/sys/bus/cam/scsi/Makefile deleted file mode 100644 index ec103723a2..0000000000 --- a/sys/bus/cam/scsi/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -# $FreeBSD: src/sys/modules/scsi_low/Makefile,v 1.1.2.1 2001/12/17 13:32:31 non Exp $ - -KMOD= scsi_low -SRCS= scsi_low.c scsi_low_pisa.c -SRCS+= opt_scsi.h opt_cam.h bus_if.h device_if.h - -.include diff --git a/sys/bus/cam/scsi/scsi_low.c b/sys/bus/cam/scsi/scsi_low.c deleted file mode 100644 index a4a0218e2c..0000000000 --- a/sys/bus/cam/scsi/scsi_low.c +++ /dev/null @@ -1,4109 +0,0 @@ -/* - * $FreeBSD: src/sys/cam/scsi/scsi_low.c,v 1.1.2.5 2003/08/09 06:18:30 non Exp $ - * $NetBSD: scsi_low.c,v 1.24.10.8 2001/06/26 07:39:44 honda Exp $ - */ - -#define SCSI_LOW_STATICS -#define SCSI_LOW_DEBUG -#define SCSI_LOW_NEGOTIATE_BEFORE_SENSE -#define SCSI_LOW_START_UP_CHECK - -/* #define SCSI_LOW_INFO_DETAIL */ -/* #define SCSI_LOW_QCLEAR_AFTER_CA */ -/* #define SCSI_LOW_FLAGS_QUIRKS_OK */ - -#define SCSI_LOW_FLAGS_QUIRKS_OK - -/* - * [NetBSD for NEC PC-98 series] - * Copyright (c) 1995, 1996, 1997, 1998, 1999, 2000, 2001 - * NetBSD/pc98 porting staff. All rights reserved. - * Copyright (c) 1995, 1996, 1997, 1998, 1999, 2000, 2001 - * Naofumi HONDA. All rights reserved. - * - * [Ported for FreeBSD CAM] - * Copyright (c) 2000, 2001 - * MITSUNAGA Noriaki, NOKUBI Hirotaka and TAKAHASHI Yoshihiro. - * All rights reserved. - * - * 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. - */ - -/* - * When our host is reselected, - * nexus establish processes are little complicated. - * Normal steps are followings: - * 1) Our host selected by target => target nexus (slp->sl_Tnexus) - * 2) Identify msgin => lun nexus (slp->sl_Lnexus) - * 3) Qtag msg => ccb nexus (slp->sl_Qnexus) - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include - -/************************************************************** - * Constants - **************************************************************/ -#define SCSI_LOW_POLL_HZ 1000 - -/* functions return values */ -#define SCSI_LOW_START_NO_QTAG 0 -#define SCSI_LOW_START_QTAG 1 - -#define SCSI_LOW_DONE_COMPLETE 0 -#define SCSI_LOW_DONE_RETRY 1 - -/* internal disk flags */ -#define SCSI_LOW_DISK_DISC 0x00000001 -#define SCSI_LOW_DISK_QTAG 0x00000002 -#define SCSI_LOW_DISK_LINK 0x00000004 -#define SCSI_LOW_DISK_PARITY 0x00000008 -#define SCSI_LOW_DISK_SYNC 0x00010000 -#define SCSI_LOW_DISK_WIDE_16 0x00020000 -#define SCSI_LOW_DISK_WIDE_32 0x00040000 -#define SCSI_LOW_DISK_WIDE (SCSI_LOW_DISK_WIDE_16 | SCSI_LOW_DISK_WIDE_32) -#define SCSI_LOW_DISK_LFLAGS 0x0000ffff -#define SCSI_LOW_DISK_TFLAGS 0xffff0000 - -MALLOC_DEFINE(M_SCSILOW, "SCSI low", "SCSI low buffers"); - -/************************************************************** - * Declarations - **************************************************************/ -/* static */ void scsi_low_info (struct scsi_low_softc *, struct targ_info *, u_char *); -static void scsi_low_engage (void *); -static struct slccb *scsi_low_establish_ccb (struct targ_info *, struct lun_info *, scsi_low_tag_t); -static int scsi_low_done (struct scsi_low_softc *, struct slccb *); -static int scsi_low_setup_done (struct scsi_low_softc *, struct slccb *); -static void scsi_low_bus_release (struct scsi_low_softc *, struct targ_info *); -static void scsi_low_twiddle_wait (void); -static struct lun_info *scsi_low_alloc_li (struct targ_info *, int, int); -static struct targ_info *scsi_low_alloc_ti (struct scsi_low_softc *, int); -static void scsi_low_calcf_lun (struct lun_info *); -static void scsi_low_calcf_target (struct targ_info *); -static void scsi_low_calcf_show (struct lun_info *); -static void scsi_low_reset_nexus (struct scsi_low_softc *, int); -static void scsi_low_reset_nexus_target (struct scsi_low_softc *, struct targ_info *, int); -static void scsi_low_reset_nexus_lun (struct scsi_low_softc *, struct lun_info *, int); -static int scsi_low_init (struct scsi_low_softc *, u_int); -static void scsi_low_start (struct scsi_low_softc *); -static void scsi_low_free_ti (struct scsi_low_softc *); - -static int scsi_low_alloc_qtag (struct slccb *); -static int scsi_low_dealloc_qtag (struct slccb *); -static int scsi_low_enqueue (struct scsi_low_softc *, struct targ_info *, struct lun_info *, struct slccb *, u_int, u_int); -static int scsi_low_message_enqueue (struct scsi_low_softc *, struct targ_info *, struct lun_info *, u_int); -static void scsi_low_unit_ready_cmd (struct slccb *); -static void scsi_low_timeout (void *); -static int scsi_low_timeout_check (struct scsi_low_softc *); -#ifdef SCSI_LOW_START_UP_CHECK -static int scsi_low_start_up (struct scsi_low_softc *); -#endif /* SCSI_LOW_START_UP_CHECK */ -static int scsi_low_abort_ccb (struct scsi_low_softc *, struct slccb *); -static struct slccb *scsi_low_revoke_ccb (struct scsi_low_softc *, struct slccb *, int); - -int scsi_low_version_major = 2; -int scsi_low_version_minor = 17; - -static struct scsi_low_softc_tab sl_tab = LIST_HEAD_INITIALIZER(sl_tab); - -/************************************************************** - * Debug, Run test and Statics - **************************************************************/ -#ifdef SCSI_LOW_INFO_DETAIL -#define SCSI_LOW_INFO(slp, ti, s) scsi_low_info((slp), (ti), (s)) -#else /* !SCSI_LOW_INFO_DETAIL */ -#define SCSI_LOW_INFO(slp, ti, s) kprintf("%s: %s\n", (slp)->sl_xname, (s)) -#endif /* !SCSI_LOW_INFO_DETAIL */ - -#ifdef SCSI_LOW_STATICS -static struct scsi_low_statics { - int nexus_win; - int nexus_fail; - int nexus_disconnected; - int nexus_reselected; - int nexus_conflict; -} scsi_low_statics; -#endif /* SCSI_LOW_STATICS */ - -#ifdef SCSI_LOW_DEBUG -#define SCSI_LOW_DEBUG_DONE 0x00001 -#define SCSI_LOW_DEBUG_DISC 0x00002 -#define SCSI_LOW_DEBUG_SENSE 0x00004 -#define SCSI_LOW_DEBUG_CALCF 0x00008 -#define SCSI_LOW_DEBUG_ACTION 0x10000 -int scsi_low_debug = 0; - -#define SCSI_LOW_MAX_ATTEN_CHECK 32 -#define SCSI_LOW_ATTEN_CHECK 0x0001 -#define SCSI_LOW_CMDLNK_CHECK 0x0002 -#define SCSI_LOW_ABORT_CHECK 0x0004 -#define SCSI_LOW_NEXUS_CHECK 0x0008 -int scsi_low_test = 0; -int scsi_low_test_id = 0; - -static void scsi_low_test_abort (struct scsi_low_softc *, struct targ_info *, struct lun_info *); -static void scsi_low_test_cmdlnk (struct scsi_low_softc *, struct slccb *); -static void scsi_low_test_atten (struct scsi_low_softc *, struct targ_info *, u_int); -#define SCSI_LOW_DEBUG_TEST_GO(fl, id) \ - ((scsi_low_test & (fl)) != 0 && (scsi_low_test_id & (1 << (id))) == 0) -#define SCSI_LOW_DEBUG_GO(fl, id) \ - ((scsi_low_debug & (fl)) != 0 && (scsi_low_test_id & (1 << (id))) == 0) -#endif /* SCSI_LOW_DEBUG */ - -/************************************************************** - * CCB - **************************************************************/ -GENERIC_CCB_STATIC_ALLOC(scsi_low, slccb) -GENERIC_CCB(scsi_low, slccb, ccb_chain) - -/************************************************************** - * Inline functions - **************************************************************/ -#define SCSI_LOW_INLINE static __inline -SCSI_LOW_INLINE void scsi_low_activate_qtag (struct slccb *); -SCSI_LOW_INLINE void scsi_low_deactivate_qtag (struct slccb *); -SCSI_LOW_INLINE void scsi_low_ccb_message_assert (struct slccb *, u_int); -SCSI_LOW_INLINE void scsi_low_ccb_message_exec (struct scsi_low_softc *, struct slccb *); -SCSI_LOW_INLINE void scsi_low_ccb_message_retry (struct slccb *); -SCSI_LOW_INLINE void scsi_low_ccb_message_clear (struct slccb *); -SCSI_LOW_INLINE void scsi_low_init_msgsys (struct scsi_low_softc *, struct targ_info *); - -SCSI_LOW_INLINE void -scsi_low_activate_qtag(struct slccb *cb) -{ - struct lun_info *li = cb->li; - - if (cb->ccb_tag != SCSI_LOW_UNKTAG) - return; - - li->li_nqio ++; - cb->ccb_tag = cb->ccb_otag; -} - -SCSI_LOW_INLINE void -scsi_low_deactivate_qtag(struct slccb *cb) -{ - struct lun_info *li = cb->li; - - if (cb->ccb_tag == SCSI_LOW_UNKTAG) - return; - - li->li_nqio --; - cb->ccb_tag = SCSI_LOW_UNKTAG; -} - -SCSI_LOW_INLINE void -scsi_low_ccb_message_exec(struct scsi_low_softc *slp, struct slccb *cb) -{ - scsi_low_assert_msg(slp, cb->ti, cb->ccb_msgoutflag, 0); - cb->ccb_msgoutflag = 0; -} - -SCSI_LOW_INLINE void -scsi_low_ccb_message_assert(struct slccb *cb, u_int msg) -{ - cb->ccb_msgoutflag = cb->ccb_omsgoutflag = msg; -} - -SCSI_LOW_INLINE void -scsi_low_ccb_message_retry(struct slccb *cb) -{ - cb->ccb_msgoutflag = cb->ccb_omsgoutflag; -} - -SCSI_LOW_INLINE void -scsi_low_ccb_message_clear(struct slccb *cb) -{ - cb->ccb_msgoutflag = 0; -} - -SCSI_LOW_INLINE void -scsi_low_init_msgsys(struct scsi_low_softc *slp, struct targ_info *ti) -{ - ti->ti_msginptr = 0; - ti->ti_emsgflags = ti->ti_msgflags = ti->ti_omsgflags = 0; - SCSI_LOW_DEASSERT_ATN(slp); - SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_NULL); -} - -/*============================================================= - * START OF OS switch (All OS depend fucntions should be here) - =============================================================*/ -/* common os depend utitlities */ -#define SCSI_LOW_CMD_RESIDUAL_CHK 0x0001 -#define SCSI_LOW_CMD_ORDERED_QTAG 0x0002 -#define SCSI_LOW_CMD_ABORT_WARNING 0x0004 - -static u_int8_t scsi_low_cmd_flags[256] = { -/* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ -/*0*/ 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 5, 0, 0, 0, 0, 0, -/*1*/ 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, -/*2*/ 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 5, 0, 0, 0, 5, 5, -/*3*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, -}; - -struct scsi_low_error_code { - int error_bits; - int error_code; -}; - -static struct slccb *scsi_low_find_ccb (struct scsi_low_softc *, u_int, u_int, void *); -static int scsi_low_translate_error_code (struct slccb *, struct scsi_low_error_code *); - -static struct slccb * -scsi_low_find_ccb(struct scsi_low_softc *slp, u_int target, u_int lun, void *osdep) -{ - struct targ_info *ti; - struct lun_info *li; - struct slccb *cb; - - ti = slp->sl_ti[target]; - li = scsi_low_alloc_li(ti, lun, 0); - if (li == NULL) - return NULL; - - if ((cb = slp->sl_Qnexus) != NULL && cb->osdep == osdep) - return cb; - - TAILQ_FOREACH(cb, &slp->sl_start, ccb_chain) - { - if (cb->osdep == osdep) - return cb; - } - - TAILQ_FOREACH(cb, &li->li_discq, ccb_chain) - { - if (cb->osdep == osdep) - return cb; - } - return NULL; -} - -static int -scsi_low_translate_error_code(struct slccb *cb, struct scsi_low_error_code *tp) -{ - if (cb->ccb_error == 0) - return tp->error_code; - - for (tp ++; (cb->ccb_error & tp->error_bits) == 0; tp ++) - ; - return tp->error_code; -} - -/************************************************************** - * SCSI INTERFACE (CAM) - **************************************************************/ -#define SCSI_LOW_MALLOC(size) kmalloc((size), M_SCSILOW, M_INTWAIT) -#define SCSI_LOW_FREE(pt) kfree((pt), M_SCSILOW) -#define SCSI_LOW_ALLOC_CCB(flags) scsi_low_get_ccb() - -static void scsi_low_poll_cam (struct cam_sim *); -static void scsi_low_cam_rescan_callback (struct cam_periph *, union ccb *); -static void scsi_low_rescan_bus_cam (struct scsi_low_softc *); -void scsi_low_scsi_action_cam (struct cam_sim *, union ccb *); - -static int scsi_low_attach_cam (struct scsi_low_softc *); -static int scsi_low_world_start_cam (struct scsi_low_softc *); -static int scsi_low_dettach_cam (struct scsi_low_softc *); -static int scsi_low_ccb_setup_cam (struct scsi_low_softc *, struct slccb *); -static int scsi_low_done_cam (struct scsi_low_softc *, struct slccb *); -static void scsi_low_timeout_cam (struct scsi_low_softc *, int, int); - -struct scsi_low_osdep_funcs scsi_low_osdep_funcs_cam = { - scsi_low_attach_cam, - scsi_low_world_start_cam, - scsi_low_dettach_cam, - scsi_low_ccb_setup_cam, - scsi_low_done_cam, - scsi_low_timeout_cam -}; - -struct scsi_low_error_code scsi_low_error_code_cam[] = { - {0, CAM_REQ_CMP}, - {SENSEIO, CAM_AUTOSNS_VALID | CAM_REQ_CMP_ERR}, - {SENSEERR, CAM_AUTOSENSE_FAIL}, - {UACAERR, CAM_SCSI_STATUS_ERROR}, - {BUSYERR | STATERR, CAM_SCSI_STATUS_ERROR}, - {SELTIMEOUTIO, CAM_SEL_TIMEOUT}, - {TIMEOUTIO, CAM_CMD_TIMEOUT}, - {PDMAERR, CAM_DATA_RUN_ERR}, - {PARITYERR, CAM_UNCOR_PARITY}, - {UBFERR, CAM_UNEXP_BUSFREE}, - {ABORTIO, CAM_REQ_ABORTED}, - {-1, CAM_UNREC_HBA_ERROR} -}; - -#define SIM2SLP(sim) ((struct scsi_low_softc *) cam_sim_softc((sim))) - -/* XXX: - * Please check a polling hz, currently we assume scsi_low_poll() is - * called each 1 ms. - */ -#define SCSI_LOW_CAM_POLL_HZ 1000 /* OK ? */ - -static void -scsi_low_poll_cam(struct cam_sim *sim) -{ - struct scsi_low_softc *slp = SIM2SLP(sim); - - (*slp->sl_funcs->scsi_low_poll) (slp); - - if (slp->sl_si.si_poll_count ++ >= - SCSI_LOW_CAM_POLL_HZ / SCSI_LOW_TIMEOUT_HZ) - { - slp->sl_si.si_poll_count = 0; - scsi_low_timeout_check(slp); - } -} - -static void -scsi_low_cam_rescan_callback(struct cam_periph *periph, union ccb *ccb) -{ - xpt_free_path(ccb->ccb_h.path); - xpt_free_ccb(ccb); -} - -static void -scsi_low_rescan_bus_cam(struct scsi_low_softc *slp) -{ - struct cam_path *path; - union ccb *ccb = xpt_alloc_ccb(); - cam_status status; - - status = xpt_create_path(&path, xpt_periph, - cam_sim_path(slp->sl_si.sim), -1, 0); - if (status != CAM_REQ_CMP) - return; - - xpt_setup_ccb(&ccb->ccb_h, path, 5); - ccb->ccb_h.func_code = XPT_SCAN_BUS; - ccb->ccb_h.cbfcnp = scsi_low_cam_rescan_callback; - ccb->crcn.flags = CAM_FLAG_NONE; - xpt_action(ccb); -} - -void -scsi_low_scsi_action_cam(struct cam_sim *sim, union ccb *ccb) -{ - struct scsi_low_softc *slp = SIM2SLP(sim); - struct targ_info *ti; - struct lun_info *li; - struct slccb *cb; - u_int lun, flags, msg, target; - int rv; - - target = (u_int) (ccb->ccb_h.target_id); - lun = (u_int) ccb->ccb_h.target_lun; - -#ifdef SCSI_LOW_DEBUG - if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_ACTION, target) != 0) - { - kprintf("%s: cam_action: func code 0x%x target: %d, lun: %d\n", - slp->sl_xname, ccb->ccb_h.func_code, target, lun); - } -#endif /* SCSI_LOW_DEBUG */ - - switch (ccb->ccb_h.func_code) { - case XPT_SCSI_IO: /* Execute the requested I/O operation */ -#ifdef SCSI_LOW_DIAGNOSTIC - if (target == CAM_TARGET_WILDCARD || lun == CAM_LUN_WILDCARD) - { - kprintf("%s: invalid target/lun\n", slp->sl_xname); - ccb->ccb_h.status = CAM_REQ_INVALID; - xpt_done(ccb); - return; - } -#endif /* SCSI_LOW_DIAGNOSTIC */ - - if (((cb = SCSI_LOW_ALLOC_CCB(1)) == NULL)) { - ccb->ccb_h.status = CAM_RESRC_UNAVAIL; - xpt_done(ccb); - return; - } - - ti = slp->sl_ti[target]; - cb->osdep = ccb; - cb->bp = NULL; - if ((ccb->ccb_h.flags & CAM_DIS_AUTOSENSE) == 0) - flags = CCB_AUTOSENSE | CCB_SCSIIO; - else - flags = CCB_SCSIIO; - - crit_enter(); - li = scsi_low_alloc_li(ti, lun, 1); - - if (ti->ti_setup_msg != 0) - { - scsi_low_message_enqueue(slp, ti, li, CCB_AUTOSENSE); - } - - scsi_low_enqueue(slp, ti, li, cb, flags, 0); - -#ifdef SCSI_LOW_DEBUG - if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_ABORT_CHECK, target) != 0) - { - scsi_low_test_abort(slp, ti, li); - } -#endif /* SCSI_LOW_DEBUG */ - crit_exit(); - break; - - case XPT_EN_LUN: /* Enable LUN as a target */ - case XPT_TARGET_IO: /* Execute target I/O request */ - case XPT_ACCEPT_TARGET_IO: /* Accept Host Target Mode CDB */ - case XPT_CONT_TARGET_IO: /* Continue Host Target I/O Connection*/ - /* XXX Implement */ - ccb->ccb_h.status = CAM_REQ_INVALID; - xpt_done(ccb); - break; - - case XPT_ABORT: /* Abort the specified CCB */ -#ifdef SCSI_LOW_DIAGNOSTIC - if (target == CAM_TARGET_WILDCARD || lun == CAM_LUN_WILDCARD) - { - kprintf("%s: invalid target/lun\n", slp->sl_xname); - ccb->ccb_h.status = CAM_REQ_INVALID; - xpt_done(ccb); - return; - } -#endif /* SCSI_LOW_DIAGNOSTIC */ - - crit_enter(); - cb = scsi_low_find_ccb(slp, target, lun, ccb->cab.abort_ccb); - rv = scsi_low_abort_ccb(slp, cb); - crit_exit(); - - if (rv == 0) - ccb->ccb_h.status = CAM_REQ_CMP; - else - ccb->ccb_h.status = CAM_REQ_INVALID; - xpt_done(ccb); - break; - - case XPT_SET_TRAN_SETTINGS: { - struct ccb_trans_settings_scsi *scsi; - struct ccb_trans_settings_spi *spi; - struct ccb_trans_settings *cts; - u_int val; - -#ifdef SCSI_LOW_DIAGNOSTIC - if (target == CAM_TARGET_WILDCARD) - { - kprintf("%s: invalid target\n", slp->sl_xname); - ccb->ccb_h.status = CAM_REQ_INVALID; - xpt_done(ccb); - return; - } -#endif /* SCSI_LOW_DIAGNOSTIC */ - cts = &ccb->cts; - ti = slp->sl_ti[target]; - if (lun == CAM_LUN_WILDCARD) - lun = 0; - - crit_enter(); - scsi = &cts->proto_specific.scsi; - spi = &cts->xport_specific.spi; - if ((spi->valid & (CTS_SPI_VALID_BUS_WIDTH | - CTS_SPI_VALID_SYNC_RATE | - CTS_SPI_VALID_SYNC_OFFSET)) != 0) - { - if (spi->valid & CTS_SPI_VALID_BUS_WIDTH) { - val = spi->bus_width; - if (val < ti->ti_width) - ti->ti_width = val; - } - if (spi->valid & CTS_SPI_VALID_SYNC_RATE) { - val = spi->sync_period; - if (val == 0 || val > ti->ti_maxsynch.period) - ti->ti_maxsynch.period = val; - } - if (spi->valid & CTS_SPI_VALID_SYNC_OFFSET) { - val = spi->sync_offset; - if (val < ti->ti_maxsynch.offset) - ti->ti_maxsynch.offset = val; - } - ti->ti_flags_valid |= SCSI_LOW_TARG_FLAGS_QUIRKS_VALID; - scsi_low_calcf_target(ti); - } - - if ((spi->valid & CTS_SPI_FLAGS_DISC_ENB) != 0 || - (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) != 0) { - - li = scsi_low_alloc_li(ti, lun, 1); - if (spi->valid & CTS_SPI_FLAGS_DISC_ENB) { - li->li_quirks |= SCSI_LOW_DISK_DISC; - } else { - li->li_quirks &= ~SCSI_LOW_DISK_DISC; - } - - if (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) { - li->li_quirks |= SCSI_LOW_DISK_QTAG; - } else { - li->li_quirks &= ~SCSI_LOW_DISK_QTAG; - } - li->li_flags_valid |= SCSI_LOW_LUN_FLAGS_QUIRKS_VALID; - scsi_low_calcf_target(ti); - scsi_low_calcf_lun(li); - if ((slp->sl_show_result & SHOW_CALCF_RES) != 0) - scsi_low_calcf_show(li); - } - crit_exit(); - - ccb->ccb_h.status = CAM_REQ_CMP; - xpt_done(ccb); - break; - } - - case XPT_GET_TRAN_SETTINGS: { - struct ccb_trans_settings *cts; - u_int diskflags; - - cts = &ccb->cts; -#ifdef SCSI_LOW_DIAGNOSTIC - if (target == CAM_TARGET_WILDCARD) - { - kprintf("%s: invalid target\n", slp->sl_xname); - ccb->ccb_h.status = CAM_REQ_INVALID; - xpt_done(ccb); - return; - } -#endif /* SCSI_LOW_DIAGNOSTIC */ - ti = slp->sl_ti[target]; - if (lun == CAM_LUN_WILDCARD) - lun = 0; - - crit_enter(); - li = scsi_low_alloc_li(ti, lun, 1); - if (li != NULL && cts->type == CTS_TYPE_CURRENT_SETTINGS) { - struct ccb_trans_settings_scsi *scsi = - &cts->proto_specific.scsi; - struct ccb_trans_settings_spi *spi = - &cts->xport_specific.spi; -#ifdef SCSI_LOW_DIAGNOSTIC - if (li->li_flags_valid != SCSI_LOW_LUN_FLAGS_ALL_VALID) - { - ccb->ccb_h.status = CAM_FUNC_NOTAVAIL; - kprintf("%s: invalid GET_TRANS_CURRENT_SETTINGS call\n", - slp->sl_xname); - goto settings_out; - } -#endif /* SCSI_LOW_DIAGNOSTIC */ - cts->protocol = PROTO_SCSI; - cts->protocol_version = SCSI_REV_2; - cts->transport = XPORT_SPI; - cts->transport_version = 2; - - scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB; - spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB; - - diskflags = li->li_diskflags & li->li_cfgflags; - if (diskflags & SCSI_LOW_DISK_DISC) - spi->flags |= CTS_SPI_FLAGS_DISC_ENB; - if (diskflags & SCSI_LOW_DISK_QTAG) - scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB; - - spi->sync_period = ti->ti_maxsynch.period; - spi->valid |= CTS_SPI_VALID_SYNC_RATE; - spi->sync_offset = ti->ti_maxsynch.offset; - spi->valid |= CTS_SPI_VALID_SYNC_OFFSET; - - spi->valid |= CTS_SPI_VALID_BUS_WIDTH; - spi->bus_width = ti->ti_width; - - if (cts->ccb_h.target_lun != CAM_LUN_WILDCARD) { - scsi->valid = CTS_SCSI_VALID_TQ; - spi->valid |= CTS_SPI_VALID_DISC; - } else - scsi->valid = 0; - } else - ccb->ccb_h.status = CAM_FUNC_NOTAVAIL; -settings_out: - crit_exit(); - xpt_done(ccb); - break; - } - - case XPT_CALC_GEOMETRY: { /* not yet HN2 */ - cam_calc_geometry(&ccb->ccg, /*extended*/1); - xpt_done(ccb); - break; - } - - case XPT_RESET_BUS: /* Reset the specified SCSI bus */ - crit_enter(); - scsi_low_restart(slp, SCSI_LOW_RESTART_HARD, NULL); - crit_exit(); - ccb->ccb_h.status = CAM_REQ_CMP; - xpt_done(ccb); - break; - - case XPT_TERM_IO: /* Terminate the I/O process */ - ccb->ccb_h.status = CAM_REQ_INVALID; - xpt_done(ccb); - break; - - case XPT_RESET_DEV: /* Bus Device Reset the specified SCSI device */ -#ifdef SCSI_LOW_DIAGNOSTIC - if (target == CAM_TARGET_WILDCARD) - { - kprintf("%s: invalid target\n", slp->sl_xname); - ccb->ccb_h.status = CAM_REQ_INVALID; - xpt_done(ccb); - return; - } -#endif /* SCSI_LOW_DIAGNOSTIC */ - - msg = SCSI_LOW_MSG_RESET; - if (((cb = SCSI_LOW_ALLOC_CCB(1)) == NULL)) - { - ccb->ccb_h.status = CAM_RESRC_UNAVAIL; - xpt_done(ccb); - return; - } - - ti = slp->sl_ti[target]; - if (lun == CAM_LUN_WILDCARD) - lun = 0; - cb->osdep = ccb; - cb->bp = NULL; - if ((ccb->ccb_h.flags & CAM_DIS_AUTOSENSE) == 0) - flags = CCB_AUTOSENSE | CCB_NORETRY | CCB_URGENT; - else - flags = CCB_NORETRY | CCB_URGENT; - - crit_enter(); - li = scsi_low_alloc_li(ti, lun, 1); - scsi_low_enqueue(slp, ti, li, cb, flags, msg); - crit_exit(); - break; - - case XPT_PATH_INQ: { /* Path routing inquiry */ - struct ccb_pathinq *cpi = &ccb->cpi; - - cpi->version_num = scsi_low_version_major; - cpi->hba_inquiry = PI_TAG_ABLE | PI_LINKED_CDB; - ti = slp->sl_ti[slp->sl_hostid]; /* host id */ - if (ti->ti_width > SCSI_LOW_BUS_WIDTH_8) - cpi->hba_inquiry |= PI_WIDE_16; - if (ti->ti_width > SCSI_LOW_BUS_WIDTH_16) - cpi->hba_inquiry |= PI_WIDE_32; - if (ti->ti_maxsynch.offset > 0) - cpi->hba_inquiry |= PI_SDTR_ABLE; - cpi->target_sprt = 0; - cpi->hba_misc = 0; - cpi->hba_eng_cnt = 0; - cpi->max_target = slp->sl_ntargs - 1; - cpi->max_lun = slp->sl_nluns - 1; - cpi->initiator_id = slp->sl_hostid; - cpi->bus_id = cam_sim_bus(sim); - cpi->base_transfer_speed = 3300; - cpi->transport = XPORT_SPI; - cpi->transport_version = 2; - cpi->protocol = PROTO_SCSI; - cpi->protocol_version = SCSI_REV_2; - strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN); - strncpy(cpi->hba_vid, "SCSI_LOW", HBA_IDLEN); - strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN); - cpi->unit_number = cam_sim_unit(sim); - cpi->ccb_h.status = CAM_REQ_CMP; - xpt_done(ccb); - break; - } - - default: - kprintf("scsi_low: non support func_code = %d ", - ccb->ccb_h.func_code); - ccb->ccb_h.status = CAM_REQ_INVALID; - xpt_done(ccb); - break; - } -} - -static int -scsi_low_attach_cam(struct scsi_low_softc *slp) -{ - struct cam_devq *devq; - int tagged_openings; - - ksprintf(slp->sl_xname, "%s%d", - DEVPORT_DEVNAME(slp->sl_dev), DEVPORT_DEVUNIT(slp->sl_dev)); - - devq = cam_simq_alloc(SCSI_LOW_NCCB); - if (devq == NULL) - return (ENOMEM); - - /* - * ask the adapter what subunits are present - */ - tagged_openings = min(slp->sl_openings, SCSI_LOW_MAXNEXUS); - slp->sl_si.sim = cam_sim_alloc(scsi_low_scsi_action_cam, - scsi_low_poll_cam, - DEVPORT_DEVNAME(slp->sl_dev), slp, - DEVPORT_DEVUNIT(slp->sl_dev), &sim_mplock, - slp->sl_openings, tagged_openings, devq); - cam_simq_release(devq); - if (slp->sl_si.sim == NULL) { - return ENODEV; - } - - if (xpt_bus_register(slp->sl_si.sim, 0) != CAM_SUCCESS) { - cam_sim_free(slp->sl_si.sim); - slp->sl_si.sim = NULL; - return ENODEV; - } - - if (xpt_create_path(&slp->sl_si.path, /*periph*/NULL, - cam_sim_path(slp->sl_si.sim), CAM_TARGET_WILDCARD, - CAM_LUN_WILDCARD) != CAM_REQ_CMP) { - xpt_bus_deregister(cam_sim_path(slp->sl_si.sim)); - cam_sim_free(slp->sl_si.sim); - slp->sl_si.sim = NULL; - return ENODEV; - } - - slp->sl_show_result = SHOW_CALCF_RES; /* OK ? */ - return 0; -} - -static int -scsi_low_world_start_cam(struct scsi_low_softc *slp) -{ -#if 0 - if (!cold) - scsi_low_rescan_bus_cam(slp); -#endif - scsi_low_rescan_bus_cam(slp); - return 0; -} - -static int -scsi_low_dettach_cam(struct scsi_low_softc *slp) -{ - xpt_async(AC_LOST_DEVICE, slp->sl_si.path, NULL); - xpt_free_path(slp->sl_si.path); - xpt_bus_deregister(cam_sim_path(slp->sl_si.sim)); - cam_sim_free(slp->sl_si.sim); - slp->sl_si.sim = NULL; - return 0; -} - -static int -scsi_low_ccb_setup_cam(struct scsi_low_softc *slp, struct slccb *cb) -{ - union ccb *ccb = (union ccb *) cb->osdep; - - if ((cb->ccb_flags & CCB_SCSIIO) != 0) - { - cb->ccb_scp.scp_cmd = ccb->csio.cdb_io.cdb_bytes; - cb->ccb_scp.scp_cmdlen = (int) ccb->csio.cdb_len; - cb->ccb_scp.scp_data = ccb->csio.data_ptr; - cb->ccb_scp.scp_datalen = (int) ccb->csio.dxfer_len; - if((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT) - cb->ccb_scp.scp_direction = SCSI_LOW_WRITE; - else /* if((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) */ - cb->ccb_scp.scp_direction = SCSI_LOW_READ; - cb->ccb_tcmax = ccb->ccb_h.timeout / 1000; - } - else - { - scsi_low_unit_ready_cmd(cb); - } - return SCSI_LOW_START_QTAG; -} - -static int -scsi_low_done_cam(struct scsi_low_softc *slp, struct slccb *cb) -{ - union ccb *ccb; - - ccb = (union ccb *) cb->osdep; - if (cb->ccb_error == 0) - { - ccb->ccb_h.status = CAM_REQ_CMP; - ccb->csio.resid = 0; - } - else - { - if (cb->ccb_rcnt >= slp->sl_max_retry) - cb->ccb_error |= ABORTIO; - - if ((cb->ccb_flags & CCB_NORETRY) == 0 && - (cb->ccb_error & ABORTIO) == 0) - return EJUSTRETURN; - - if ((cb->ccb_error & SENSEIO) != 0) - { - memcpy(&ccb->csio.sense_data, - &cb->ccb_sense, - sizeof(ccb->csio.sense_data)); - } - - ccb->ccb_h.status = scsi_low_translate_error_code(cb, - &scsi_low_error_code_cam[0]); - -#ifdef SCSI_LOW_DIAGNOSTIC - if ((cb->ccb_flags & CCB_SILENT) == 0 && - cb->ccb_scp.scp_cmdlen > 0 && - (scsi_low_cmd_flags[cb->ccb_scp.scp_cmd[0]] & - SCSI_LOW_CMD_ABORT_WARNING) != 0) - { - kprintf("%s: WARNING: scsi_low IO abort\n", - slp->sl_xname); - scsi_low_print(slp, NULL); - } -#endif /* SCSI_LOW_DIAGNOSTIC */ - } - - if ((ccb->ccb_h.status & CAM_STATUS_MASK) == 0) - ccb->ccb_h.status |= CAM_REQ_CMP_ERR; - - if (cb->ccb_scp.scp_status == ST_UNKNOWN) - ccb->csio.scsi_status = 0; /* XXX */ - else - ccb->csio.scsi_status = cb->ccb_scp.scp_status; - - if ((cb->ccb_flags & CCB_NOSDONE) == 0) - xpt_done(ccb); - return 0; -} - -static void -scsi_low_timeout_cam(struct scsi_low_softc *slp, int ch, int action) -{ - switch (ch) - { - case SCSI_LOW_TIMEOUT_CH_IO: - switch (action) - { - case SCSI_LOW_TIMEOUT_START: - callout_reset(&slp->sl_si.timeout_ch, - hz / SCSI_LOW_TIMEOUT_HZ, scsi_low_timeout, slp); - break; - case SCSI_LOW_TIMEOUT_STOP: - callout_stop(&slp->sl_si.timeout_ch); - break; - } - break; - - case SCSI_LOW_TIMEOUT_CH_ENGAGE: - switch (action) - { - case SCSI_LOW_TIMEOUT_START: - callout_reset(&slp->sl_si.engage_ch, 1, - scsi_low_engage, slp); - break; - case SCSI_LOW_TIMEOUT_STOP: - callout_stop(&slp->sl_si.engage_ch); - break; - } - break; - case SCSI_LOW_TIMEOUT_CH_RECOVER: - break; - } -} - -/************************************************************** - * scsi low deactivate and activate - **************************************************************/ -int -scsi_low_is_busy(struct scsi_low_softc *slp) -{ - if (slp->sl_nio > 0) - return EBUSY; - return 0; -} - -int -scsi_low_deactivate(struct scsi_low_softc *slp) -{ - crit_enter(); - slp->sl_flags |= HW_INACTIVE; - (*slp->sl_osdep_fp->scsi_low_osdep_timeout) - (slp, SCSI_LOW_TIMEOUT_CH_IO, SCSI_LOW_TIMEOUT_STOP); - (*slp->sl_osdep_fp->scsi_low_osdep_timeout) - (slp, SCSI_LOW_TIMEOUT_CH_ENGAGE, SCSI_LOW_TIMEOUT_STOP); - crit_exit(); - return 0; -} - -int -scsi_low_activate(struct scsi_low_softc *slp) -{ - int error; - - crit_enter(); - slp->sl_flags &= ~HW_INACTIVE; - if ((error = scsi_low_restart(slp, SCSI_LOW_RESTART_HARD, NULL)) != 0) - { - slp->sl_flags |= HW_INACTIVE; - crit_exit(); - return error; - } - - slp->sl_timeout_count = 0; - (*slp->sl_osdep_fp->scsi_low_osdep_timeout) - (slp, SCSI_LOW_TIMEOUT_CH_IO, SCSI_LOW_TIMEOUT_START); - crit_exit(); - return 0; -} - -/************************************************************** - * scsi low log - **************************************************************/ -#ifdef SCSI_LOW_DIAGNOSTIC -static void scsi_low_msg_log_init (struct scsi_low_msg_log *); -static void scsi_low_msg_log_write (struct scsi_low_msg_log *, u_int8_t *, -int); -static void scsi_low_msg_log_show (struct scsi_low_msg_log *, char *, int); - -static void -scsi_low_msg_log_init(struct scsi_low_msg_log *slmlp) -{ - slmlp->slml_ptr = 0; -} - -static void -scsi_low_msg_log_write(struct scsi_low_msg_log *slmlp, u_int8_t *datap, int len) -{ - int ptr, ind; - - if (slmlp->slml_ptr >= SCSI_LOW_MSG_LOG_DATALEN) - return; - - ptr = slmlp->slml_ptr ++; - for (ind = 0; ind < sizeof(slmlp->slml_msg[0]) && ind < len; ind ++) - slmlp->slml_msg[ptr].msg[ind] = datap[ind]; - for ( ; ind < sizeof(slmlp->slml_msg[0]); ind ++) - slmlp->slml_msg[ptr].msg[ind] = 0; -} - -static void -scsi_low_msg_log_show(struct scsi_low_msg_log *slmlp, char *s, int len) -{ - int ptr, ind; - - kprintf("%s: (%d) ", s, slmlp->slml_ptr); - for (ptr = 0; ptr < slmlp->slml_ptr; ptr ++) - { - for (ind = 0; ind < len && ind < sizeof(slmlp->slml_msg[0]); - ind ++) - { - kprintf("[%x]", (u_int) slmlp->slml_msg[ptr].msg[ind]); - } - kprintf(">"); - } - kprintf("\n"); -} -#endif /* SCSI_LOW_DIAGNOSTIC */ - -/************************************************************** - * power control - **************************************************************/ -static void -scsi_low_engage(void *arg) -{ - struct scsi_low_softc *slp = arg; - - crit_enter(); - - switch (slp->sl_rstep) - { - case 0: - slp->sl_rstep ++; - (*slp->sl_funcs->scsi_low_power) (slp, SCSI_LOW_ENGAGE); - (*slp->sl_osdep_fp->scsi_low_osdep_timeout) (slp, - SCSI_LOW_TIMEOUT_CH_ENGAGE, SCSI_LOW_TIMEOUT_START); - break; - - case 1: - slp->sl_rstep ++; - slp->sl_flags &= ~HW_RESUME; - scsi_low_start(slp); - break; - - case 2: - break; - } - crit_exit(); -} - -static int -scsi_low_init(struct scsi_low_softc *slp, u_int flags) -{ - int rv = 0; - - slp->sl_flags |= HW_INITIALIZING; - - /* clear power control timeout */ - if ((slp->sl_flags & HW_POWERCTRL) != 0) - { - (*slp->sl_osdep_fp->scsi_low_osdep_timeout) (slp, - SCSI_LOW_TIMEOUT_CH_ENGAGE, SCSI_LOW_TIMEOUT_STOP); - slp->sl_flags &= ~(HW_POWDOWN | HW_RESUME); - slp->sl_active = 1; - slp->sl_powc = SCSI_LOW_POWDOWN_TC; - } - - /* reset current nexus */ - scsi_low_reset_nexus(slp, flags); - if ((slp->sl_flags & HW_INACTIVE) != 0) - { - rv = EBUSY; - goto out; - } - - if (flags != SCSI_LOW_RESTART_SOFT) - { - rv = ((*slp->sl_funcs->scsi_low_init) (slp, flags)); - } - -out: - slp->sl_flags &= ~HW_INITIALIZING; - return rv; -} - -/************************************************************** - * allocate lun_info - **************************************************************/ -static struct lun_info * -scsi_low_alloc_li(struct targ_info *ti, int lun, int alloc) -{ - struct scsi_low_softc *slp = ti->ti_sc; - struct lun_info *li; - - li = LIST_FIRST(&ti->ti_litab); - if (li != NULL) - { - if (li->li_lun == lun) - return li; - - while ((li = LIST_NEXT(li, lun_chain)) != NULL) - { - if (li->li_lun == lun) - { - LIST_REMOVE(li, lun_chain); - LIST_INSERT_HEAD(&ti->ti_litab, li, lun_chain); - return li; - } - } - } - - if (alloc == 0) - return li; - - li = SCSI_LOW_MALLOC(ti->ti_lunsize); - if (li == NULL) - panic("no lun info mem"); - - SCSI_LOW_BZERO(li, ti->ti_lunsize); - li->li_lun = lun; - li->li_ti = ti; - - li->li_cfgflags = SCSI_LOW_SYNC | SCSI_LOW_LINK | SCSI_LOW_DISC | - SCSI_LOW_QTAG; - li->li_quirks = li->li_diskflags = SCSI_LOW_DISK_LFLAGS; - li->li_flags_valid = SCSI_LOW_LUN_FLAGS_USER_VALID; -#ifdef SCSI_LOW_FLAGS_QUIRKS_OK - li->li_flags_valid |= SCSI_LOW_LUN_FLAGS_QUIRKS_VALID; -#endif /* SCSI_LOW_FLAGS_QUIRKS_OK */ - - li->li_qtagbits = (u_int) -1; - - TAILQ_INIT(&li->li_discq); - LIST_INSERT_HEAD(&ti->ti_litab, li, lun_chain); - - /* host specific structure initialization per lun */ - if (slp->sl_funcs->scsi_low_lun_init != NULL) - (*slp->sl_funcs->scsi_low_lun_init) - (slp, ti, li, SCSI_LOW_INFO_ALLOC); - scsi_low_calcf_lun(li); - return li; -} - -/************************************************************** - * allocate targ_info - **************************************************************/ -static struct targ_info * -scsi_low_alloc_ti(struct scsi_low_softc *slp, int targ) -{ - struct targ_info *ti; - - if (TAILQ_FIRST(&slp->sl_titab) == NULL) - TAILQ_INIT(&slp->sl_titab); - - ti = SCSI_LOW_MALLOC(slp->sl_targsize); - if (ti == NULL) - panic("%s short of memory", slp->sl_xname); - - SCSI_LOW_BZERO(ti, slp->sl_targsize); - ti->ti_id = targ; - ti->ti_sc = slp; - - slp->sl_ti[targ] = ti; - TAILQ_INSERT_TAIL(&slp->sl_titab, ti, ti_chain); - LIST_INIT(&ti->ti_litab); - - ti->ti_quirks = ti->ti_diskflags = SCSI_LOW_DISK_TFLAGS; - ti->ti_owidth = SCSI_LOW_BUS_WIDTH_8; - ti->ti_flags_valid = SCSI_LOW_TARG_FLAGS_USER_VALID; -#ifdef SCSI_LOW_FLAGS_QUIRKS_OK - ti->ti_flags_valid |= SCSI_LOW_TARG_FLAGS_QUIRKS_VALID; -#endif /* SCSI_LOW_FLAGS_QUIRKS_OK */ - - if (slp->sl_funcs->scsi_low_targ_init != NULL) - { - (*slp->sl_funcs->scsi_low_targ_init) - (slp, ti, SCSI_LOW_INFO_ALLOC); - } - scsi_low_calcf_target(ti); - return ti; -} - -static void -scsi_low_free_ti(struct scsi_low_softc *slp) -{ - struct targ_info *ti, *tib; - struct lun_info *li, *nli; - - for (ti = TAILQ_FIRST(&slp->sl_titab); ti; ti = tib) - { - for (li = LIST_FIRST(&ti->ti_litab); li != NULL; li = nli) - { - if (slp->sl_funcs->scsi_low_lun_init != NULL) - { - (*slp->sl_funcs->scsi_low_lun_init) - (slp, ti, li, SCSI_LOW_INFO_DEALLOC); - } - nli = LIST_NEXT(li, lun_chain); - SCSI_LOW_FREE(li); - } - - if (slp->sl_funcs->scsi_low_targ_init != NULL) - { - (*slp->sl_funcs->scsi_low_targ_init) - (slp, ti, SCSI_LOW_INFO_DEALLOC); - } - tib = TAILQ_NEXT(ti, ti_chain); - SCSI_LOW_FREE(ti); - } -} - -/************************************************************** - * timeout - **************************************************************/ -void -scsi_low_bus_idle(struct scsi_low_softc *slp) -{ - slp->sl_retry_sel = 0; - if (slp->sl_Tnexus == NULL) - scsi_low_start(slp); -} - -static void -scsi_low_timeout(void *arg) -{ - struct scsi_low_softc *slp = arg; - - crit_enter(); - scsi_low_timeout_check(slp); - (*slp->sl_osdep_fp->scsi_low_osdep_timeout) - (slp, SCSI_LOW_TIMEOUT_CH_IO, SCSI_LOW_TIMEOUT_START); - crit_exit(); -} - -static int -scsi_low_timeout_check(struct scsi_low_softc *slp) -{ - struct targ_info *ti; - struct lun_info *li; - struct slccb *cb = NULL; /* XXX */ - - /* selection restart */ - if (slp->sl_retry_sel != 0) - { - slp->sl_retry_sel = 0; - if (slp->sl_Tnexus != NULL) - goto step1; - - cb = TAILQ_FIRST(&slp->sl_start); - if (cb == NULL) - goto step1; - - if (cb->ccb_selrcnt >= SCSI_LOW_MAX_SELECTION_RETRY) - { - cb->ccb_flags |= CCB_NORETRY; - cb->ccb_error |= SELTIMEOUTIO; - if (scsi_low_revoke_ccb(slp, cb, 1) != NULL) - panic("%s: ccb not finished", slp->sl_xname); - } - - if (slp->sl_Tnexus == NULL) - scsi_low_start(slp); - } - - /* call hardware timeout */ -step1: - if (slp->sl_funcs->scsi_low_timeout != NULL) - { - (*slp->sl_funcs->scsi_low_timeout) (slp); - } - - if (slp->sl_timeout_count ++ < - SCSI_LOW_TIMEOUT_CHECK_INTERVAL * SCSI_LOW_TIMEOUT_HZ) - return 0; - - slp->sl_timeout_count = 0; - if (slp->sl_nio > 0) - { - if ((cb = slp->sl_Qnexus) != NULL) - { - cb->ccb_tc -= SCSI_LOW_TIMEOUT_CHECK_INTERVAL; - if (cb->ccb_tc < 0) - goto bus_reset; - } - else if (slp->sl_disc == 0) - { - if ((cb = TAILQ_FIRST(&slp->sl_start)) == NULL) - return 0; - - cb->ccb_tc -= SCSI_LOW_TIMEOUT_CHECK_INTERVAL; - if (cb->ccb_tc < 0) - goto bus_reset; - } - else TAILQ_FOREACH(ti, &slp->sl_titab, ti_chain) - { - if (ti->ti_disc == 0) - continue; - - LIST_FOREACH(li, &ti->ti_litab, lun_chain) - { - TAILQ_FOREACH(cb, &li->li_discq, ccb_chain) - { - cb->ccb_tc -= - SCSI_LOW_TIMEOUT_CHECK_INTERVAL; - if (cb->ccb_tc < 0) - goto bus_reset; - } - } - } - - } - else if ((slp->sl_flags & HW_POWERCTRL) != 0) - { - if ((slp->sl_flags & (HW_POWDOWN | HW_RESUME)) != 0) - return 0; - - if (slp->sl_active != 0) - { - slp->sl_powc = SCSI_LOW_POWDOWN_TC; - slp->sl_active = 0; - return 0; - } - - slp->sl_powc --; - if (slp->sl_powc < 0) - { - slp->sl_powc = SCSI_LOW_POWDOWN_TC; - slp->sl_flags |= HW_POWDOWN; - (*slp->sl_funcs->scsi_low_power) - (slp, SCSI_LOW_POWDOWN); - } - } - return 0; - -bus_reset: - cb->ccb_error |= TIMEOUTIO; - kprintf("%s: slccb (0x%lx) timeout!\n", slp->sl_xname, (u_long) cb); - scsi_low_info(slp, NULL, "scsi bus hangup. try to recover."); - scsi_low_init(slp, SCSI_LOW_RESTART_HARD); - scsi_low_start(slp); - return ERESTART; -} - - -static int -scsi_low_abort_ccb(struct scsi_low_softc *slp, struct slccb *cb) -{ - struct targ_info *ti; - u_int msg; - - if (cb == NULL) - return EINVAL; - if ((cb->ccb_omsgoutflag & - (SCSI_LOW_MSG_ABORT | SCSI_LOW_MSG_ABORT_QTAG)) != 0) - return EBUSY; - - ti = cb->ti; - if (cb->ccb_tag == SCSI_LOW_UNKTAG) - msg = SCSI_LOW_MSG_ABORT; - else - msg = SCSI_LOW_MSG_ABORT_QTAG; - - cb->ccb_error |= ABORTIO; - cb->ccb_flags |= CCB_NORETRY; - scsi_low_ccb_message_assert(cb, msg); - - if (cb == slp->sl_Qnexus) - { - scsi_low_assert_msg(slp, ti, msg, 1); - } - else if ((cb->ccb_flags & CCB_DISCQ) != 0) - { - if (scsi_low_revoke_ccb(slp, cb, 0) == NULL) - panic("%s: revoked ccb done", slp->sl_xname); - - cb->ccb_flags |= CCB_STARTQ; - TAILQ_INSERT_HEAD(&slp->sl_start, cb, ccb_chain); - - if (slp->sl_Tnexus == NULL) - scsi_low_start(slp); - } - else - { - if (scsi_low_revoke_ccb(slp, cb, 1) != NULL) - panic("%s: revoked ccb retried", slp->sl_xname); - } - return 0; -} - -/************************************************************** - * Generic SCSI INTERFACE - **************************************************************/ -int -scsi_low_attach(struct scsi_low_softc *slp, int openings, int ntargs, int nluns, - int targsize, int lunsize) -{ - struct targ_info *ti; - struct lun_info *li; - int i, nccb, rv; - - slp->sl_osdep_fp = &scsi_low_osdep_funcs_cam; - - if (slp->sl_osdep_fp == NULL) - panic("scsi_low: interface not spcified"); - - if (ntargs > SCSI_LOW_NTARGETS) - { - kprintf("scsi_low: %d targets are too large\n", ntargs); - kprintf("change kernel options SCSI_LOW_NTARGETS"); - return EINVAL; - } - - if (openings <= 0) - slp->sl_openings = (SCSI_LOW_NCCB / ntargs); - else - slp->sl_openings = openings; - slp->sl_ntargs = ntargs; - slp->sl_nluns = nluns; - slp->sl_max_retry = SCSI_LOW_MAX_RETRY; - - if (lunsize < sizeof(struct lun_info)) - lunsize = sizeof(struct lun_info); - - if (targsize < sizeof(struct targ_info)) - targsize = sizeof(struct targ_info); - - slp->sl_targsize = targsize; - for (i = 0; i < ntargs; i ++) - { - ti = scsi_low_alloc_ti(slp, i); - ti->ti_lunsize = lunsize; - li = scsi_low_alloc_li(ti, 0, 1); - } - - /* initialize queue */ - nccb = openings * ntargs; - if (nccb >= SCSI_LOW_NCCB || nccb <= 0) - nccb = SCSI_LOW_NCCB; - scsi_low_init_ccbque(nccb); - TAILQ_INIT(&slp->sl_start); - - /* call os depend attach */ - callout_init(&slp->sl_si.timeout_ch); - callout_init(&slp->sl_si.engage_ch); - - crit_enter(); - rv = (*slp->sl_osdep_fp->scsi_low_osdep_attach) (slp); - if (rv != 0) - { - crit_exit(); - kprintf("%s: scsi_low_attach: osdep attach failed\n", - slp->sl_xname); - return EINVAL; - } - - /* check hardware */ - SCSI_LOW_DELAY(1000); /* wait for 1ms */ - if (scsi_low_init(slp, SCSI_LOW_RESTART_HARD) != 0) - { - crit_exit(); - kprintf("%s: scsi_low_attach: initialization failed\n", - slp->sl_xname); - return EINVAL; - } - - /* start watch dog */ - slp->sl_timeout_count = 0; - (*slp->sl_osdep_fp->scsi_low_osdep_timeout) - (slp, SCSI_LOW_TIMEOUT_CH_IO, SCSI_LOW_TIMEOUT_START); - LIST_INSERT_HEAD(&sl_tab, slp, sl_chain); - - /* fake call */ - scsi_low_abort_ccb(slp, scsi_low_find_ccb(slp, 0, 0, NULL)); - -#ifdef SCSI_LOW_START_UP_CHECK - /* probing devices */ - scsi_low_start_up(slp); -#endif /* SCSI_LOW_START_UP_CHECK */ - - /* call os depend attach done*/ - (*slp->sl_osdep_fp->scsi_low_osdep_world_start) (slp); - crit_exit(); - return 0; -} - -int -scsi_low_dettach(struct scsi_low_softc *slp) -{ - int rv; - - crit_enter(); - if (scsi_low_is_busy(slp) != 0) - { - crit_exit(); - return EBUSY; - } - - scsi_low_deactivate(slp); - - rv = (*slp->sl_osdep_fp->scsi_low_osdep_dettach) (slp); - if (rv != 0) - { - crit_exit(); - return EBUSY; - } - - scsi_low_free_ti(slp); - LIST_REMOVE(slp, sl_chain); - crit_exit(); - return 0; -} - -/************************************************************** - * Generic enqueue - **************************************************************/ -static int -scsi_low_enqueue(struct scsi_low_softc *slp, struct targ_info *ti, - struct lun_info *li, struct slccb *cb, u_int flags, - u_int msg) -{ - - cb->ti = ti; - cb->li = li; - - scsi_low_ccb_message_assert(cb, msg); - - cb->ccb_otag = cb->ccb_tag = SCSI_LOW_UNKTAG; - scsi_low_alloc_qtag(cb); - - cb->ccb_flags = flags | CCB_STARTQ; - cb->ccb_tc = cb->ccb_tcmax = SCSI_LOW_MIN_TOUT; - cb->ccb_error |= PENDINGIO; - - if ((flags & CCB_URGENT) != 0) - { - TAILQ_INSERT_HEAD(&slp->sl_start, cb, ccb_chain); - } - else - { - TAILQ_INSERT_TAIL(&slp->sl_start, cb, ccb_chain); - } - - slp->sl_nio ++; - - if (slp->sl_Tnexus == NULL) - scsi_low_start(slp); - return 0; -} - -static int -scsi_low_message_enqueue(struct scsi_low_softc *slp, struct targ_info *ti, - struct lun_info *li, u_int flags) -{ - struct slccb *cb; - u_int tmsgflags; - - tmsgflags = ti->ti_setup_msg; - ti->ti_setup_msg = 0; - - flags |= CCB_NORETRY; - if ((cb = SCSI_LOW_ALLOC_CCB(1)) == NULL) - return ENOMEM; - - cb->osdep = NULL; - cb->bp = NULL; - scsi_low_enqueue(slp, ti, li, cb, flags, tmsgflags); - return 0; -} - -/************************************************************** - * Generic Start & Done - **************************************************************/ -#define SLSC_MODE_SENSE_SHORT 0x1a -static u_int8_t ss_cmd[6] = {START_STOP, 0, 0, 0, SSS_START, 0}; -static u_int8_t sms_cmd[6] = {SLSC_MODE_SENSE_SHORT, 0x08, 0x0a, 0, - sizeof(struct scsi_low_mode_sense_data), 0}; -static u_int8_t inq_cmd[6] = {INQUIRY, 0, 0, 0, - sizeof(struct scsi_low_inq_data), 0}; -static u_int8_t unit_ready_cmd[6]; -static int scsi_low_setup_start (struct scsi_low_softc *, struct targ_info *, struct lun_info *, struct slccb *); -static int scsi_low_sense_abort_start (struct scsi_low_softc *, struct targ_info *, struct lun_info *, struct slccb *); -static int scsi_low_resume (struct scsi_low_softc *); - -static void -scsi_low_unit_ready_cmd(struct slccb *cb) -{ - cb->ccb_scp.scp_cmd = unit_ready_cmd; - cb->ccb_scp.scp_cmdlen = sizeof(unit_ready_cmd); - cb->ccb_scp.scp_datalen = 0; - cb->ccb_scp.scp_direction = SCSI_LOW_READ; - cb->ccb_tcmax = 15; -} - -static int -scsi_low_sense_abort_start(struct scsi_low_softc *slp, struct targ_info *ti, - struct lun_info *li, struct slccb *cb) -{ - cb->ccb_scp.scp_cmdlen = 6; - SCSI_LOW_BZERO(cb->ccb_scsi_cmd, cb->ccb_scp.scp_cmdlen); - cb->ccb_scsi_cmd[0] = REQUEST_SENSE; - cb->ccb_scsi_cmd[4] = sizeof(cb->ccb_sense); - cb->ccb_scp.scp_cmd = cb->ccb_scsi_cmd; - cb->ccb_scp.scp_data = (u_int8_t *) &cb->ccb_sense; - cb->ccb_scp.scp_datalen = sizeof(cb->ccb_sense); - cb->ccb_scp.scp_direction = SCSI_LOW_READ; - cb->ccb_tcmax = 15; - scsi_low_ccb_message_clear(cb); - if ((cb->ccb_flags & CCB_CLEARQ) != 0) - { - scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0); - } - else - { - SCSI_LOW_BZERO(&cb->ccb_sense, sizeof(cb->ccb_sense)); -#ifdef SCSI_LOW_NEGOTIATE_BEFORE_SENSE - scsi_low_assert_msg(slp, ti, ti->ti_setup_msg_done, 0); -#endif /* SCSI_LOW_NEGOTIATE_BEFORE_SENSE */ - } - - return SCSI_LOW_START_NO_QTAG; -} - -static int -scsi_low_setup_start(struct scsi_low_softc *slp, struct targ_info *ti, - struct lun_info *li, struct slccb *cb) -{ - switch(li->li_state) - { - case SCSI_LOW_LUN_SLEEP: - scsi_low_unit_ready_cmd(cb); - break; - - case SCSI_LOW_LUN_START: - cb->ccb_scp.scp_cmd = ss_cmd; - cb->ccb_scp.scp_cmdlen = sizeof(ss_cmd); - cb->ccb_scp.scp_datalen = 0; - cb->ccb_scp.scp_direction = SCSI_LOW_READ; - cb->ccb_tcmax = 30; - break; - - case SCSI_LOW_LUN_INQ: - cb->ccb_scp.scp_cmd = inq_cmd; - cb->ccb_scp.scp_cmdlen = sizeof(inq_cmd); - cb->ccb_scp.scp_data = (u_int8_t *)&li->li_inq; - cb->ccb_scp.scp_datalen = sizeof(li->li_inq); - cb->ccb_scp.scp_direction = SCSI_LOW_READ; - cb->ccb_tcmax = 15; - break; - - case SCSI_LOW_LUN_MODEQ: - cb->ccb_scp.scp_cmd = sms_cmd; - cb->ccb_scp.scp_cmdlen = sizeof(sms_cmd); - cb->ccb_scp.scp_data = (u_int8_t *)&li->li_sms; - cb->ccb_scp.scp_datalen = sizeof(li->li_sms); - cb->ccb_scp.scp_direction = SCSI_LOW_READ; - cb->ccb_tcmax = 15; - return SCSI_LOW_START_QTAG; - - default: - panic("%s: no setup phase", slp->sl_xname); - } - - return SCSI_LOW_START_NO_QTAG; -} - -static int -scsi_low_resume(struct scsi_low_softc *slp) -{ - if (slp->sl_flags & HW_RESUME) - return EJUSTRETURN; - slp->sl_flags &= ~HW_POWDOWN; - if (slp->sl_funcs->scsi_low_power != NULL) - { - slp->sl_flags |= HW_RESUME; - slp->sl_rstep = 0; - (*slp->sl_funcs->scsi_low_power) (slp, SCSI_LOW_ENGAGE); - (*slp->sl_osdep_fp->scsi_low_osdep_timeout) - (slp, SCSI_LOW_TIMEOUT_CH_ENGAGE, - SCSI_LOW_TIMEOUT_START); - return EJUSTRETURN; - } - return 0; -} - -static void -scsi_low_start(struct scsi_low_softc *slp) -{ - struct targ_info *ti; - struct lun_info *li; - struct slccb *cb; - int rv; - - /* check hardware exists or under initializations ? */ - if ((slp->sl_flags & (HW_INACTIVE | HW_INITIALIZING)) != 0) - return; - - /* check hardware power up ? */ - if ((slp->sl_flags & HW_POWERCTRL) != 0) - { - slp->sl_active ++; - if (slp->sl_flags & (HW_POWDOWN | HW_RESUME)) - { - if (scsi_low_resume(slp) == EJUSTRETURN) - return; - } - } - - /* setup nexus */ -#ifdef SCSI_LOW_DIAGNOSTIC - if (slp->sl_Tnexus || slp->sl_Lnexus || slp->sl_Qnexus) - { - scsi_low_info(slp, NULL, "NEXUS INCONSISTENT"); - panic("%s: inconsistent", slp->sl_xname); - } -#endif /* SCSI_LOW_DIAGNOSTIC */ - - TAILQ_FOREACH(cb, &slp->sl_start, ccb_chain) - { - li = cb->li; - - if (li->li_disc == 0) - { - goto scsi_low_cmd_start; - } - else if (li->li_nqio > 0) - { - if (li->li_nqio < li->li_maxnqio || - (cb->ccb_flags & (CCB_SENSE | CCB_CLEARQ)) != 0) - goto scsi_low_cmd_start; - } - } - return; - -scsi_low_cmd_start: - cb->ccb_flags &= ~CCB_STARTQ; - TAILQ_REMOVE(&slp->sl_start, cb, ccb_chain); - ti = cb->ti; - - /* clear all error flag bits (for restart) */ - cb->ccb_error = 0; - cb->ccb_datalen = -1; - cb->ccb_scp.scp_status = ST_UNKNOWN; - - /* setup nexus pointer */ - slp->sl_Qnexus = cb; - slp->sl_Lnexus = li; - slp->sl_Tnexus = ti; - - /* initialize msgsys */ - scsi_low_init_msgsys(slp, ti); - - /* exec cmd */ - if ((cb->ccb_flags & (CCB_SENSE | CCB_CLEARQ)) != 0) - { - /* CA state or forced abort */ - rv = scsi_low_sense_abort_start(slp, ti, li, cb); - } - else if (li->li_state >= SCSI_LOW_LUN_OK) - { - cb->ccb_flags &= ~CCB_INTERNAL; - rv = (*slp->sl_osdep_fp->scsi_low_osdep_ccb_setup) (slp, cb); - if (cb->ccb_msgoutflag != 0) - { - scsi_low_ccb_message_exec(slp, cb); - } - } - else - { - cb->ccb_flags |= CCB_INTERNAL; - rv = scsi_low_setup_start(slp, ti, li, cb); - } - - /* allocate qtag */ -#define SCSI_LOW_QTAG_OK (SCSI_LOW_QTAG | SCSI_LOW_DISC) - - if (rv == SCSI_LOW_START_QTAG && - (li->li_flags & SCSI_LOW_QTAG_OK) == SCSI_LOW_QTAG_OK && - li->li_maxnqio > 0) - { - u_int qmsg; - - scsi_low_activate_qtag(cb); - if ((scsi_low_cmd_flags[cb->ccb_scp.scp_cmd[0]] & - SCSI_LOW_CMD_ORDERED_QTAG) != 0) - qmsg = SCSI_LOW_MSG_ORDERED_QTAG; - else if ((cb->ccb_flags & CCB_URGENT) != 0) - qmsg = SCSI_LOW_MSG_HEAD_QTAG; - else - qmsg = SCSI_LOW_MSG_SIMPLE_QTAG; - scsi_low_assert_msg(slp, ti, qmsg, 0); - } - - /* timeout */ - if (cb->ccb_tcmax < SCSI_LOW_MIN_TOUT) - cb->ccb_tcmax = SCSI_LOW_MIN_TOUT; - cb->ccb_tc = cb->ccb_tcmax; - - /* setup saved scsi data pointer */ - cb->ccb_sscp = cb->ccb_scp; - - /* setup current scsi pointer */ - slp->sl_scp = cb->ccb_sscp; - slp->sl_error = cb->ccb_error; - - /* assert always an identify msg */ - scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_IDENTIFY, 0); - - /* debug section */ -#ifdef SCSI_LOW_DIAGNOSTIC - scsi_low_msg_log_init(&ti->ti_log_msgin); - scsi_low_msg_log_init(&ti->ti_log_msgout); -#endif /* SCSI_LOW_DIAGNOSTIC */ - - /* selection start */ - slp->sl_selid = cb; - rv = ((*slp->sl_funcs->scsi_low_start_bus) (slp, cb)); - if (rv == SCSI_LOW_START_OK) - { -#ifdef SCSI_LOW_STATICS - scsi_low_statics.nexus_win ++; -#endif /* SCSI_LOW_STATICS */ - return; - } - - scsi_low_arbit_fail(slp, cb); -#ifdef SCSI_LOW_STATICS - scsi_low_statics.nexus_fail ++; -#endif /* SCSI_LOW_STATICS */ -} - -void -scsi_low_arbit_fail(struct scsi_low_softc *slp, struct slccb *cb) -{ - struct targ_info *ti = cb->ti; - - scsi_low_deactivate_qtag(cb); - scsi_low_ccb_message_retry(cb); - cb->ccb_flags |= CCB_STARTQ; - TAILQ_INSERT_HEAD(&slp->sl_start, cb, ccb_chain); - - scsi_low_bus_release(slp, ti); - - cb->ccb_selrcnt ++; - if (slp->sl_disc == 0) - { -#ifdef SCSI_LOW_DIAGNOSTIC - kprintf("%s: try selection again\n", slp->sl_xname); -#endif /* SCSI_LOW_DIAGNOSTIC */ - slp->sl_retry_sel = 1; - } -} - -static void -scsi_low_bus_release(struct scsi_low_softc *slp, struct targ_info *ti) -{ - if (ti->ti_disc > 0) - { - SCSI_LOW_SETUP_PHASE(ti, PH_DISC); - } - else - { - SCSI_LOW_SETUP_PHASE(ti, PH_NULL); - } - - /* clear all nexus pointer */ - slp->sl_Qnexus = NULL; - slp->sl_Lnexus = NULL; - slp->sl_Tnexus = NULL; - - /* clear selection assert */ - slp->sl_selid = NULL; - - /* clear nexus data */ - slp->sl_scp.scp_direction = SCSI_LOW_RWUNK; - - /* clear phase change counter */ - slp->sl_ph_count = 0; -} - -static int -scsi_low_setup_done(struct scsi_low_softc *slp, struct slccb *cb) -{ - struct targ_info *ti; - struct lun_info *li; - - ti = cb->ti; - li = cb->li; - - if (cb->ccb_rcnt >= slp->sl_max_retry) - { - cb->ccb_error |= ABORTIO; - return SCSI_LOW_DONE_COMPLETE; - } - - /* XXX: special huck for selection timeout */ - if (li->li_state == SCSI_LOW_LUN_SLEEP && - (cb->ccb_error & SELTIMEOUTIO) != 0) - { - cb->ccb_error |= ABORTIO; - return SCSI_LOW_DONE_COMPLETE; - } - - switch(li->li_state) - { - case SCSI_LOW_LUN_INQ: - if (cb->ccb_error != 0) - { - li->li_diskflags &= - ~(SCSI_LOW_DISK_LINK | SCSI_LOW_DISK_QTAG); - if (li->li_lun > 0) - goto resume; - ti->ti_diskflags &= - ~(SCSI_LOW_DISK_SYNC | SCSI_LOW_DISK_WIDE); - } - else if ((li->li_inq.sd_version & 7) >= 2 || - (li->li_inq.sd_len >= 4)) - { - if ((li->li_inq.sd_support & 0x2) == 0) - li->li_diskflags &= ~SCSI_LOW_DISK_QTAG; - if ((li->li_inq.sd_support & 0x8) == 0) - li->li_diskflags &= ~SCSI_LOW_DISK_LINK; - if (li->li_lun > 0) - goto resume; - if ((li->li_inq.sd_support & 0x10) == 0) - ti->ti_diskflags &= ~SCSI_LOW_DISK_SYNC; - if ((li->li_inq.sd_support & 0x20) == 0) - ti->ti_diskflags &= ~SCSI_LOW_DISK_WIDE_16; - if ((li->li_inq.sd_support & 0x40) == 0) - ti->ti_diskflags &= ~SCSI_LOW_DISK_WIDE_32; - } - else - { - li->li_diskflags &= - ~(SCSI_LOW_DISK_QTAG | SCSI_LOW_DISK_LINK); - if (li->li_lun > 0) - goto resume; - ti->ti_diskflags &= ~SCSI_LOW_DISK_WIDE; - } - ti->ti_flags_valid |= SCSI_LOW_TARG_FLAGS_DISK_VALID; -resume: - scsi_low_calcf_target(ti); - scsi_low_calcf_lun(li); - break; - - case SCSI_LOW_LUN_MODEQ: - if (cb->ccb_error != 0) - { - if (cb->ccb_error & SENSEIO) - { -#ifdef SCSI_LOW_DEBUG - if (scsi_low_debug & SCSI_LOW_DEBUG_SENSE) - { - kprintf("SENSE: [%x][%x][%x][%x][%x]\n", - (u_int) cb->ccb_sense.error_code, - (u_int) cb->ccb_sense.segment, - (u_int) cb->ccb_sense.flags, - (u_int) cb->ccb_sense.add_sense_code, - (u_int) cb->ccb_sense.add_sense_code_qual); - } -#endif /* SCSI_LOW_DEBUG */ - } - else - { - li->li_diskflags &= ~SCSI_LOW_DISK_QTAG; - } - } - else if ((li->li_sms.sms_cmp.cmp_page & 0x3f) == 0x0a) - { - if (li->li_sms.sms_cmp.cmp_qc & 0x02) - li->li_qflags |= SCSI_LOW_QFLAG_CA_QCLEAR; - else - li->li_qflags &= ~SCSI_LOW_QFLAG_CA_QCLEAR; - if ((li->li_sms.sms_cmp.cmp_qc & 0x01) != 0) - li->li_diskflags &= ~SCSI_LOW_DISK_QTAG; - } - li->li_flags_valid |= SCSI_LOW_LUN_FLAGS_DISK_VALID; - scsi_low_calcf_lun(li); - break; - - default: - break; - } - - li->li_state ++; - if (li->li_state == SCSI_LOW_LUN_OK) - { - scsi_low_calcf_target(ti); - scsi_low_calcf_lun(li); - if (li->li_flags_valid == SCSI_LOW_LUN_FLAGS_ALL_VALID && - (slp->sl_show_result & SHOW_CALCF_RES) != 0) - { - scsi_low_calcf_show(li); - } - } - - cb->ccb_rcnt --; - return SCSI_LOW_DONE_RETRY; -} - -static int -scsi_low_done(struct scsi_low_softc *slp, struct slccb *cb) -{ - int rv; - - if (cb->ccb_error == 0) - { - if ((cb->ccb_flags & (CCB_SENSE | CCB_CLEARQ)) != 0) - { -#ifdef SCSI_LOW_QCLEAR_AFTER_CA - /* XXX: - * SCSI-2 draft suggests - * page 0x0a QErr bit determins if - * the target aborts or continues - * the queueing io's after CA state resolved. - * However many targets seem not to support - * the page 0x0a. Thus we should manually clear the - * queuing io's after CA state. - */ - if ((cb->ccb_flags & CCB_CLEARQ) == 0) - { - cb->ccb_rcnt --; - cb->ccb_flags |= CCB_CLEARQ; - goto retry; - } -#endif /* SCSI_LOW_QCLEAR_AFTER_CA */ - - if ((cb->ccb_flags & CCB_SENSE) != 0) - cb->ccb_error |= (SENSEIO | ABORTIO); - cb->ccb_flags &= ~(CCB_SENSE | CCB_CLEARQ); - } - else switch (cb->ccb_sscp.scp_status) - { - case ST_GOOD: - case ST_MET: - case ST_INTERGOOD: - case ST_INTERMET: - if (cb->ccb_datalen == 0 || - cb->ccb_scp.scp_datalen == 0) - break; - - if (cb->ccb_scp.scp_cmdlen > 0 && - (scsi_low_cmd_flags[cb->ccb_scp.scp_cmd[0]] & - SCSI_LOW_CMD_RESIDUAL_CHK) == 0) - break; - - cb->ccb_error |= PDMAERR; - break; - - case ST_BUSY: - case ST_QUEFULL: - cb->ccb_error |= (BUSYERR | STATERR); - break; - - case ST_CONFLICT: - cb->ccb_error |= (STATERR | ABORTIO); - break; - - case ST_CHKCOND: - case ST_CMDTERM: - if (cb->ccb_flags & (CCB_AUTOSENSE | CCB_INTERNAL)) - { - cb->ccb_rcnt --; - cb->ccb_flags |= CCB_SENSE; - goto retry; - } - cb->ccb_error |= (UACAERR | STATERR | ABORTIO); - break; - - case ST_UNKNOWN: - default: - cb->ccb_error |= FATALIO; - break; - } - } - else - { - if (cb->ccb_flags & CCB_SENSE) - { - cb->ccb_error |= (SENSEERR | ABORTIO); - } - cb->ccb_flags &= ~(CCB_CLEARQ | CCB_SENSE); - } - - /* internal ccb */ - if ((cb->ccb_flags & CCB_INTERNAL) != 0) - { - if (scsi_low_setup_done(slp, cb) == SCSI_LOW_DONE_RETRY) - goto retry; - } - - /* check a ccb msgout flag */ - if (cb->ccb_omsgoutflag != 0) - { -#define SCSI_LOW_MSG_ABORT_OK (SCSI_LOW_MSG_ABORT | \ - SCSI_LOW_MSG_ABORT_QTAG | \ - SCSI_LOW_MSG_CLEAR_QTAG | \ - SCSI_LOW_MSG_TERMIO) - - if ((cb->ccb_omsgoutflag & SCSI_LOW_MSG_ABORT_OK) != 0) - { - cb->ccb_error |= ABORTIO; - } - } - - /* call OS depend done */ - if (cb->osdep != NULL) - { - rv = (*slp->sl_osdep_fp->scsi_low_osdep_done) (slp, cb); - if (rv == EJUSTRETURN) - goto retry; - } - else if (cb->ccb_error != 0) - { - if (cb->ccb_rcnt >= slp->sl_max_retry) - cb->ccb_error |= ABORTIO; - - if ((cb->ccb_flags & CCB_NORETRY) == 0 && - (cb->ccb_error & ABORTIO) == 0) - goto retry; - } - - /* free our target */ -#ifdef SCSI_LOW_DEBUG - if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_DONE, cb->ti->ti_id) != 0) - { - kprintf(">> SCSI_LOW_DONE_COMPLETE ===============\n"); - scsi_low_print(slp, NULL); - } -#endif /* SCSI_LOW_DEBUG */ - - scsi_low_deactivate_qtag(cb); - scsi_low_dealloc_qtag(cb); - scsi_low_free_ccb(cb); - slp->sl_nio --; - return SCSI_LOW_DONE_COMPLETE; - -retry: -#ifdef SCSI_LOW_DEBUG - if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_DONE, cb->ti->ti_id) != 0) - { - kprintf("** SCSI_LOW_DONE_RETRY ===============\n"); - scsi_low_print(slp, NULL); - } -#endif /* SCSI_LOW_DEBUG */ - - cb->ccb_rcnt ++; - scsi_low_deactivate_qtag(cb); - scsi_low_ccb_message_retry(cb); - return SCSI_LOW_DONE_RETRY; -} - -/************************************************************** - * Reset - **************************************************************/ -static void -scsi_low_reset_nexus_target(struct scsi_low_softc *slp, struct targ_info *ti, - int fdone) -{ - struct lun_info *li; - - LIST_FOREACH(li, &ti->ti_litab, lun_chain) - { - scsi_low_reset_nexus_lun(slp, li, fdone); - li->li_state = SCSI_LOW_LUN_SLEEP; - li->li_maxnqio = 0; - } - - ti->ti_disc = 0; - ti->ti_setup_msg = 0; - ti->ti_setup_msg_done = 0; - - ti->ti_osynch.offset = ti->ti_osynch.period = 0; - ti->ti_owidth = SCSI_LOW_BUS_WIDTH_8; - - ti->ti_diskflags = SCSI_LOW_DISK_TFLAGS; - ti->ti_flags_valid &= ~SCSI_LOW_TARG_FLAGS_DISK_VALID; - - if (slp->sl_funcs->scsi_low_targ_init != NULL) - { - ((*slp->sl_funcs->scsi_low_targ_init) - (slp, ti, SCSI_LOW_INFO_REVOKE)); - } - scsi_low_calcf_target(ti); - - LIST_FOREACH(li, &ti->ti_litab, lun_chain) - { - li->li_flags = 0; - - li->li_diskflags = SCSI_LOW_DISK_LFLAGS; - li->li_flags_valid &= ~SCSI_LOW_LUN_FLAGS_DISK_VALID; - - if (slp->sl_funcs->scsi_low_lun_init != NULL) - { - ((*slp->sl_funcs->scsi_low_lun_init) - (slp, ti, li, SCSI_LOW_INFO_REVOKE)); - } - scsi_low_calcf_lun(li); - } -} - -static void -scsi_low_reset_nexus(struct scsi_low_softc *slp, int fdone) -{ - struct targ_info *ti; - struct slccb *cb, *topcb; - - if ((cb = slp->sl_Qnexus) != NULL) - { - topcb = scsi_low_revoke_ccb(slp, cb, fdone); - } - else - { - topcb = NULL; - } - - TAILQ_FOREACH(ti, &slp->sl_titab, ti_chain) - { - scsi_low_reset_nexus_target(slp, ti, fdone); - scsi_low_bus_release(slp, ti); - scsi_low_init_msgsys(slp, ti); - } - - if (topcb != NULL) - { - topcb->ccb_flags |= CCB_STARTQ; - TAILQ_INSERT_HEAD(&slp->sl_start, topcb, ccb_chain); - } - - slp->sl_disc = 0; - slp->sl_retry_sel = 0; - slp->sl_flags &= ~HW_PDMASTART; -} - -/* misc */ -static int tw_pos; -static char tw_chars[] = "|/-\\"; -#define TWIDDLEWAIT 10000 - -static void -scsi_low_twiddle_wait(void) -{ - kprintf("\b%c", tw_chars[tw_pos++]); - tw_pos %= (sizeof(tw_chars) - 1); - SCSI_LOW_DELAY(TWIDDLEWAIT); -} - -void -scsi_low_bus_reset(struct scsi_low_softc *slp) -{ - int i; - - (*slp->sl_funcs->scsi_low_bus_reset) (slp); - - kprintf("%s: try to reset scsi bus ", slp->sl_xname); - for (i = 0; i <= SCSI2_RESET_DELAY / TWIDDLEWAIT ; i++) - scsi_low_twiddle_wait(); - kprintf("\b\n"); -} - -int -scsi_low_restart(struct scsi_low_softc *slp, int flags, u_char *s) -{ - int error; - - if (s != NULL) - kprintf("%s: scsi bus restart. reason: %s\n", slp->sl_xname, s); - - if ((error = scsi_low_init(slp, flags)) != 0) - return error; - - scsi_low_start(slp); - return 0; -} - -/************************************************************** - * disconnect and reselect - **************************************************************/ -#define MSGCMD_LUN(msg) (msg & 0x07) - -static struct slccb * -scsi_low_establish_ccb(struct targ_info *ti, struct lun_info *li, scsi_low_tag_t tag) -{ - struct scsi_low_softc *slp = ti->ti_sc; - struct slccb *cb; - - if (li == NULL) - return NULL; - - TAILQ_FOREACH(cb, &li->li_discq, ccb_chain) - if (cb->ccb_tag == tag) - goto found; - return cb; - - /* - * establish our ccb nexus - */ -found: -#ifdef SCSI_LOW_DEBUG - if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_NEXUS_CHECK, ti->ti_id) != 0) - { - kprintf("%s: nexus(0x%lx) abort check start\n", - slp->sl_xname, (u_long) cb); - cb->ccb_flags |= (CCB_NORETRY | CCB_SILENT); - scsi_low_revoke_ccb(slp, cb, 1); - return NULL; - } - - if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_ATTEN_CHECK, ti->ti_id) != 0) - { - if (cb->ccb_omsgoutflag == 0) - scsi_low_ccb_message_assert(cb, SCSI_LOW_MSG_NOOP); - } -#endif /* SCSI_LOW_DEBUG */ - - TAILQ_REMOVE(&li->li_discq, cb, ccb_chain); - cb->ccb_flags &= ~CCB_DISCQ; - slp->sl_Qnexus = cb; - - slp->sl_scp = cb->ccb_sscp; - slp->sl_error |= cb->ccb_error; - - slp->sl_disc --; - ti->ti_disc --; - li->li_disc --; - - /* inform "ccb nexus established" to the host driver */ - (*slp->sl_funcs->scsi_low_establish_ccb_nexus) (slp); - - /* check msg */ - if (cb->ccb_msgoutflag != 0) - { - scsi_low_ccb_message_exec(slp, cb); - } - - return cb; -} - -struct targ_info * -scsi_low_reselected(struct scsi_low_softc *slp, u_int targ) -{ - struct targ_info *ti; - struct slccb *cb; - u_char *s; - - /* - * Check select vs reselected collision. - */ - - if ((cb = slp->sl_selid) != NULL) - { - scsi_low_arbit_fail(slp, cb); -#ifdef SCSI_LOW_STATICS - scsi_low_statics.nexus_conflict ++; -#endif /* SCSI_LOW_STATICS */ - } - - /* - * Check if no current active nexus. - */ - if (slp->sl_Tnexus != NULL) - { - s = "host busy"; - goto world_restart; - } - - /* - * Check a valid target id asserted ? - */ - if (targ >= slp->sl_ntargs || targ == slp->sl_hostid) - { - s = "scsi id illegal"; - goto world_restart; - } - - /* - * Check the target scsi status. - */ - ti = slp->sl_ti[targ]; - if (ti->ti_phase != PH_DISC && ti->ti_phase != PH_NULL) - { - s = "phase mismatch"; - goto world_restart; - } - - /* - * Setup init msgsys - */ - slp->sl_error = 0; - scsi_low_init_msgsys(slp, ti); - - /* - * Establish our target nexus - */ - SCSI_LOW_SETUP_PHASE(ti, PH_RESEL); - slp->sl_Tnexus = ti; -#ifdef SCSI_LOW_STATICS - scsi_low_statics.nexus_reselected ++; -#endif /* SCSI_LOW_STATICS */ - return ti; - -world_restart: - kprintf("%s: reselect(%x:unknown) %s\n", slp->sl_xname, targ, s); - scsi_low_restart(slp, SCSI_LOW_RESTART_HARD, - "reselect: scsi world confused"); - return NULL; -} - -/************************************************************** - * cmd out pointer setup - **************************************************************/ -int -scsi_low_cmd(struct scsi_low_softc *slp, struct targ_info *ti) -{ - struct slccb *cb = slp->sl_Qnexus; - - slp->sl_ph_count ++; - if (cb == NULL) - { - /* - * no ccb, abort! - */ - slp->sl_scp.scp_cmd = (u_int8_t *) &unit_ready_cmd; - slp->sl_scp.scp_cmdlen = sizeof(unit_ready_cmd); - slp->sl_scp.scp_datalen = 0; - slp->sl_scp.scp_direction = SCSI_LOW_READ; - slp->sl_error |= FATALIO; - scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0); - SCSI_LOW_INFO(slp, ti, "CMDOUT: ccb nexus not found"); - return EINVAL; - } - else - { -#ifdef SCSI_LOW_DEBUG - if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_CMDLNK_CHECK, ti->ti_id)) - { - scsi_low_test_cmdlnk(slp, cb); - } -#endif /* SCSI_LOW_DEBUG */ - } - return 0; -} - -/************************************************************** - * data out pointer setup - **************************************************************/ -int -scsi_low_data(struct scsi_low_softc *slp, struct targ_info *ti, - struct buf **bp, int direction) -{ - struct slccb *cb = slp->sl_Qnexus; - - if (cb != NULL && direction == cb->ccb_sscp.scp_direction) - { - *bp = cb->bp; - return 0; - } - - slp->sl_error |= (FATALIO | PDMAERR); - slp->sl_scp.scp_datalen = 0; - slp->sl_scp.scp_direction = direction; - scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0); - if (ti->ti_ophase != ti->ti_phase) - { - char *s; - - if (cb == NULL) - s = "DATA PHASE: ccb nexus not found"; - else - s = "DATA PHASE: xfer direction mismatch"; - SCSI_LOW_INFO(slp, ti, s); - } - - *bp = NULL; - return EINVAL; -} - -/************************************************************** - * MSG_SYS - **************************************************************/ -#define MSGINPTR_CLR(ti) {(ti)->ti_msginptr = 0; (ti)->ti_msginlen = 0;} -#define MSGIN_PERIOD(ti) ((ti)->ti_msgin[3]) -#define MSGIN_OFFSET(ti) ((ti)->ti_msgin[4]) -#define MSGIN_WIDTHP(ti) ((ti)->ti_msgin[3]) -#define MSGIN_DATA_LAST 0x30 - -static int scsi_low_errfunc_synch (struct scsi_low_softc *, u_int); -static int scsi_low_errfunc_wide (struct scsi_low_softc *, u_int); -static int scsi_low_errfunc_identify (struct scsi_low_softc *, u_int); -static int scsi_low_errfunc_qtag (struct scsi_low_softc *, u_int); - -static int scsi_low_msgfunc_synch (struct scsi_low_softc *); -static int scsi_low_msgfunc_wide (struct scsi_low_softc *); -static int scsi_low_msgfunc_identify (struct scsi_low_softc *); -static int scsi_low_msgfunc_abort (struct scsi_low_softc *); -static int scsi_low_msgfunc_qabort (struct scsi_low_softc *); -static int scsi_low_msgfunc_qtag (struct scsi_low_softc *); -static int scsi_low_msgfunc_reset (struct scsi_low_softc *); - -struct scsi_low_msgout_data { - u_int md_flags; - u_int8_t md_msg; - int (*md_msgfunc) (struct scsi_low_softc *); - int (*md_errfunc) (struct scsi_low_softc *, u_int); -#define MSG_RELEASE_ATN 0x0001 - u_int md_condition; -}; - -struct scsi_low_msgout_data scsi_low_msgout_data[] = { -/* 0 */ {SCSI_LOW_MSG_RESET, MSG_RESET, scsi_low_msgfunc_reset, NULL, MSG_RELEASE_ATN}, -/* 1 */ {SCSI_LOW_MSG_REJECT, MSG_REJECT, NULL, NULL, MSG_RELEASE_ATN}, -/* 2 */ {SCSI_LOW_MSG_PARITY, MSG_PARITY, NULL, NULL, MSG_RELEASE_ATN}, -/* 3 */ {SCSI_LOW_MSG_ERROR, MSG_I_ERROR, NULL, NULL, MSG_RELEASE_ATN}, -/* 4 */ {SCSI_LOW_MSG_IDENTIFY, MSG_IDENTIFY, scsi_low_msgfunc_identify, scsi_low_errfunc_identify, 0}, -/* 5 */ {SCSI_LOW_MSG_ABORT, MSG_ABORT, scsi_low_msgfunc_abort, NULL, MSG_RELEASE_ATN}, -/* 6 */ {SCSI_LOW_MSG_TERMIO, MSG_TERM_IO, NULL, NULL, MSG_RELEASE_ATN}, -/* 7 */ {SCSI_LOW_MSG_SIMPLE_QTAG, MSG_SIMPLE_QTAG, scsi_low_msgfunc_qtag, scsi_low_errfunc_qtag, 0}, -/* 8 */ {SCSI_LOW_MSG_ORDERED_QTAG, MSG_ORDERED_QTAG, scsi_low_msgfunc_qtag, scsi_low_errfunc_qtag, 0}, -/* 9 */{SCSI_LOW_MSG_HEAD_QTAG, MSG_HEAD_QTAG, scsi_low_msgfunc_qtag, scsi_low_errfunc_qtag, 0}, -/* 10 */ {SCSI_LOW_MSG_ABORT_QTAG, MSG_ABORT_QTAG, scsi_low_msgfunc_qabort, NULL, MSG_RELEASE_ATN}, -/* 11 */ {SCSI_LOW_MSG_CLEAR_QTAG, MSG_CLEAR_QTAG, scsi_low_msgfunc_abort, NULL, MSG_RELEASE_ATN}, -/* 12 */{SCSI_LOW_MSG_WIDE, MSG_EXTEND, scsi_low_msgfunc_wide, scsi_low_errfunc_wide, MSG_RELEASE_ATN}, -/* 13 */{SCSI_LOW_MSG_SYNCH, MSG_EXTEND, scsi_low_msgfunc_synch, scsi_low_errfunc_synch, MSG_RELEASE_ATN}, -/* 14 */{SCSI_LOW_MSG_NOOP, MSG_NOOP, NULL, NULL, MSG_RELEASE_ATN}, -/* 15 */{SCSI_LOW_MSG_ALL, 0}, -}; - -static int scsi_low_msginfunc_ext (struct scsi_low_softc *); -static int scsi_low_synch (struct scsi_low_softc *); -static int scsi_low_wide (struct scsi_low_softc *); -static int scsi_low_msginfunc_msg_reject (struct scsi_low_softc *); -static int scsi_low_msginfunc_rejop (struct scsi_low_softc *); -static int scsi_low_msginfunc_rp (struct scsi_low_softc *); -static int scsi_low_msginfunc_sdp (struct scsi_low_softc *); -static int scsi_low_msginfunc_disc (struct scsi_low_softc *); -static int scsi_low_msginfunc_cc (struct scsi_low_softc *); -static int scsi_low_msginfunc_lcc (struct scsi_low_softc *); -static int scsi_low_msginfunc_parity (struct scsi_low_softc *); -static int scsi_low_msginfunc_noop (struct scsi_low_softc *); -static int scsi_low_msginfunc_simple_qtag (struct scsi_low_softc *); -static int scsi_low_msginfunc_i_wide_residue (struct scsi_low_softc *); - -struct scsi_low_msgin_data { - u_int md_len; - int (*md_msgfunc) (struct scsi_low_softc *); -}; - -struct scsi_low_msgin_data scsi_low_msgin_data[] = { -/* 0 */ {1, scsi_low_msginfunc_cc}, -/* 1 */ {2, scsi_low_msginfunc_ext}, -/* 2 */ {1, scsi_low_msginfunc_sdp}, -/* 3 */ {1, scsi_low_msginfunc_rp}, -/* 4 */ {1, scsi_low_msginfunc_disc}, -/* 5 */ {1, scsi_low_msginfunc_rejop}, -/* 6 */ {1, scsi_low_msginfunc_rejop}, -/* 7 */ {1, scsi_low_msginfunc_msg_reject}, -/* 8 */ {1, scsi_low_msginfunc_noop}, -/* 9 */ {1, scsi_low_msginfunc_parity}, -/* a */ {1, scsi_low_msginfunc_lcc}, -/* b */ {1, scsi_low_msginfunc_lcc}, -/* c */ {1, scsi_low_msginfunc_rejop}, -/* d */ {2, scsi_low_msginfunc_rejop}, -/* e */ {1, scsi_low_msginfunc_rejop}, -/* f */ {1, scsi_low_msginfunc_rejop}, -/* 0x10 */ {1, scsi_low_msginfunc_rejop}, -/* 0x11 */ {1, scsi_low_msginfunc_rejop}, -/* 0x12 */ {1, scsi_low_msginfunc_rejop}, -/* 0x13 */ {1, scsi_low_msginfunc_rejop}, -/* 0x14 */ {1, scsi_low_msginfunc_rejop}, -/* 0x15 */ {1, scsi_low_msginfunc_rejop}, -/* 0x16 */ {1, scsi_low_msginfunc_rejop}, -/* 0x17 */ {1, scsi_low_msginfunc_rejop}, -/* 0x18 */ {1, scsi_low_msginfunc_rejop}, -/* 0x19 */ {1, scsi_low_msginfunc_rejop}, -/* 0x1a */ {1, scsi_low_msginfunc_rejop}, -/* 0x1b */ {1, scsi_low_msginfunc_rejop}, -/* 0x1c */ {1, scsi_low_msginfunc_rejop}, -/* 0x1d */ {1, scsi_low_msginfunc_rejop}, -/* 0x1e */ {1, scsi_low_msginfunc_rejop}, -/* 0x1f */ {1, scsi_low_msginfunc_rejop}, -/* 0x20 */ {2, scsi_low_msginfunc_simple_qtag}, -/* 0x21 */ {2, scsi_low_msginfunc_rejop}, -/* 0x22 */ {2, scsi_low_msginfunc_rejop}, -/* 0x23 */ {2, scsi_low_msginfunc_i_wide_residue}, -/* 0x24 */ {2, scsi_low_msginfunc_rejop}, -/* 0x25 */ {2, scsi_low_msginfunc_rejop}, -/* 0x26 */ {2, scsi_low_msginfunc_rejop}, -/* 0x27 */ {2, scsi_low_msginfunc_rejop}, -/* 0x28 */ {2, scsi_low_msginfunc_rejop}, -/* 0x29 */ {2, scsi_low_msginfunc_rejop}, -/* 0x2a */ {2, scsi_low_msginfunc_rejop}, -/* 0x2b */ {2, scsi_low_msginfunc_rejop}, -/* 0x2c */ {2, scsi_low_msginfunc_rejop}, -/* 0x2d */ {2, scsi_low_msginfunc_rejop}, -/* 0x2e */ {2, scsi_low_msginfunc_rejop}, -/* 0x2f */ {2, scsi_low_msginfunc_rejop}, -/* 0x30 */ {1, scsi_low_msginfunc_rejop} /* default rej op */ -}; - -/************************************************************** - * msgout - **************************************************************/ -static int -scsi_low_msgfunc_synch(struct scsi_low_softc *slp) -{ - struct targ_info *ti = slp->sl_Tnexus; - int ptr = ti->ti_msgoutlen; - - ti->ti_msgoutstr[ptr + 1] = MSG_EXTEND_SYNCHLEN; - ti->ti_msgoutstr[ptr + 2] = MSG_EXTEND_SYNCHCODE; - ti->ti_msgoutstr[ptr + 3] = ti->ti_maxsynch.period; - ti->ti_msgoutstr[ptr + 4] = ti->ti_maxsynch.offset; - return MSG_EXTEND_SYNCHLEN + 2; -} - -static int -scsi_low_msgfunc_wide(struct scsi_low_softc *slp) -{ - struct targ_info *ti = slp->sl_Tnexus; - int ptr = ti->ti_msgoutlen; - - ti->ti_msgoutstr[ptr + 1] = MSG_EXTEND_WIDELEN; - ti->ti_msgoutstr[ptr + 2] = MSG_EXTEND_WIDECODE; - ti->ti_msgoutstr[ptr + 3] = ti->ti_width; - return MSG_EXTEND_WIDELEN + 2; -} - -static int -scsi_low_msgfunc_identify(struct scsi_low_softc *slp) -{ - struct targ_info *ti = slp->sl_Tnexus; - struct lun_info *li = slp->sl_Lnexus; - struct slccb *cb = slp->sl_Qnexus; - int ptr = ti->ti_msgoutlen; - u_int8_t msg; - - msg = MSG_IDENTIFY; - if (cb == NULL) - { - slp->sl_error |= FATALIO; - scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0); - SCSI_LOW_INFO(slp, ti, "MSGOUT: nexus unknown"); - } - else - { - if (scsi_low_is_disconnect_ok(cb) != 0) - msg |= (MSG_IDENTIFY_DISCPRIV | li->li_lun); - else - msg |= li->li_lun; - - if (ti->ti_phase == PH_MSGOUT) - { - (*slp->sl_funcs->scsi_low_establish_lun_nexus) (slp); - if (cb->ccb_tag == SCSI_LOW_UNKTAG) - { - (*slp->sl_funcs->scsi_low_establish_ccb_nexus) (slp); - } - } - } - ti->ti_msgoutstr[ptr + 0] = msg; - return 1; -} - -static int -scsi_low_msgfunc_abort(struct scsi_low_softc *slp) -{ - SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_ABORT); - return 1; -} - -static int -scsi_low_msgfunc_qabort(struct scsi_low_softc *slp) -{ - SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_TERM); - return 1; -} - -static int -scsi_low_msgfunc_reset(struct scsi_low_softc *slp) -{ - SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_RESET); - return 1; -} - -static int -scsi_low_msgfunc_qtag(struct scsi_low_softc *slp) -{ - struct targ_info *ti = slp->sl_Tnexus; - struct slccb *cb = slp->sl_Qnexus; - int ptr = ti->ti_msgoutlen; - - if (cb == NULL || cb->ccb_tag == SCSI_LOW_UNKTAG) - { - ti->ti_msgoutstr[ptr + 0] = MSG_NOOP; - return 1; - } - else - { - ti->ti_msgoutstr[ptr + 1] = (u_int8_t) cb->ccb_tag; - if (ti->ti_phase == PH_MSGOUT) - { - (*slp->sl_funcs->scsi_low_establish_ccb_nexus) (slp); - } - } - return 2; -} - -/* - * The following functions are called when targets give unexpected - * responces in msgin (after msgout). - */ -static int -scsi_low_errfunc_identify(struct scsi_low_softc *slp, u_int msgflags) -{ - if (slp->sl_Lnexus != NULL) - { - slp->sl_Lnexus->li_cfgflags &= ~SCSI_LOW_DISC; - scsi_low_calcf_lun(slp->sl_Lnexus); - } - return 0; -} - -static int -scsi_low_errfunc_synch(struct scsi_low_softc *slp, u_int msgflags) -{ - struct targ_info *ti = slp->sl_Tnexus; - - MSGIN_PERIOD(ti) = 0; - MSGIN_OFFSET(ti) = 0; - scsi_low_synch(slp); - return 0; -} - -static int -scsi_low_errfunc_wide(struct scsi_low_softc *slp, u_int msgflags) -{ - struct targ_info *ti = slp->sl_Tnexus; - - MSGIN_WIDTHP(ti) = 0; - scsi_low_wide(slp); - return 0; -} - -static int -scsi_low_errfunc_qtag(struct scsi_low_softc *slp, u_int msgflags) -{ - if ((msgflags & SCSI_LOW_MSG_REJECT) != 0) - { - if (slp->sl_Qnexus != NULL) - { - scsi_low_deactivate_qtag(slp->sl_Qnexus); - } - if (slp->sl_Lnexus != NULL) - { - slp->sl_Lnexus->li_cfgflags &= ~SCSI_LOW_QTAG; - scsi_low_calcf_lun(slp->sl_Lnexus); - } - kprintf("%s: scsi_low: qtag msg rejected\n", slp->sl_xname); - } - return 0; -} - - -int -scsi_low_msgout(struct scsi_low_softc *slp, struct targ_info *ti, u_int fl) -{ - struct scsi_low_msgout_data *mdp; - int len = 0; - -#ifdef SCSI_LOW_DIAGNOSTIC - if (ti != slp->sl_Tnexus) - { - scsi_low_print(slp, NULL); - panic("scsi_low_msgout: Target nexus inconsistent"); - } -#endif /* SCSI_LOW_DIAGNOSTIC */ - - slp->sl_ph_count ++; - if (slp->sl_ph_count > SCSI_LOW_MAX_PHCHANGES) - { - kprintf("%s: too many phase changes\n", slp->sl_xname); - slp->sl_error |= FATALIO; - scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0); - } - - /* STEP I. - * Scsi phase changes. - * Previously msgs asserted are accepted by our target or - * processed by scsi_low_msgin. - * Thus clear all saved informations. - */ - if ((fl & SCSI_LOW_MSGOUT_INIT) != 0) - { - ti->ti_omsgflags = 0; - ti->ti_emsgflags = 0; - } - else if (slp->sl_atten == 0) - { - /* STEP II. - * We did not assert attention, however still our target required - * msgs. Resend previous msgs. - */ - ti->ti_msgflags |= ti->ti_omsgflags; - ti->ti_omsgflags = 0; -#ifdef SCSI_LOW_DIAGNOSTIC - kprintf("%s: scsi_low_msgout: retry msgout\n", slp->sl_xname); -#endif /* SCSI_LOW_DIAGNOSTIC */ - } - - /* STEP III. - * We have no msgs. send MSG_NOOP (OK?) - */ - if (scsi_low_is_msgout_continue(ti, 0) == 0) - scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_NOOP, 0); - - /* STEP IV. - * Process all msgs - */ - ti->ti_msgoutlen = 0; - slp->sl_clear_atten = 0; - mdp = &scsi_low_msgout_data[0]; - for ( ; mdp->md_flags != SCSI_LOW_MSG_ALL; mdp ++) - { - if ((ti->ti_msgflags & mdp->md_flags) != 0) - { - ti->ti_omsgflags |= mdp->md_flags; - ti->ti_msgflags &= ~mdp->md_flags; - ti->ti_emsgflags = mdp->md_flags; - - ti->ti_msgoutstr[ti->ti_msgoutlen] = mdp->md_msg; - if (mdp->md_msgfunc != NULL) - len = (*mdp->md_msgfunc) (slp); - else - len = 1; - -#ifdef SCSI_LOW_DIAGNOSTIC - scsi_low_msg_log_write(&ti->ti_log_msgout, - &ti->ti_msgoutstr[ti->ti_msgoutlen], len); -#endif /* SCSI_LOW_DIAGNOSTIC */ - - ti->ti_msgoutlen += len; - if ((mdp->md_condition & MSG_RELEASE_ATN) != 0) - { - slp->sl_clear_atten = 1; - break; - } - - if ((fl & SCSI_LOW_MSGOUT_UNIFY) == 0 || - ti->ti_msgflags == 0) - break; - - if (ti->ti_msgoutlen >= SCSI_LOW_MAX_MSGLEN - 5) - break; - } - } - - if (scsi_low_is_msgout_continue(ti, 0) == 0) - slp->sl_clear_atten = 1; - - return ti->ti_msgoutlen; -} - -/************************************************************** - * msgin - **************************************************************/ -static int -scsi_low_msginfunc_noop(struct scsi_low_softc *slp) -{ - return 0; -} - -static int -scsi_low_msginfunc_rejop(struct scsi_low_softc *slp) -{ - struct targ_info *ti = slp->sl_Tnexus; - u_int8_t msg = ti->ti_msgin[0]; - - kprintf("%s: MSGIN: msg 0x%x rejected\n", slp->sl_xname, (u_int) msg); - scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0); - return 0; -} - -static int -scsi_low_msginfunc_cc(struct scsi_low_softc *slp) -{ - struct lun_info *li; - - SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_CMDC); - - /* validate status */ - if (slp->sl_Qnexus == NULL) - return ENOENT; - - slp->sl_Qnexus->ccb_sscp.scp_status = slp->sl_scp.scp_status; - li = slp->sl_Lnexus; - switch (slp->sl_scp.scp_status) - { - case ST_GOOD: - li->li_maxnqio = li->li_maxnexus; - break; - - case ST_CHKCOND: - li->li_maxnqio = 0; - if (li->li_qflags & SCSI_LOW_QFLAG_CA_QCLEAR) - scsi_low_reset_nexus_lun(slp, li, 0); - break; - - case ST_BUSY: - li->li_maxnqio = 0; - break; - - case ST_QUEFULL: - if (li->li_maxnexus >= li->li_nqio) - li->li_maxnexus = li->li_nqio - 1; - li->li_maxnqio = li->li_maxnexus; - break; - - case ST_INTERGOOD: - case ST_INTERMET: - slp->sl_error |= MSGERR; - break; - - default: - break; - } - return 0; -} - -static int -scsi_low_msginfunc_lcc(struct scsi_low_softc *slp) -{ - struct targ_info *ti; - struct lun_info *li; - struct slccb *ncb, *cb; - - ti = slp->sl_Tnexus; - li = slp->sl_Lnexus; - if ((cb = slp->sl_Qnexus) == NULL) - goto bad; - - cb->ccb_sscp.scp_status = slp->sl_scp.scp_status; - switch (slp->sl_scp.scp_status) - { - case ST_INTERGOOD: - case ST_INTERMET: - li->li_maxnqio = li->li_maxnexus; - break; - - default: - slp->sl_error |= MSGERR; - break; - } - - if ((li->li_flags & SCSI_LOW_LINK) == 0) - goto bad; - - cb->ccb_error |= slp->sl_error; - if (cb->ccb_error != 0) - goto bad; - - TAILQ_FOREACH(ncb, &slp->sl_start, ccb_chain) - { - if (ncb->li == li) - goto cmd_link_start; - } - - -bad: - SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_LCTERM); - scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0); - return EIO; - -cmd_link_start: - ncb->ccb_flags &= ~CCB_STARTQ; - TAILQ_REMOVE(&slp->sl_start, ncb, ccb_chain); - - scsi_low_dealloc_qtag(ncb); - ncb->ccb_tag = cb->ccb_tag; - ncb->ccb_otag = cb->ccb_otag; - cb->ccb_tag = SCSI_LOW_UNKTAG; - cb->ccb_otag = SCSI_LOW_UNKTAG; - if (scsi_low_done(slp, cb) == SCSI_LOW_DONE_RETRY) - panic("%s: linked ccb retried", slp->sl_xname); - - slp->sl_Qnexus = ncb; - slp->sl_ph_count = 0; - - ncb->ccb_error = 0; - ncb->ccb_datalen = -1; - ncb->ccb_scp.scp_status = ST_UNKNOWN; - ncb->ccb_flags &= ~CCB_INTERNAL; - - scsi_low_init_msgsys(slp, ti); - - (*slp->sl_osdep_fp->scsi_low_osdep_ccb_setup) (slp, ncb); - - if (ncb->ccb_tcmax < SCSI_LOW_MIN_TOUT) - ncb->ccb_tcmax = SCSI_LOW_MIN_TOUT; - ncb->ccb_tc = ncb->ccb_tcmax; - - /* setup saved scsi data pointer */ - ncb->ccb_sscp = ncb->ccb_scp; - slp->sl_scp = ncb->ccb_sscp; - slp->sl_error = ncb->ccb_error; - -#ifdef SCSI_LOW_DIAGNOSTIC - scsi_low_msg_log_init(&ti->ti_log_msgin); - scsi_low_msg_log_init(&ti->ti_log_msgout); -#endif /* SCSI_LOW_DIAGNOSTIC */ - return EJUSTRETURN; -} - -static int -scsi_low_msginfunc_disc(struct scsi_low_softc *slp) -{ - SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_DISC); - return 0; -} - -static int -scsi_low_msginfunc_sdp(struct scsi_low_softc *slp) -{ - struct slccb *cb = slp->sl_Qnexus; - - if (cb != NULL) - { - cb->ccb_sscp.scp_datalen = slp->sl_scp.scp_datalen; - cb->ccb_sscp.scp_data = slp->sl_scp.scp_data; - } - else - scsi_low_assert_msg(slp, slp->sl_Tnexus, SCSI_LOW_MSG_REJECT, 0); - return 0; -} - -static int -scsi_low_msginfunc_rp(struct scsi_low_softc *slp) -{ - if (slp->sl_Qnexus != NULL) - slp->sl_scp = slp->sl_Qnexus->ccb_sscp; - else - scsi_low_assert_msg(slp, slp->sl_Tnexus, SCSI_LOW_MSG_REJECT, 0); - return 0; -} - -static int -scsi_low_synch(struct scsi_low_softc *slp) -{ - struct targ_info *ti = slp->sl_Tnexus; - u_int period = 0, offset = 0, speed; - u_char *s; - int error; - - if ((MSGIN_PERIOD(ti) >= ti->ti_maxsynch.period && - MSGIN_OFFSET(ti) <= ti->ti_maxsynch.offset) || - MSGIN_OFFSET(ti) == 0) - { - if ((offset = MSGIN_OFFSET(ti)) != 0) - period = MSGIN_PERIOD(ti); - s = offset ? "synchronous" : "async"; - } - else - { - /* XXX: - * Target seems to be brain damaged. - * Force async transfer. - */ - ti->ti_maxsynch.period = 0; - ti->ti_maxsynch.offset = 0; - kprintf("%s: target brain damaged. async transfer\n", - slp->sl_xname); - return EINVAL; - } - - ti->ti_maxsynch.period = period; - ti->ti_maxsynch.offset = offset; - - error = (*slp->sl_funcs->scsi_low_msg) (slp, ti, SCSI_LOW_MSG_SYNCH); - if (error != 0) - { - /* XXX: - * Current period and offset are not acceptable - * for our adapter. - * The adapter changes max synch and max offset. - */ - kprintf("%s: synch neg failed. retry synch msg neg ...\n", - slp->sl_xname); - return error; - } - - ti->ti_osynch = ti->ti_maxsynch; - if (offset > 0) - { - ti->ti_setup_msg_done |= SCSI_LOW_MSG_SYNCH; - } - - /* inform data */ - if ((slp->sl_show_result & SHOW_SYNCH_NEG) != 0) - { -#ifdef SCSI_LOW_NEGOTIATE_BEFORE_SENSE - struct slccb *cb = slp->sl_Qnexus; - - if (cb != NULL && (cb->ccb_flags & CCB_SENSE) != 0) - return 0; -#endif /* SCSI_LOW_NEGOTIATE_BEFORE_SENSE */ - - kprintf("%s(%d:*): <%s> offset %d period %dns ", - slp->sl_xname, ti->ti_id, s, offset, period * 4); - - if (period != 0) - { - speed = 1000 * 10 / (period * 4); - kprintf("%d.%d M/s", speed / 10, speed % 10); - } - kprintf("\n"); - } - return 0; -} - -static int -scsi_low_wide(struct scsi_low_softc *slp) -{ - struct targ_info *ti = slp->sl_Tnexus; - int error; - - ti->ti_width = MSGIN_WIDTHP(ti); - error = (*slp->sl_funcs->scsi_low_msg) (slp, ti, SCSI_LOW_MSG_WIDE); - if (error != 0) - { - /* XXX: - * Current width is not acceptable for our adapter. - * The adapter changes max width. - */ - kprintf("%s: wide neg failed. retry wide msg neg ...\n", - slp->sl_xname); - return error; - } - - ti->ti_owidth = ti->ti_width; - if (ti->ti_width > SCSI_LOW_BUS_WIDTH_8) - { - ti->ti_setup_msg_done |= - (SCSI_LOW_MSG_SYNCH | SCSI_LOW_MSG_WIDE); - } - - /* inform data */ - if ((slp->sl_show_result & SHOW_WIDE_NEG) != 0) - { -#ifdef SCSI_LOW_NEGOTIATE_BEFORE_SENSE - struct slccb *cb = slp->sl_Qnexus; - - if (cb != NULL && (cb->ccb_flags & CCB_SENSE) != 0) - return 0; -#endif /* SCSI_LOW_NEGOTIATE_BEFORE_SENSE */ - - kprintf("%s(%d:*): transfer width %d bits\n", - slp->sl_xname, ti->ti_id, 1 << (3 + ti->ti_width)); - } - return 0; -} - -static int -scsi_low_msginfunc_simple_qtag(struct scsi_low_softc *slp) -{ - struct targ_info *ti = slp->sl_Tnexus; - scsi_low_tag_t etag = (scsi_low_tag_t) ti->ti_msgin[1]; - - if (slp->sl_Qnexus != NULL) - { - if (slp->sl_Qnexus->ccb_tag != etag) - { - slp->sl_error |= FATALIO; - scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0); - SCSI_LOW_INFO(slp, ti, "MSGIN: qtag mismatch"); - } - } - else if (scsi_low_establish_ccb(ti, slp->sl_Lnexus, etag) == NULL) - { -#ifdef SCSI_LOW_DEBUG - if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_NEXUS_CHECK, ti->ti_id)) - return 0; -#endif /* SCSI_LOW_DEBUG */ - - slp->sl_error |= FATALIO; - scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT_QTAG, 0); - SCSI_LOW_INFO(slp, ti, "MSGIN: taged ccb not found"); - } - return 0; -} - -static int -scsi_low_msginfunc_i_wide_residue(struct scsi_low_softc *slp) -{ - struct targ_info *ti = slp->sl_Tnexus; - struct slccb *cb = slp->sl_Qnexus; - int res = (int) ti->ti_msgin[1]; - - if (cb == NULL || res <= 0 || - (ti->ti_width == SCSI_LOW_BUS_WIDTH_16 && res > 1) || - (ti->ti_width == SCSI_LOW_BUS_WIDTH_32 && res > 3)) - return EINVAL; - - if (slp->sl_scp.scp_datalen + res > cb->ccb_scp.scp_datalen) - return EINVAL; - - slp->sl_scp.scp_datalen += res; - slp->sl_scp.scp_data -= res; - scsi_low_data_finish(slp); - return 0; -} - -static int -scsi_low_msginfunc_ext(struct scsi_low_softc *slp) -{ - struct slccb *cb = slp->sl_Qnexus; - struct lun_info *li = slp->sl_Lnexus; - struct targ_info *ti = slp->sl_Tnexus; - int count, retry; - u_int32_t *ptr; - - if (ti->ti_msginptr == 2) - { - ti->ti_msginlen = ti->ti_msgin[1] + 2; - return 0; - } - - switch (MKMSG_EXTEND(ti->ti_msgin[1], ti->ti_msgin[2])) - { - case MKMSG_EXTEND(MSG_EXTEND_MDPLEN, MSG_EXTEND_MDPCODE): - if (cb == NULL) - break; - - ptr = (u_int32_t *)(&ti->ti_msgin[3]); - count = (int) htonl((long) (*ptr)); - if(slp->sl_scp.scp_datalen - count < 0 || - slp->sl_scp.scp_datalen - count > cb->ccb_scp.scp_datalen) - break; - - slp->sl_scp.scp_datalen -= count; - slp->sl_scp.scp_data += count; - return 0; - - case MKMSG_EXTEND(MSG_EXTEND_SYNCHLEN, MSG_EXTEND_SYNCHCODE): - if (li == NULL) - break; - - retry = scsi_low_synch(slp); - if (retry != 0 || (ti->ti_emsgflags & SCSI_LOW_MSG_SYNCH) == 0) - scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_SYNCH, 0); - -#ifdef SCSI_LOW_DEBUG - if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_ATTEN_CHECK, ti->ti_id)) - { - scsi_low_test_atten(slp, ti, SCSI_LOW_MSG_SYNCH); - } -#endif /* SCSI_LOW_DEBUG */ - return 0; - - case MKMSG_EXTEND(MSG_EXTEND_WIDELEN, MSG_EXTEND_WIDECODE): - if (li == NULL) - break; - - retry = scsi_low_wide(slp); - if (retry != 0 || (ti->ti_emsgflags & SCSI_LOW_MSG_WIDE) == 0) - scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_WIDE, 0); - - return 0; - - default: - break; - } - - scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0); - return EINVAL; -} - -static int -scsi_low_msginfunc_parity(struct scsi_low_softc *slp) -{ - struct targ_info *ti = slp->sl_Tnexus; - - /* only I -> T, invalid! */ - scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0); - return 0; -} - -static int -scsi_low_msginfunc_msg_reject(struct scsi_low_softc *slp) -{ - struct targ_info *ti = slp->sl_Tnexus; - struct scsi_low_msgout_data *mdp; - u_int msgflags; - - if (ti->ti_emsgflags != 0) - { - kprintf("%s: msg flags [0x%x] rejected\n", - slp->sl_xname, ti->ti_emsgflags); - msgflags = SCSI_LOW_MSG_REJECT; - mdp = &scsi_low_msgout_data[0]; - for ( ; mdp->md_flags != SCSI_LOW_MSG_ALL; mdp ++) - { - if ((ti->ti_emsgflags & mdp->md_flags) != 0) - { - ti->ti_emsgflags &= ~mdp->md_flags; - if (mdp->md_errfunc != NULL) - (*mdp->md_errfunc) (slp, msgflags); - break; - } - } - return 0; - } - else - { - SCSI_LOW_INFO(slp, ti, "MSGIN: rejected msg not found"); - slp->sl_error |= MSGERR; - } - return EINVAL; -} - -int -scsi_low_msgin(struct scsi_low_softc *slp, struct targ_info *ti, u_int c) -{ - struct scsi_low_msgin_data *sdp; - struct lun_info *li; - u_int8_t msg; - -#ifdef SCSI_LOW_DIAGNOSTIC - if (ti != slp->sl_Tnexus) - { - scsi_low_print(slp, NULL); - panic("scsi_low_msgin: Target nexus inconsistent"); - } -#endif /* SCSI_LOW_DIAGNOSTIC */ - - /* - * Phase changes, clear the pointer. - */ - if (ti->ti_ophase != ti->ti_phase) - { - MSGINPTR_CLR(ti); - ti->ti_msgin_parity_error = 0; - - slp->sl_ph_count ++; - if (slp->sl_ph_count > SCSI_LOW_MAX_PHCHANGES) - { - kprintf("%s: too many phase changes\n", slp->sl_xname); - slp->sl_error |= FATALIO; - scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0); - } - } - - /* - * Store a current messages byte into buffer and - * wait for the completion of the current msg. - */ - ti->ti_msgin[ti->ti_msginptr ++] = (u_int8_t) c; - if (ti->ti_msginptr >= SCSI_LOW_MAX_MSGLEN) - { - ti->ti_msginptr = SCSI_LOW_MAX_MSGLEN - 1; - scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0); - } - - /* - * Check parity errors. - */ - if ((c & SCSI_LOW_DATA_PE) != 0) - { - ti->ti_msgin_parity_error ++; - scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_PARITY, 0); - goto out; - } - - if (ti->ti_msgin_parity_error != 0) - goto out; - - /* - * Calculate messages length. - */ - msg = ti->ti_msgin[0]; - if (msg < MSGIN_DATA_LAST) - sdp = &scsi_low_msgin_data[msg]; - else - sdp = &scsi_low_msgin_data[MSGIN_DATA_LAST]; - - if (ti->ti_msginlen == 0) - { - ti->ti_msginlen = sdp->md_len; - } - - /* - * Check comletion. - */ - if (ti->ti_msginptr < ti->ti_msginlen) - return EJUSTRETURN; - - /* - * Do process. - */ - if ((msg & MSG_IDENTIFY) == 0) - { - if (((*sdp->md_msgfunc) (slp)) == EJUSTRETURN) - return EJUSTRETURN; - } - else - { - li = slp->sl_Lnexus; - if (li == NULL) - { - li = scsi_low_alloc_li(ti, MSGCMD_LUN(msg), 0); - if (li == NULL) - goto badlun; - slp->sl_Lnexus = li; - (*slp->sl_funcs->scsi_low_establish_lun_nexus) (slp); - } - else - { - if (MSGCMD_LUN(msg) != li->li_lun) - goto badlun; - } - - if (slp->sl_Qnexus == NULL && li->li_nqio == 0) - { - if (!scsi_low_establish_ccb(ti, li, SCSI_LOW_UNKTAG)) - { -#ifdef SCSI_LOW_DEBUG - if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_NEXUS_CHECK, ti->ti_id) != 0) - { - goto out; - } -#endif /* SCSI_LOW_DEBUG */ - goto badlun; - } - } - } - goto out; - - /* - * Msg process completed, reset msgin pointer and assert ATN if desired. - */ -badlun: - slp->sl_error |= FATALIO; - scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0); - SCSI_LOW_INFO(slp, ti, "MSGIN: identify wrong"); - -out: - if (ti->ti_msginptr < ti->ti_msginlen) - return EJUSTRETURN; - -#ifdef SCSI_LOW_DIAGNOSTIC - scsi_low_msg_log_write(&ti->ti_log_msgin, - &ti->ti_msgin[0], ti->ti_msginlen); -#endif /* SCSI_LOW_DIAGNOSTIC */ - - MSGINPTR_CLR(ti); - return 0; -} - -/********************************************************** - * disconnect - **********************************************************/ -int -scsi_low_disconnected(struct scsi_low_softc *slp, struct targ_info *ti) -{ - struct slccb *cb = slp->sl_Qnexus; - - /* check phase completion */ - switch (slp->sl_msgphase) - { - case MSGPH_RESET: - scsi_low_statusin(slp, slp->sl_Tnexus, ST_GOOD); - scsi_low_msginfunc_cc(slp); - scsi_low_reset_nexus_target(slp, slp->sl_Tnexus, 0); - goto io_resume; - - case MSGPH_ABORT: - scsi_low_statusin(slp, slp->sl_Tnexus, ST_GOOD); - scsi_low_msginfunc_cc(slp); - scsi_low_reset_nexus_lun(slp, slp->sl_Lnexus, 0); - goto io_resume; - - case MSGPH_TERM: - scsi_low_statusin(slp, slp->sl_Tnexus, ST_GOOD); - scsi_low_msginfunc_cc(slp); - goto io_resume; - - case MSGPH_DISC: - if (cb != NULL) - { - struct lun_info *li; - - li = cb->li; - TAILQ_INSERT_TAIL(&li->li_discq, cb, ccb_chain); - cb->ccb_flags |= CCB_DISCQ; - cb->ccb_error |= slp->sl_error; - li->li_disc ++; - ti->ti_disc ++; - slp->sl_disc ++; - } - -#ifdef SCSI_LOW_STATICS - scsi_low_statics.nexus_disconnected ++; -#endif /* SCSI_LOW_STATICS */ - -#ifdef SCSI_LOW_DEBUG - if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_DISC, ti->ti_id) != 0) - { - kprintf("## SCSI_LOW_DISCONNECTED ===============\n"); - scsi_low_print(slp, NULL); - } -#endif /* SCSI_LOW_DEBUG */ - break; - - case MSGPH_NULL: - slp->sl_error |= FATALIO; - if (ti->ti_phase == PH_SELSTART) - slp->sl_error |= SELTIMEOUTIO; - else - slp->sl_error |= UBFERR; - /* fall through */ - - case MSGPH_LCTERM: - case MSGPH_CMDC: -io_resume: - if (cb == NULL) - break; - -#ifdef SCSI_LOW_DEBUG - if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_ATTEN_CHECK, ti->ti_id)) - { - if (cb->ccb_omsgoutflag == SCSI_LOW_MSG_NOOP && - (cb->ccb_msgoutflag != 0 || - (ti->ti_msgflags & SCSI_LOW_MSG_NOOP))) - { - scsi_low_info(slp, ti, "ATTEN CHECK FAILED"); - } - } -#endif /* SCSI_LOW_DEBUG */ - - cb->ccb_error |= slp->sl_error; - if (scsi_low_done(slp, cb) == SCSI_LOW_DONE_RETRY) - { - cb->ccb_flags |= CCB_STARTQ; - TAILQ_INSERT_HEAD(&slp->sl_start, cb, ccb_chain); - } - break; - } - - scsi_low_bus_release(slp, ti); - scsi_low_start(slp); - return 1; -} - -/********************************************************** - * TAG operations - **********************************************************/ -static int -scsi_low_alloc_qtag(struct slccb *cb) -{ - struct lun_info *li = cb->li; - scsi_low_tag_t etag; - - if (cb->ccb_otag != SCSI_LOW_UNKTAG) - return 0; - -#ifndef SCSI_LOW_ALT_QTAG_ALLOCATE - etag = ffs(li->li_qtagbits); - if (etag == 0) - return ENOSPC; - - li->li_qtagbits &= ~(1 << (etag - 1)); - cb->ccb_otag = etag; - return 0; - -#else /* SCSI_LOW_ALT_QTAG_ALLOCATE */ - for (etag = li->li_qd ; li->li_qd < SCSI_LOW_MAXNEXUS; li->li_qd ++) - if (li->li_qtagarray[li->li_qd] == 0) - goto found; - - for (li->li_qd = 0; li->li_qd < etag; li->li_qd ++) - if (li->li_qtagarray[li->li_qd] == 0) - goto found; - - return ENOSPC; - -found: - li->li_qtagarray[li->li_qd] ++; - cb->ccb_otag = (li->li_qd ++); - return 0; -#endif /* SCSI_LOW_ALT_QTAG_ALLOCATE */ -} - -static int -scsi_low_dealloc_qtag(struct slccb *cb) -{ - struct lun_info *li = cb->li; - scsi_low_tag_t etag; - - if (cb->ccb_otag == SCSI_LOW_UNKTAG) - return 0; - -#ifndef SCSI_LOW_ALT_QTAG_ALLOCATE - etag = cb->ccb_otag - 1; -#ifdef SCSI_LOW_DIAGNOSTIC - if (etag >= sizeof(li->li_qtagbits) * NBBY) - panic("scsi_low_dealloc_tag: illegal tag"); -#endif /* SCSI_LOW_DIAGNOSTIC */ - li->li_qtagbits |= (1 << etag); - -#else /* SCSI_LOW_ALT_QTAG_ALLOCATE */ - etag = cb->ccb_otag; -#ifdef SCSI_LOW_DIAGNOSTIC - if (etag >= SCSI_LOW_MAXNEXUS) - panic("scsi_low_dealloc_tag: illegal tag"); -#endif /* SCSI_LOW_DIAGNOSTIC */ - li->li_qtagarray[etag] --; -#endif /* SCSI_LOW_ALT_QTAG_ALLOCATE */ - - cb->ccb_otag = SCSI_LOW_UNKTAG; - return 0; -} - -static struct slccb * -scsi_low_revoke_ccb(struct scsi_low_softc *slp, struct slccb *cb, int fdone) -{ - struct targ_info *ti = cb->ti; - struct lun_info *li = cb->li; - -#ifdef SCSI_LOW_DIAGNOSTIC - if ((cb->ccb_flags & (CCB_STARTQ | CCB_DISCQ)) == - (CCB_STARTQ | CCB_DISCQ)) - { - panic("%s: ccb in both queue", slp->sl_xname); - } -#endif /* SCSI_LOW_DIAGNOSTIC */ - - if ((cb->ccb_flags & CCB_STARTQ) != 0) - { - TAILQ_REMOVE(&slp->sl_start, cb, ccb_chain); - } - - if ((cb->ccb_flags & CCB_DISCQ) != 0) - { - TAILQ_REMOVE(&li->li_discq, cb, ccb_chain); - li->li_disc --; - ti->ti_disc --; - slp->sl_disc --; - } - - cb->ccb_flags &= ~(CCB_STARTQ | CCB_DISCQ | - CCB_SENSE | CCB_CLEARQ | CCB_INTERNAL); - - if (fdone != 0 && - (cb->ccb_rcnt ++ >= slp->sl_max_retry || - (cb->ccb_flags & CCB_NORETRY) != 0)) - { - cb->ccb_error |= FATALIO; - cb->ccb_flags &= ~CCB_AUTOSENSE; - if (scsi_low_done(slp, cb) != SCSI_LOW_DONE_COMPLETE) - panic("%s: done ccb retried", slp->sl_xname); - return NULL; - } - else - { - cb->ccb_error |= PENDINGIO; - scsi_low_deactivate_qtag(cb); - scsi_low_ccb_message_retry(cb); - cb->ccb_tc = cb->ccb_tcmax = SCSI_LOW_MIN_TOUT; - return cb; - } -} - -static void -scsi_low_reset_nexus_lun(struct scsi_low_softc *slp, struct lun_info *li, int fdone) -{ - struct slccb *cb, *ncb, *ecb; - - if (li == NULL) - return; - - ecb = NULL; - for (cb = TAILQ_FIRST(&li->li_discq); cb != NULL; cb = ncb) - { - ncb = TAILQ_NEXT(cb, ccb_chain); - cb = scsi_low_revoke_ccb(slp, cb, fdone); - if (cb != NULL) - { - /* - * presumely keep ordering of io - */ - cb->ccb_flags |= CCB_STARTQ; - if (ecb == NULL) - { - TAILQ_INSERT_HEAD(&slp->sl_start,\ - cb, ccb_chain); - } - else - { - TAILQ_INSERT_AFTER(&slp->sl_start,\ - ecb, cb, ccb_chain); - } - ecb = cb; - } - } -} - -/************************************************************** - * Qurik setup - **************************************************************/ -static void -scsi_low_calcf_lun(struct lun_info *li) -{ - struct targ_info *ti = li->li_ti; - struct scsi_low_softc *slp = ti->ti_sc; - u_int cfgflags, diskflags; - - if (li->li_flags_valid == SCSI_LOW_LUN_FLAGS_ALL_VALID) - cfgflags = li->li_cfgflags; - else - cfgflags = 0; - - diskflags = li->li_diskflags & li->li_quirks; - - /* disconnect */ - li->li_flags &= ~SCSI_LOW_DISC; - if ((slp->sl_cfgflags & CFG_NODISC) == 0 && - (diskflags & SCSI_LOW_DISK_DISC) != 0 && - (cfgflags & SCSI_LOW_DISC) != 0) - li->li_flags |= SCSI_LOW_DISC; - - /* parity */ - li->li_flags |= SCSI_LOW_NOPARITY; - if ((slp->sl_cfgflags & CFG_NOPARITY) == 0 && - (diskflags & SCSI_LOW_DISK_PARITY) != 0 && - (cfgflags & SCSI_LOW_NOPARITY) == 0) - li->li_flags &= ~SCSI_LOW_NOPARITY; - - /* qtag */ - if ((slp->sl_cfgflags & CFG_NOQTAG) == 0 && - (cfgflags & SCSI_LOW_QTAG) != 0 && - (diskflags & SCSI_LOW_DISK_QTAG) != 0) - { - li->li_flags |= SCSI_LOW_QTAG; - li->li_maxnexus = SCSI_LOW_MAXNEXUS; - li->li_maxnqio = li->li_maxnexus; - } - else - { - li->li_flags &= ~SCSI_LOW_QTAG; - li->li_maxnexus = 0; - li->li_maxnqio = li->li_maxnexus; - } - - /* cmd link */ - li->li_flags &= ~SCSI_LOW_LINK; - if ((cfgflags & SCSI_LOW_LINK) != 0 && - (diskflags & SCSI_LOW_DISK_LINK) != 0) - li->li_flags |= SCSI_LOW_LINK; - - /* compatible flags */ - li->li_flags &= ~SCSI_LOW_SYNC; - if (ti->ti_maxsynch.offset > 0) - li->li_flags |= SCSI_LOW_SYNC; - -#ifdef SCSI_LOW_DEBUG - if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_CALCF, ti->ti_id) != 0) - { - scsi_low_calcf_show(li); - } -#endif /* SCSI_LOW_DEBUG */ -} - -static void -scsi_low_calcf_target(struct targ_info *ti) -{ - struct scsi_low_softc *slp = ti->ti_sc; - u_int offset, period, diskflags; - - diskflags = ti->ti_diskflags & ti->ti_quirks; - - /* synch */ - if ((slp->sl_cfgflags & CFG_ASYNC) == 0 && - (diskflags & SCSI_LOW_DISK_SYNC) != 0) - { - offset = ti->ti_maxsynch.offset; - period = ti->ti_maxsynch.period; - if (offset == 0 || period == 0) - offset = period = 0; - } - else - { - offset = period = 0; - } - - ti->ti_maxsynch.offset = offset; - ti->ti_maxsynch.period = period; - - /* wide */ - if ((diskflags & SCSI_LOW_DISK_WIDE_32) == 0 && - ti->ti_width > SCSI_LOW_BUS_WIDTH_16) - ti->ti_width = SCSI_LOW_BUS_WIDTH_16; - - if ((diskflags & SCSI_LOW_DISK_WIDE_16) == 0 && - ti->ti_width > SCSI_LOW_BUS_WIDTH_8) - ti->ti_width = SCSI_LOW_BUS_WIDTH_8; - - if (ti->ti_flags_valid == SCSI_LOW_TARG_FLAGS_ALL_VALID) - { - if (ti->ti_maxsynch.offset != ti->ti_osynch.offset || - ti->ti_maxsynch.period != ti->ti_osynch.period) - ti->ti_setup_msg |= SCSI_LOW_MSG_SYNCH; - if (ti->ti_width != ti->ti_owidth) - ti->ti_setup_msg |= (SCSI_LOW_MSG_WIDE | SCSI_LOW_MSG_SYNCH); - - ti->ti_osynch = ti->ti_maxsynch; - ti->ti_owidth = ti->ti_width; - } - -#ifdef SCSI_LOW_DEBUG - if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_CALCF, ti->ti_id) != 0) - { - kprintf("%s(%d:*): max period(%dns) offset(%d) width(%d)\n", - slp->sl_xname, ti->ti_id, - ti->ti_maxsynch.period * 4, - ti->ti_maxsynch.offset, - ti->ti_width); - } -#endif /* SCSI_LOW_DEBUG */ -} - -static void -scsi_low_calcf_show(struct lun_info *li) -{ - struct targ_info *ti = li->li_ti; - struct scsi_low_softc *slp = ti->ti_sc; - - kprintf("%s(%d:%d): period(%d ns) offset(%d) width(%d) flags 0x%b\n", - slp->sl_xname, ti->ti_id, li->li_lun, - ti->ti_maxsynch.period * 4, - ti->ti_maxsynch.offset, - ti->ti_width, - li->li_flags, SCSI_LOW_BITS); -} - -#ifdef SCSI_LOW_START_UP_CHECK -/************************************************************** - * scsi world start up - **************************************************************/ -static int scsi_low_poll (struct scsi_low_softc *, struct slccb *); - -static int -scsi_low_start_up(struct scsi_low_softc *slp) -{ - struct targ_info *ti; - struct lun_info *li; - struct slccb *cb; - int target, lun; - - kprintf("%s: scsi_low: probing all devices ....\n", slp->sl_xname); - - for (target = 0; target < slp->sl_ntargs; target ++) - { - if (target == slp->sl_hostid) - { - if ((slp->sl_show_result & SHOW_PROBE_RES) != 0) - { - kprintf("%s: scsi_low: target %d (host card)\n", - slp->sl_xname, target); - } - continue; - } - - if ((slp->sl_show_result & SHOW_PROBE_RES) != 0) - { - kprintf("%s: scsi_low: target %d lun ", - slp->sl_xname, target); - } - - ti = slp->sl_ti[target]; - for (lun = 0; lun < slp->sl_nluns; lun ++) - { - if ((cb = SCSI_LOW_ALLOC_CCB(1)) == NULL) - break; - - cb->osdep = NULL; - cb->bp = NULL; - - li = scsi_low_alloc_li(ti, lun, 1); - - scsi_low_enqueue(slp, ti, li, cb, - CCB_AUTOSENSE | CCB_POLLED, 0); - - scsi_low_poll(slp, cb); - - if (li->li_state != SCSI_LOW_LUN_OK) - break; - - if ((slp->sl_show_result & SHOW_PROBE_RES) != 0) - { - kprintf("%d ", lun); - } - } - - if ((slp->sl_show_result & SHOW_PROBE_RES) != 0) - { - kprintf("\n"); - } - } - return 0; -} - -static int -scsi_low_poll(struct scsi_low_softc *slp, struct slccb *cb) -{ - int tcount; - - tcount = 0; - while (slp->sl_nio > 0) - { - SCSI_LOW_DELAY((1000 * 1000) / SCSI_LOW_POLL_HZ); - - (*slp->sl_funcs->scsi_low_poll) (slp); - if (tcount ++ < SCSI_LOW_POLL_HZ / SCSI_LOW_TIMEOUT_HZ) - continue; - - tcount = 0; - scsi_low_timeout_check(slp); - } - - return 0; -} -#endif /* SCSI_LOW_START_UP_CHECK */ - -/********************************************************** - * DEBUG SECTION - **********************************************************/ -#ifdef SCSI_LOW_DEBUG -static void -scsi_low_test_abort(struct scsi_low_softc *slp, struct targ_info *ti, - struct lun_info *li) -{ - struct slccb *acb; - - if (li->li_disc > 1) - { - acb = TAILQ_FIRST(&li->li_discq); - if (scsi_low_abort_ccb(slp, acb) == 0) - { - kprintf("%s: aborting ccb(0x%lx) start\n", - slp->sl_xname, (u_long) acb); - } - } -} - -static void -scsi_low_test_atten(struct scsi_low_softc *slp, struct targ_info *ti, u_int msg) -{ - if (slp->sl_ph_count < SCSI_LOW_MAX_ATTEN_CHECK) - scsi_low_assert_msg(slp, ti, msg, 0); - else - kprintf("%s: atten check OK\n", slp->sl_xname); -} - -static void -scsi_low_test_cmdlnk(struct scsi_low_softc *slp, struct slccb *cb) -{ -#define SCSI_LOW_CMDLNK_NOK (CCB_INTERNAL | CCB_SENSE | CCB_CLEARQ) - - if ((cb->ccb_flags & SCSI_LOW_CMDLNK_NOK) != 0) - return; - - memcpy(cb->ccb_scsi_cmd, slp->sl_scp.scp_cmd, - slp->sl_scp.scp_cmdlen); - cb->ccb_scsi_cmd[slp->sl_scp.scp_cmdlen - 1] |= 1; - slp->sl_scp.scp_cmd = cb->ccb_scsi_cmd; -} -#endif /* SCSI_LOW_DEBUG */ - -/* static */ void -scsi_low_info(struct scsi_low_softc *slp, struct targ_info *ti, u_char *s) -{ - if (slp == NULL) - slp = LIST_FIRST(&sl_tab); - if (s == NULL) - s = "no message"; - - kprintf(">>>>> SCSI_LOW_INFO(0x%lx): %s\n", (u_long) slp->sl_Tnexus, s); - if (ti == NULL) - { - TAILQ_FOREACH(ti, &slp->sl_titab, ti_chain) - { - scsi_low_print(slp, ti); - } - } - else - { - scsi_low_print(slp, ti); - } -} - -static u_char *phase[] = -{ - "FREE", "ARBSTART", "SELSTART", "SELECTED", - "CMDOUT", "DATA", "MSGIN", "MSGOUT", "STATIN", "DISC", "RESEL" -}; - -void -scsi_low_print(struct scsi_low_softc *slp, struct targ_info *ti) -{ - struct lun_info *li; - struct slccb *cb; - struct sc_p *sp; - - if (ti == NULL || ti == slp->sl_Tnexus) - { - ti = slp->sl_Tnexus; - li = slp->sl_Lnexus; - cb = slp->sl_Qnexus; - } - else - { - li = LIST_FIRST(&ti->ti_litab); - cb = TAILQ_FIRST(&li->li_discq); - } - sp = &slp->sl_scp; - - kprintf("%s: === NEXUS T(0x%lx) L(0x%lx) Q(0x%lx) NIO(%d) ===\n", - slp->sl_xname, (u_long) ti, (u_long) li, (u_long) cb, - slp->sl_nio); - - /* target stat */ - if (ti != NULL) - { - u_int flags = 0, maxnqio = 0, nqio = 0; - int lun = -1; - - if (li != NULL) - { - lun = li->li_lun; - flags = li->li_flags; - maxnqio = li->li_maxnqio; - nqio = li->li_nqio; - } - - kprintf("%s(%d:%d) ph<%s> => ph<%s> DISC(%d) QIO(%d:%d)\n", - slp->sl_xname, - ti->ti_id, lun, phase[(int) ti->ti_ophase], - phase[(int) ti->ti_phase], ti->ti_disc, - nqio, maxnqio); - - if (cb != NULL) - { -kprintf("CCB: cmd[0] 0x%x clen 0x%x dlen 0x%x<0x%x stat 0x%x err %b\n", - (u_int) cb->ccb_scp.scp_cmd[0], - cb->ccb_scp.scp_cmdlen, - cb->ccb_datalen, - cb->ccb_scp.scp_datalen, - (u_int) cb->ccb_sscp.scp_status, - cb->ccb_error, SCSI_LOW_ERRORBITS); - } - -kprintf("MSGIN: ptr(%x) [%x][%x][%x][%x][%x] attention: %d\n", - (u_int) (ti->ti_msginptr), - (u_int) (ti->ti_msgin[0]), - (u_int) (ti->ti_msgin[1]), - (u_int) (ti->ti_msgin[2]), - (u_int) (ti->ti_msgin[3]), - (u_int) (ti->ti_msgin[4]), - slp->sl_atten); - -kprintf("MSGOUT: msgflags 0x%x [%x][%x][%x][%x][%x] msgoutlen %d C_FLAGS: %b\n", - (u_int) ti->ti_msgflags, - (u_int) (ti->ti_msgoutstr[0]), - (u_int) (ti->ti_msgoutstr[1]), - (u_int) (ti->ti_msgoutstr[2]), - (u_int) (ti->ti_msgoutstr[3]), - (u_int) (ti->ti_msgoutstr[4]), - ti->ti_msgoutlen, - flags, SCSI_LOW_BITS); - -#ifdef SCSI_LOW_DIAGNOSTIC - scsi_low_msg_log_show(&ti->ti_log_msgin, "MIN LOG ", 2); - scsi_low_msg_log_show(&ti->ti_log_msgout, "MOUT LOG", 2); -#endif /* SCSI_LOW_DIAGNOSTIC */ - - } - - kprintf("SCB: daddr 0x%lx dlen 0x%x stat 0x%x err %b\n", - (u_long) sp->scp_data, - sp->scp_datalen, - (u_int) sp->scp_status, - slp->sl_error, SCSI_LOW_ERRORBITS); -} diff --git a/sys/bus/cam/scsi/scsi_low.h b/sys/bus/cam/scsi/scsi_low.h deleted file mode 100644 index d486eafa74..0000000000 --- a/sys/bus/cam/scsi/scsi_low.h +++ /dev/null @@ -1,808 +0,0 @@ -/* $FreeBSD: src/sys/cam/scsi/scsi_low.h,v 1.1.2.4 2001/07/22 00:21:41 non Exp $ */ -/* $NecBSD: scsi_low.h,v 1.24.10.5 2001/06/26 07:31:46 honda Exp $ */ -/* $NetBSD$ */ - -#define SCSI_LOW_DIAGNOSTIC -#define SCSI_LOW_ALT_QTAG_ALLOCATE - -/* - * [NetBSD for NEC PC-98 series] - * Copyright (c) 1995, 1996, 1997, 1998, 1999, 2000, 2001 - * NetBSD/pc98 porting staff. All rights reserved. - * Copyright (c) 1995, 1996, 1997, 1998, 1999, 2000, 2001 - * Naofumi HONDA. All rights reserved. - * - * [Ported for FreeBSD CAM] - * Copyright (c) 2000, 2001 - * MITSUNAGA Noriaki, NOKUBI Hirotaka and TAKAHASHI Yoshihiro. - * All rights reserved. - * - * 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. - */ - -#ifndef _SCSI_LOW_H_ -#define _SCSI_LOW_H_ - -#define SCSI_LOW_INTERFACE_CAM - -#include -#include -#include -#include -#include -#include -#include - -#include "scsi_dvcfg.h" - -#undef MSG_IDENTIFY -#define SCSI_LOW_DEBUGGER(dev) Debugger((dev)) -#define SCSI_LOW_DELAY(mu) DELAY((mu)) -#define SCSI_LOW_BZERO(pt, size) bzero((pt), (size)) - -typedef struct scsi_sense_data scsi_low_osdep_sense_data_t; - -struct scsi_low_osdep_interface { - DEVPORT_DEVICE si_dev; - - struct cam_sim *sim; - struct cam_path *path; - - int si_poll_count; - - struct callout engage_ch; - struct callout timeout_ch; -}; - -struct scsi_low_osdep_targ_interface { -}; - -struct scsi_low_osdep_lun_interface { -}; - -/******** os depend interface functions *************/ -struct slccb; -struct scsi_low_softc; -#define SCSI_LOW_TIMEOUT_STOP 0 -#define SCSI_LOW_TIMEOUT_START 1 -#define SCSI_LOW_TIMEOUT_CH_IO 0 -#define SCSI_LOW_TIMEOUT_CH_ENGAGE 1 -#define SCSI_LOW_TIMEOUT_CH_RECOVER 2 - -struct scsi_low_osdep_funcs { - int (*scsi_low_osdep_attach) \ - (struct scsi_low_softc *); - int (*scsi_low_osdep_world_start) \ - (struct scsi_low_softc *); - int (*scsi_low_osdep_dettach) \ - (struct scsi_low_softc *); - int (*scsi_low_osdep_ccb_setup) \ - (struct scsi_low_softc *, struct slccb *); - int (*scsi_low_osdep_done) \ - (struct scsi_low_softc *, struct slccb *); - void (*scsi_low_osdep_timeout) \ - (struct scsi_low_softc *, int, int); -}; - -/*================================================ - * Generic Scsi Low header file - * (All os depend structures should be above!) - ================================================*/ -/************************************************* - * Scsi low definitions - *************************************************/ -#define SCSI_LOW_SYNC DVF_SCSI_SYNC -#define SCSI_LOW_DISC DVF_SCSI_DISC -#define SCSI_LOW_WAIT DVF_SCSI_WAIT -#define SCSI_LOW_LINK DVF_SCSI_LINK -#define SCSI_LOW_QTAG DVF_SCSI_QTAG -#define SCSI_LOW_NOPARITY DVF_SCSI_NOPARITY -#define SCSI_LOW_SAVESP DVF_SCSI_SAVESP -#define SCSI_LOW_DEFCFG DVF_SCSI_DEFCFG -#define SCSI_LOW_BITS DVF_SCSI_BITS - -#define SCSI_LOW_PERIOD(n) DVF_SCSI_PERIOD(n) -#define SCSI_LOW_OFFSET(n) DVF_SCSI_OFFSET(n) - -/* host scsi id and targets macro */ -#ifndef SCSI_LOW_NTARGETS -#define SCSI_LOW_NTARGETS 8 -#endif /* SCSI_LOW_NTARGETS */ -#define SCSI_LOW_NCCB 128 - -#define SCSI_LOW_MAX_RETRY 3 -#define SCSI_LOW_MAX_SELECTION_RETRY 10 - -/* timeout control macro */ -#define SCSI_LOW_TIMEOUT_HZ 10 -#define SCSI_LOW_MIN_TOUT 12 -#define SCSI_LOW_TIMEOUT_CHECK_INTERVAL 1 -#define SCSI_LOW_POWDOWN_TC 15 -#define SCSI_LOW_MAX_PHCHANGES 256 -#define SCSI2_RESET_DELAY 5000000 - -/* msg */ -#define SCSI_LOW_MAX_MSGLEN 32 -#define SCSI_LOW_MSG_LOG_DATALEN 8 - -/************************************************* - * Scsi Data Pointer - *************************************************/ -/* scsi pointer */ -struct sc_p { - u_int8_t *scp_data; - int scp_datalen; - - u_int8_t *scp_cmd; - int scp_cmdlen; - - u_int8_t scp_direction; -#define SCSI_LOW_RWUNK (-1) -#define SCSI_LOW_WRITE 0 -#define SCSI_LOW_READ 1 - u_int8_t scp_status; - u_int8_t scp_spare[2]; -}; - -/************************************************* - * Command Control Block Structure - *************************************************/ -typedef int scsi_low_tag_t; -struct targ_info; - -#define SCSI_LOW_UNKLUN ((u_int) -1) -#define SCSI_LOW_UNKTAG ((scsi_low_tag_t) -1) - -struct slccb { - TAILQ_ENTRY(slccb) ccb_chain; - - void *osdep; /* os depend structure */ - - struct targ_info *ti; /* targ_info */ - struct lun_info *li; /* lun info */ - struct buf *bp; /* io bufs */ - - scsi_low_tag_t ccb_tag; /* effective qtag */ - scsi_low_tag_t ccb_otag; /* allocated qtag */ - - /***************************************** - * Scsi data pointers (original and saved) - *****************************************/ - struct sc_p ccb_scp; /* given */ - struct sc_p ccb_sscp; /* saved scsi data pointer */ - int ccb_datalen; /* transfered data counter */ - - /***************************************** - * Msgout - *****************************************/ - u_int ccb_msgoutflag; - u_int ccb_omsgoutflag; - - /***************************************** - * Error or Timeout counters - *****************************************/ - u_int ccb_flags; -#define CCB_INTERNAL 0x0001 -#define CCB_SENSE 0x0002 -#define CCB_CLEARQ 0x0004 -#define CCB_DISCQ 0x0008 -#define CCB_STARTQ 0x0010 -#define CCB_POLLED 0x0100 /* polling ccb */ -#define CCB_NORETRY 0x0200 /* do NOT retry */ -#define CCB_AUTOSENSE 0x0400 /* do a sence after CA */ -#define CCB_URGENT 0x0800 /* an urgent ccb */ -#define CCB_NOSDONE 0x1000 /* do not call an os done routine */ -#define CCB_SCSIIO 0x2000 /* a normal scsi io coming from upper layer */ -#define CCB_SILENT 0x4000 /* no terminate messages */ - - u_int ccb_error; - - int ccb_rcnt; /* retry counter */ - int ccb_selrcnt; /* selection retry counter */ - int ccb_tc; /* timer counter */ - int ccb_tcmax; /* max timeout */ - - /***************************************** - * Sense data buffer - *****************************************/ - u_int8_t ccb_scsi_cmd[12]; - scsi_low_osdep_sense_data_t ccb_sense; -}; - -/************************************************* - * Slccb functions - *************************************************/ -GENERIC_CCB_ASSERT(scsi_low, slccb) - -/************************************************* - * Target and Lun structures - *************************************************/ -struct scsi_low_softc; -LIST_HEAD(scsi_low_softc_tab, scsi_low_softc); -TAILQ_HEAD(targ_info_tab, targ_info); -LIST_HEAD(lun_info_tab, lun_info); - -struct lun_info { - struct scsi_low_osdep_lun_interface li_sloi; - - int li_lun; - struct targ_info *li_ti; /* my target */ - - LIST_ENTRY(lun_info) lun_chain; /* targ_info link */ - - struct slccbtab li_discq; /* disconnect queue */ - - /* - * qtag control - */ - int li_maxnexus; - int li_maxnqio; - int li_nqio; - int li_disc; - -#define SCSI_LOW_MAXNEXUS (sizeof(u_int) * NBBY) - u_int li_qtagbits; - -#ifdef SCSI_LOW_ALT_QTAG_ALLOCATE - u_int8_t li_qtagarray[SCSI_LOW_MAXNEXUS]; - u_int li_qd; -#endif /* SCSI_LOW_ALT_QTAG_ALLOCATE */ - -#define SCSI_LOW_QFLAG_CA_QCLEAR 0x01 - u_int li_qflags; - - /* - * lun state - */ -#define SCSI_LOW_LUN_SLEEP 0x00 -#define SCSI_LOW_LUN_START 0x01 -#define SCSI_LOW_LUN_INQ 0x02 -#define SCSI_LOW_LUN_MODEQ 0x03 -#define SCSI_LOW_LUN_OK 0x04 - u_int li_state; /* target lun state */ - - /* - * lun control flags - */ - u_int li_flags_valid; /* valid flags */ -#define SCSI_LOW_LUN_FLAGS_USER_VALID 0x0001 -#define SCSI_LOW_LUN_FLAGS_DISK_VALID 0x0002 -#define SCSI_LOW_LUN_FLAGS_QUIRKS_VALID 0x0004 -#define SCSI_LOW_LUN_FLAGS_ALL_VALID \ - (SCSI_LOW_LUN_FLAGS_USER_VALID | \ - SCSI_LOW_LUN_FLAGS_DISK_VALID | SCSI_LOW_LUN_FLAGS_QUIRKS_VALID) - - u_int li_flags; /* real lun control flags */ - u_int li_cfgflags; /* lun control flags given by user */ - u_int li_diskflags; /* lun control flags given by hardware info */ - u_int li_quirks; /* lun control flags given by upper layer */ - - /* inq buffer */ - struct scsi_low_inq_data { - u_int8_t sd_type; - u_int8_t sd_sp1; - u_int8_t sd_version; - u_int8_t sd_resp; - u_int8_t sd_len; - u_int8_t sd_sp2[2]; - u_int8_t sd_support; - } __attribute__((packed)) li_inq; - - /* modeq buffer */ - struct scsi_low_mode_sense_data { - u_int8_t sms_header[4]; - struct { - u_int8_t cmp_page; - u_int8_t cmp_length; - u_int8_t cmp_rlec; - u_int8_t cmp_qc; - u_int8_t cmp_eca; - u_int8_t cmp_spare[3]; - } __attribute__((packed)) sms_cmp; - - } li_sms; -}; - -struct scsi_low_msg_log { - int slml_ptr; - struct { - u_int8_t msg[2]; - } slml_msg[SCSI_LOW_MSG_LOG_DATALEN]; -}; - -struct targ_info { - struct scsi_low_osdep_targ_interface ti_slti; - - TAILQ_ENTRY(targ_info) ti_chain; /* targ_info link */ - - struct scsi_low_softc *ti_sc; /* our softc */ - u_int ti_id; /* scsi id */ - - /* - * Lun chain - */ - struct lun_info_tab ti_litab; /* lun chain */ - - /* - * total disconnected nexus - */ - int ti_disc; - - /* - * Scsi phase control - */ - -#define PH_NULL 0x00 -#define PH_ARBSTART 0x01 -#define PH_SELSTART 0x02 -#define PH_SELECTED 0x03 -#define PH_CMD 0x04 -#define PH_DATA 0x05 -#define PH_MSGIN 0x06 -#define PH_MSGOUT 0x07 -#define PH_STAT 0x08 -#define PH_DISC 0x09 -#define PH_RESEL 0x0a - u_int ti_phase; /* scsi phase */ - u_int ti_ophase; /* old scsi phase */ - - /* - * Msg in - */ - u_int ti_msginptr; /* msgin ptr */ - u_int ti_msginlen; /* expected msg length */ - int ti_msgin_parity_error; /* parity error detected */ - u_int8_t ti_msgin[SCSI_LOW_MAX_MSGLEN]; /* msgin buffer */ - - /* - * Msg out - */ - u_int ti_msgflags; /* msgs to be asserted */ - u_int ti_omsgflags; /* msgs asserted */ - u_int ti_emsgflags; /* a msg currently asserted */ -#define SCSI_LOW_MSG_RESET 0x00000001 -#define SCSI_LOW_MSG_REJECT 0x00000002 -#define SCSI_LOW_MSG_PARITY 0x00000004 -#define SCSI_LOW_MSG_ERROR 0x00000008 -#define SCSI_LOW_MSG_IDENTIFY 0x00000010 -#define SCSI_LOW_MSG_ABORT 0x00000020 -#define SCSI_LOW_MSG_TERMIO 0x00000040 -#define SCSI_LOW_MSG_SIMPLE_QTAG 0x00000080 -#define SCSI_LOW_MSG_ORDERED_QTAG 0x00000100 -#define SCSI_LOW_MSG_HEAD_QTAG 0x00000200 -#define SCSI_LOW_MSG_ABORT_QTAG 0x00000400 -#define SCSI_LOW_MSG_CLEAR_QTAG 0x00000800 -#define SCSI_LOW_MSG_WIDE 0x00001000 -#define SCSI_LOW_MSG_SYNCH 0x00002000 -#define SCSI_LOW_MSG_NOOP 0x00004000 -#define SCSI_LOW_MSG_LAST 0x00008000 -#define SCSI_LOW_MSG_ALL 0xffffffff - - /* msgout buffer */ - u_int8_t ti_msgoutstr[SCSI_LOW_MAX_MSGLEN]; /* scsi msgout */ - u_int ti_msgoutlen; /* msgout strlen */ - - /* - * target initialize msgout - */ - u_int ti_setup_msg; /* setup msgout requests */ - u_int ti_setup_msg_done; - - /* - * synch and wide data info - */ - u_int ti_flags_valid; /* valid flags */ -#define SCSI_LOW_TARG_FLAGS_USER_VALID 0x0001 -#define SCSI_LOW_TARG_FLAGS_DISK_VALID 0x0002 -#define SCSI_LOW_TARG_FLAGS_QUIRKS_VALID 0x0004 -#define SCSI_LOW_TARG_FLAGS_ALL_VALID \ - (SCSI_LOW_TARG_FLAGS_USER_VALID | \ - SCSI_LOW_TARG_FLAGS_DISK_VALID | SCSI_LOW_TARG_FLAGS_QUIRKS_VALID) - - u_int ti_diskflags; /* given target disk flags */ - u_int ti_quirks; /* given target quirk */ - - struct synch { - u_int8_t offset; - u_int8_t period; - } ti_osynch, ti_maxsynch; /* synch data */ - -#define SCSI_LOW_BUS_WIDTH_8 0 -#define SCSI_LOW_BUS_WIDTH_16 1 -#define SCSI_LOW_BUS_WIDTH_32 2 - u_int ti_owidth, ti_width; - - /* - * lun info size. - */ - int ti_lunsize; - -#ifdef SCSI_LOW_DIAGNOSTIC - struct scsi_low_msg_log ti_log_msgout; - struct scsi_low_msg_log ti_log_msgin; -#endif /* SCSI_LOW_DIAGNOSTIC */ -}; - -/************************************************* - * COMMON HEADER STRUCTURE - *************************************************/ -struct scsi_low_softc; -struct proc; -typedef struct scsi_low_softc *sc_low_t; - -#define SCSI_LOW_START_OK 0 -#define SCSI_LOW_START_FAIL 1 -#define SCSI_LOW_INFO_ALLOC 0 -#define SCSI_LOW_INFO_REVOKE 1 -#define SCSI_LOW_INFO_DEALLOC 2 -#define SCSI_LOW_POWDOWN 1 -#define SCSI_LOW_ENGAGE 2 - -#define SC_LOW_INIT_T (int (*) (sc_low_t, int)) -#define SC_LOW_BUSRST_T (void (*) (sc_low_t)) -#define SC_LOW_TARG_INIT_T (int (*) (sc_low_t, struct targ_info *, int)) -#define SC_LOW_LUN_INIT_T (int (*) (sc_low_t, struct targ_info *, struct lun_info *, int)) -#define SC_LOW_SELECT_T (int (*) (sc_low_t, struct slccb *)) -#define SC_LOW_ATTEN_T (void (*) (sc_low_t)) -#define SC_LOW_NEXUS_T (int (*) (sc_low_t)) -#define SC_LOW_MSG_T (int (*) (sc_low_t, struct targ_info *, u_int)) -#define SC_LOW_POLL_T (int (*) (void *)) -#define SC_LOW_POWER_T (int (*) (sc_low_t, u_int)) -#define SC_LOW_TIMEOUT_T (int (*) (sc_low_t)) - -struct scsi_low_funcs { - int (*scsi_low_init) (sc_low_t, int); - void (*scsi_low_bus_reset) (sc_low_t); - int (*scsi_low_targ_init) (sc_low_t, struct targ_info *, int); - int (*scsi_low_lun_init) (sc_low_t, struct targ_info *, struct lun_info *, int); - int (*scsi_low_start_bus) (sc_low_t, struct slccb *); - int (*scsi_low_establish_lun_nexus) (sc_low_t); - int (*scsi_low_establish_ccb_nexus) (sc_low_t); - void (*scsi_low_attention) (sc_low_t); - int (*scsi_low_msg) (sc_low_t, struct targ_info *, u_int); - int (*scsi_low_timeout) (sc_low_t); - int (*scsi_low_poll) (void *); - int (*scsi_low_power) (sc_low_t, u_int); - int (*scsi_low_ioctl) (sc_low_t, u_long, caddr_t, int, struct proc *); -}; - -struct scsi_low_softc { - /* os depend structure */ - struct scsi_low_osdep_interface sl_si; -#define sl_dev sl_si.si_dev - struct scsi_low_osdep_funcs *sl_osdep_fp; - u_char sl_xname[16]; - - /* our chain */ - LIST_ENTRY(scsi_low_softc) sl_chain; - - /* my targets */ - struct targ_info *sl_ti[SCSI_LOW_NTARGETS]; - struct targ_info_tab sl_titab; - - /* current active T_L_Q nexus */ - struct targ_info *sl_Tnexus; /* Target nexus */ - struct lun_info *sl_Lnexus; /* Lun nexus */ - struct slccb *sl_Qnexus; /* Qtag nexus */ - int sl_nexus_call; - - /* ccb start queue */ - struct slccbtab sl_start; - - /* retry limit and phase change counter */ - int sl_max_retry; - int sl_ph_count; - int sl_timeout_count; - - /* selection & total num disconnect targets */ - int sl_nio; - int sl_disc; - int sl_retry_sel; - struct slccb *sl_selid; - - /* attention */ - int sl_atten; /* ATN asserted */ - int sl_clear_atten; /* negate ATN required */ - - /* scsi phase suggested by scsi msg */ - u_int sl_msgphase; -#define MSGPH_NULL 0x00 /* no msg */ -#define MSGPH_DISC 0x01 /* disconnect msg */ -#define MSGPH_CMDC 0x02 /* cmd complete msg */ -#define MSGPH_ABORT 0x03 /* abort seq */ -#define MSGPH_TERM 0x04 /* current io terminate */ -#define MSGPH_LCTERM 0x05 /* cmd link terminated */ -#define MSGPH_RESET 0x06 /* reset target */ - - /* error */ - u_int sl_error; /* error flags */ -#define FATALIO 0x0001 /* generic io error & retry io */ -#define ABORTIO 0x0002 /* generic io error & terminate io */ -#define TIMEOUTIO 0x0004 /* watch dog timeout */ -#define SELTIMEOUTIO 0x0008 /* selection timeout */ -#define PDMAERR 0x0010 /* dma xfer error */ -#define MSGERR 0x0020 /* msgsys error */ -#define PARITYERR 0x0040 /* parity error */ -#define BUSYERR 0x0080 /* target busy error */ -#define STATERR 0x0100 /* status error */ -#define UACAERR 0x0200 /* target CA state, no sense check */ -#define SENSEIO 0x1000 /* cmd not excuted but sense data ok */ -#define SENSEERR 0x2000 /* cmd not excuted and sense data bad */ -#define UBFERR 0x4000 /* unexpected bus free */ -#define PENDINGIO 0x8000 /* ccb start not yet */ -#define SCSI_LOW_ERRORBITS "\020\017ubferr\016senseerr\015senseio\012uacaerr\011staterr\010busy\007parity\006msgerr\005pdmaerr\004seltimeout\003timeout\002abort\001fatal" - - /* current scsi data pointer */ - struct sc_p sl_scp; - - /* power control */ - u_int sl_active; /* host is busy state */ - int sl_powc; /* power down timer counter */ - u_int sl_rstep; /* resume step */ - - /* configuration flags */ - u_int sl_flags; -#define HW_POWDOWN 0x0001 -#define HW_RESUME 0x0002 -#define HW_PDMASTART 0x0004 -#define HW_INACTIVE 0x0008 -#define HW_POWERCTRL 0x0010 -#define HW_INITIALIZING 0x0020 -#define HW_READ_PADDING 0x1000 -#define HW_WRITE_PADDING 0x2000 - - u_int sl_cfgflags; -#define CFG_NODISC 0x0001 -#define CFG_NOPARITY 0x0002 -#define CFG_NOATTEN 0x0004 -#define CFG_ASYNC 0x0008 -#define CFG_NOQTAG 0x0010 - - int sl_show_result; -#define SHOW_SYNCH_NEG 0x0001 -#define SHOW_WIDE_NEG 0x0002 -#define SHOW_CALCF_RES 0x0010 -#define SHOW_PROBE_RES 0x0020 -#define SHOW_ALL_NEG -1 - - /* host informations */ - u_int sl_hostid; - int sl_nluns; - int sl_ntargs; - int sl_openings; - - /* interface functions */ - struct scsi_low_funcs *sl_funcs; - - /* targinfo size */ - int sl_targsize; -}; - -/************************************************* - * SCSI LOW service functions - *************************************************/ -/* - * Scsi low attachment function. - */ -int scsi_low_attach (struct scsi_low_softc *, int, int, int, int, int); -int scsi_low_dettach (struct scsi_low_softc *); - -/* - * Scsi low interface activate or deactivate functions - */ -int scsi_low_is_busy (struct scsi_low_softc *); -int scsi_low_activate (struct scsi_low_softc *); -int scsi_low_deactivate (struct scsi_low_softc *); - -/* - * Scsi phase "bus service" functions. - * These functions are corresponding to each scsi bus phaeses. - */ -/* bus idle phase (other initiators or targets release bus) */ -void scsi_low_bus_idle (struct scsi_low_softc *); - -/* arbitration and selection phase */ -void scsi_low_arbit_fail (struct scsi_low_softc *, struct slccb *); -static __inline void scsi_low_arbit_win (struct scsi_low_softc *); - -/* msgout phase */ -#define SCSI_LOW_MSGOUT_INIT 0x00000001 -#define SCSI_LOW_MSGOUT_UNIFY 0x00000002 -int scsi_low_msgout (struct scsi_low_softc *, struct targ_info *, u_int); - -/* msgin phase */ -#define SCSI_LOW_DATA_PE 0x80000000 -int scsi_low_msgin (struct scsi_low_softc *, struct targ_info *, u_int); - -/* statusin phase */ -static __inline int scsi_low_statusin (struct scsi_low_softc *, struct targ_info *, u_int); - -/* data phase */ -int scsi_low_data (struct scsi_low_softc *, struct targ_info *, struct buf **, int); -static __inline void scsi_low_data_finish (struct scsi_low_softc *); - -/* cmd phase */ -int scsi_low_cmd (struct scsi_low_softc *, struct targ_info *); - -/* reselection phase */ -struct targ_info *scsi_low_reselected (struct scsi_low_softc *, u_int); - -/* disconnection phase */ -int scsi_low_disconnected (struct scsi_low_softc *, struct targ_info *); - -/* - * Scsi bus restart function. - * Canncel all established nexuses => scsi system initialized => restart jobs. - */ -#define SCSI_LOW_RESTART_HARD 1 -#define SCSI_LOW_RESTART_SOFT 0 -int scsi_low_restart (struct scsi_low_softc *, int, u_char *); - -/* - * Scsi utility fucntions - */ -/* print current status */ -void scsi_low_print (struct scsi_low_softc *, struct targ_info *); - -/* bus reset utility */ -void scsi_low_bus_reset (struct scsi_low_softc *); - -/************************************************* - * Message macro defs - *************************************************/ -#define SCSI_LOW_SETUP_PHASE(ti, phase) \ -{ \ - (ti)->ti_ophase = ti->ti_phase; \ - (ti)->ti_phase = (phase); \ -} - -#define SCSI_LOW_SETUP_MSGPHASE(slp, PHASE) \ -{ \ - (slp)->sl_msgphase = (PHASE); \ -} - -#define SCSI_LOW_ASSERT_ATN(slp) \ -{ \ - (slp)->sl_atten = 1; \ -} - -#define SCSI_LOW_DEASSERT_ATN(slp) \ -{ \ - (slp)->sl_atten = 0; \ -} - -/************************************************* - * Inline functions - *************************************************/ -static __inline void scsi_low_attention (struct scsi_low_softc *); -static __inline int scsi_low_is_msgout_continue (struct targ_info *, u_int); -static __inline int scsi_low_assert_msg (struct scsi_low_softc *, struct targ_info *, u_int, int); -static __inline int scsi_low_is_disconnect_ok (struct slccb *); - -static __inline int -scsi_low_is_msgout_continue(struct targ_info *ti, u_int mask) -{ - return ((ti->ti_msgflags & (~mask)) != 0); -} - -static __inline int -scsi_low_is_disconnect_ok(struct slccb *cb) -{ - return ((cb->li->li_flags & SCSI_LOW_DISC) != 0 && - (cb->ccb_flags & (CCB_SENSE | CCB_CLEARQ)) == 0); -} - -static __inline void -scsi_low_attention(struct scsi_low_softc *slp) -{ - if (slp->sl_atten != 0) - return; - - (*slp->sl_funcs->scsi_low_attention) (slp); - SCSI_LOW_ASSERT_ATN(slp); -} - -static __inline int -scsi_low_assert_msg(struct scsi_low_softc *slp, struct targ_info *ti, u_int msg, int now) -{ - ti->ti_msgflags |= msg; - if (now != 0) - scsi_low_attention(slp); - return 0; -} - -static __inline void -scsi_low_arbit_win(struct scsi_low_softc *slp) -{ - slp->sl_selid = NULL; -} - -static __inline void -scsi_low_data_finish(struct scsi_low_softc *slp) -{ - if (slp->sl_Qnexus != NULL) - { - slp->sl_Qnexus->ccb_datalen = slp->sl_scp.scp_datalen; - } -} - -static __inline int -scsi_low_statusin(struct scsi_low_softc *slp, struct targ_info *ti, u_int c) -{ - slp->sl_ph_count ++; - if ((c & SCSI_LOW_DATA_PE) != 0) - { - scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ERROR, 0); - return EIO; - } - slp->sl_scp.scp_status = (u_int8_t) c; - return 0; -} - -/************************************************* - * Message out defs - *************************************************/ -/* XXX: use scsi_message.h */ -#define ST_GOOD 0x00 -#define ST_CHKCOND 0x02 -#define ST_MET 0x04 -#define ST_BUSY 0x08 -#define ST_INTERGOOD 0x10 -#define ST_INTERMET 0x14 -#define ST_CONFLICT 0x18 -#define ST_CMDTERM 0x22 -#define ST_QUEFULL 0x28 -#define ST_UNKNOWN 0xff - -#define MSG_COMP 0x00 -#define MSG_EXTEND 0x01 - -#define MKMSG_EXTEND(XLEN, XCODE) ((((u_int)(XLEN)) << NBBY) | ((u_int)(XCODE))) -#define MSG_EXTEND_MDPCODE 0x00 -#define MSG_EXTEND_MDPLEN 0x05 -#define MSG_EXTEND_SYNCHCODE 0x01 -#define MSG_EXTEND_SYNCHLEN 0x03 -#define MSG_EXTEND_WIDECODE 0x03 -#define MSG_EXTEND_WIDELEN 0x02 - -#define MSG_SAVESP 0x02 -#define MSG_RESTORESP 0x03 -#define MSG_DISCON 0x04 -#define MSG_I_ERROR 0x05 -#define MSG_ABORT 0x06 -#define MSG_REJECT 0x07 -#define MSG_NOOP 0x08 -#define MSG_PARITY 0x09 -#define MSG_LCOMP 0x0a -#define MSG_LCOMP_F 0x0b -#define MSG_RESET 0x0c -#define MSG_ABORT_QTAG 0x0d -#define MSG_CLEAR_QTAG 0x0e -#define MSG_TERM_IO 0x11 -#define MSG_SIMPLE_QTAG 0x20 -#define MSG_HEAD_QTAG 0x21 -#define MSG_ORDERED_QTAG 0x22 -#define MSG_IDENTIFY 0x80 -#define MSG_IDENTIFY_DISCPRIV 0x40 -#endif /* !_SCSI_LOW_H_ */ diff --git a/sys/bus/cam/scsi/scsi_low_pisa.c b/sys/bus/cam/scsi/scsi_low_pisa.c deleted file mode 100644 index 0fd2b83e0f..0000000000 --- a/sys/bus/cam/scsi/scsi_low_pisa.c +++ /dev/null @@ -1,75 +0,0 @@ -/* $FreeBSD: src/sys/cam/scsi/scsi_low_pisa.c,v 1.2.2.4 2001/12/17 13:30:20 non Exp $ */ -/* $DragonFly: src/sys/bus/cam/scsi/scsi_low_pisa.c,v 1.6 2005/12/05 03:42:31 swildner Exp $ */ -/* $NecBSD: scsi_low_pisa.c,v 1.13 1998/11/26 14:26:11 honda Exp $ */ -/* $NetBSD$ */ - -/* - * [NetBSD for NEC PC-98 series] - * Copyright (c) 1995, 1996, 1997, 1998 - * NetBSD/pc98 porting staff. All rights reserved. - * Copyright (c) 1995, 1996, 1997, 1998 - * Naofumi HONDA. All rights reserved. - * - * 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. - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -int -scsi_low_deactivate_pisa(struct scsi_low_softc *sc) -{ - if (scsi_low_deactivate(sc) != 0) - return EBUSY; - return 0; -} - -int -scsi_low_activate_pisa(struct scsi_low_softc *sc, int flags) -{ - sc->sl_cfgflags = ((sc->sl_cfgflags & 0xffff0000) | - (flags & 0x00ff)); - - if (scsi_low_activate(sc) != 0) - return EBUSY; - return 0; -} - -static moduledata_t scsi_low_moduledata = { - "scsi_low", - NULL, - NULL -}; - -DECLARE_MODULE(scsi_low, scsi_low_moduledata, SI_SUB_DRIVERS, SI_ORDER_MIDDLE); -MODULE_VERSION(scsi_low, 1); -MODULE_DEPEND(scsi_low, cam, 1, 1, 1); diff --git a/sys/bus/cam/scsi/scsi_low_pisa.h b/sys/bus/cam/scsi/scsi_low_pisa.h deleted file mode 100644 index d165d1b800..0000000000 --- a/sys/bus/cam/scsi/scsi_low_pisa.h +++ /dev/null @@ -1,40 +0,0 @@ -/* $FreeBSD: src/sys/cam/scsi/scsi_low_pisa.h,v 1.2.2.2 2001/07/22 00:21:41 non Exp $ */ -/* $DragonFly: src/sys/bus/cam/scsi/scsi_low_pisa.h,v 1.5 2004/09/17 01:50:06 joerg Exp $ */ -/* $NecBSD: scsi_low_pisa.h,v 1.3 1999/04/15 01:35:57 kmatsuda Exp $ */ -/* $NetBSD$ */ - -/* - * [NetBSD for NEC PC-98 series] - * Copyright (c) 1998 - * NetBSD/pc98 porting staff. All rights reserved. - * - * 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. - */ - -#ifndef _SCSI_LOW_PISA_H_ -#define _SCSI_LOW_PISA_H_ - -int scsi_low_activate_pisa (struct scsi_low_softc *, int); -int scsi_low_deactivate_pisa (struct scsi_low_softc *); -#endif /* !_SCSI_LOW_PISA_H_ */ diff --git a/sys/conf/files b/sys/conf/files index 40add8a6a0..92cc7d1728 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -65,12 +65,6 @@ bus/cam/scsi/scsi_pt.c optional pt bus/cam/scsi/scsi_sa.c optional sa bus/cam/scsi/scsi_cd.c optional cd bus/cam/scsi/scsi_ch.c optional ch -bus/cam/scsi/scsi_low.c optional ncv -bus/cam/scsi/scsi_low.c optional nsp -bus/cam/scsi/scsi_low.c optional stg -bus/cam/scsi/scsi_low_pisa.c optional ncv -bus/cam/scsi/scsi_low_pisa.c optional nsp -bus/cam/scsi/scsi_low_pisa.c optional stg bus/cam/scsi/scsi_pass.c optional pass bus/cam/scsi/scsi_ses.c optional ses bus/cam/scsi/scsi_sg.c optional sg @@ -947,12 +941,8 @@ dev/netif/mxge/fw/rss_ethp_z8e/mxge_rss_ethp_z8e.c optional mxge pci net/zlib.c optional mxge pci dev/netif/my/if_my.c optional my dev/misc/musycc/musycc.c optional musycc -dev/disk/ncv/ncr53c500.c optional ncv -dev/disk/ncv/ncr53c500_pccard.c optional ncv pccard dev/netif/nge/if_nge.c optional nge dev/misc/nmdm/nmdm.c optional nmdm -dev/disk/nsp/nsp.c optional nsp -dev/disk/nsp/nsp_pccard.c optional nsp pccard dev/netif/oce/oce_hw.c optional oce pci dev/netif/oce/oce_if.c optional oce pci dev/netif/oce/oce_mbox.c optional oce pci @@ -1009,8 +999,6 @@ dev/netif/sln/if_sln.c optional sln pci dev/netif/sn/if_sn.c optional sn dev/netif/sn/if_sn_pccard.c optional sn pccard dev/misc/snp/snp.c optional snp -dev/disk/stg/tmc18c30.c optional stg -dev/disk/stg/tmc18c30_pccard.c optional stg pccard dev/crypto/tpm/tpm.c optional tpm dev/crypto/tpm/tpm_acpi.c optional tpm acpi dev/crypto/tpm/tpm_isa.c optional tpm isa diff --git a/sys/config/LINT64 b/sys/config/LINT64 index d8e1a7fbf5..f9f612b45c 100644 --- a/sys/config/LINT64 +++ b/sys/config/LINT64 @@ -920,9 +920,6 @@ options SC_TWOBUTTON_MOUSE # ahc: Adaptec 274x/284x/294x # aic: Adaptec 1460 # bt: Most Buslogic controllers -# ncv: NCR 53C500 based SCSI host adapters. -# nsp: Workbit Ninja SCSI-3 based PC Card SCSI host adapters. -# stg: TMC 18C30, 18C50 based PC Card SCSI host adapters. # # Note that the order is important in order for Buslogic cards to be # probed correctly. @@ -932,9 +929,6 @@ device bt device adv device adw device aic -device ncv -device nsp -device stg # # Adaptec FSA RAID controllers, including integrated DELL controller, diff --git a/sys/config/X86_64_GENERIC b/sys/config/X86_64_GENERIC index eede857d57..c12686bd56 100644 --- a/sys/config/X86_64_GENERIC +++ b/sys/config/X86_64_GENERIC @@ -106,10 +106,6 @@ device adw device bt device aic -device ncv # NCR 53C500 -device nsp # Workbit Ninja SCSI-3 -device stg # TMC 18C30/18C50 - # SCSI peripherals device scbus # SCSI bus (required) device da # Direct Access (disks) diff --git a/sys/dev/disk/Makefile b/sys/dev/disk/Makefile index adde16ab9a..78749dd3d0 100644 --- a/sys/dev/disk/Makefile +++ b/sys/dev/disk/Makefile @@ -1,7 +1,7 @@ .include "${.CURDIR}/../../platform/${MACHINE_PLATFORM}/Makefile.inc" -SUBDIR= ahci aic aic7xxx ccd dm iscsi isp ispfw md mmcsd mpt nata ncv nsp -SUBDIR+= nvme sbp sdhci sili stg sym trm vn vpo +SUBDIR= ahci aic aic7xxx ccd dm iscsi isp ispfw md mmcsd mpt nata +SUBDIR+= nvme sbp sdhci sili sym trm vn vpo .for dir in ${SUBDIR} .if empty(DEV_SUPPORT:Mdisk) && \ diff --git a/sys/dev/disk/ncv/Makefile b/sys/dev/disk/ncv/Makefile deleted file mode 100644 index 2f12becd88..0000000000 --- a/sys/dev/disk/ncv/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -# $FreeBSD: src/sys/modules/ncv/Makefile,v 1.1.2.2 2002/01/02 07:59:12 non Exp $ - -KMOD= ncv -SRCS= ncr53c500_pccard.c ncr53c500.c -SRCS+= device_if.h bus_if.h pci_if.h isa_if.h card_if.h pccarddevs.h -SRCS+= opt_cam.h opt_scsi.h opt_ddb.h - -.include diff --git a/sys/dev/disk/ncv/dvcfg.h b/sys/dev/disk/ncv/dvcfg.h deleted file mode 100644 index 85c1c89aa2..0000000000 --- a/sys/dev/disk/ncv/dvcfg.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * [NetBSD for NEC PC98 series] - * Copyright (c) 1996 NetBSD/pc98 porting staff. - * All rights reserved. - * - * 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. - * - * $NetBSD$ - * $FreeBSD: src/sys/i386/include/dvcfg.h,v 1.2.6.1 2000/08/03 01:01:19 peter Exp $ - */ -/* - * Copyright (c) 1996 Naofumi HONDA. All rights reserved. - */ - -#ifndef _DVCFG_H_ -#define _DVCFG_H_ - -#ifndef _SYS_TYPES_H_ -#include -#endif - -typedef void *dvcfg_hw_t; - -struct dvcfg_hwsel { - int cfg_max; - - dvcfg_hw_t *cfg_sel; -}; - -#define DVCFG_MAJOR(dvcfg) (((u_int)(dvcfg)) >> 16) -#define DVCFG_MINOR(dvcfg) (((u_int)(dvcfg)) & 0xffff) - -#define DVCFG_MKCFG(major, minor) ((((u_int)(major)) << 16) | ((minor) & 0xffff)) - -#define DVCFG_HWSEL_SZ(array) (sizeof(array) / sizeof(dvcfg_hw_t)) - -static __inline dvcfg_hw_t dvcfg_hw (struct dvcfg_hwsel *, u_int); - -static __inline dvcfg_hw_t -dvcfg_hw(struct dvcfg_hwsel *selp, u_int num) -{ - - return ((num >= selp->cfg_max) ? 0 : selp->cfg_sel[num]); -} - -#define DVCFG_HW(SELP, NUM) dvcfg_hw((SELP), (NUM)) -#endif /* !_DVCFG_H_ */ diff --git a/sys/dev/disk/ncv/ncr53c500.c b/sys/dev/disk/ncv/ncr53c500.c deleted file mode 100644 index dc8dce4d10..0000000000 --- a/sys/dev/disk/ncv/ncr53c500.c +++ /dev/null @@ -1,1236 +0,0 @@ -/* $FreeBSD: src/sys/dev/ncv/ncr53c500.c,v 1.1.2.4 2001/12/17 13:30:18 non Exp $ */ -/* $NecBSD: ncr53c500.c,v 1.30.12.3 2001/06/26 07:31:41 honda Exp $ */ -/* $NetBSD$ */ - -#define NCV_DEBUG -#define NCV_STATICS -#define NCV_IO_CONTROL_FLAGS (0) - -/* - * [NetBSD for NEC PC-98 series] - * Copyright (c) 1995, 1996, 1997, 1998, 1999, 2000, 2001 - * NetBSD/pc98 porting staff. All rights reserved. - * Copyright (c) 1995, 1996, 1997, 1998, 1999, 2000, 2001 - * Naofumi HONDA. All rights reserved. - * - * 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. - */ -#include "opt_ddb.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "dvcfg.h" - -#include - -#include "ncr53c500reg.h" -#include "ncr53c500hw.h" -#include "ncr53c500var.h" - -#include "ncr53c500hwtab.h" - -#define NCV_MAX_DATA_SIZE (64 * 1024) -#define NCV_DELAY_MAX (2 * 1000 * 1000) -#define NCV_DELAY_INTERVAL (1) -#define NCV_PADDING_SIZE (32) - -/*************************************************** - * IO control - ***************************************************/ -#define NCV_READ_INTERRUPTS_DRIVEN 0x0001 -#define NCV_WRITE_INTERRUPTS_DRIVEN 0x0002 -#define NCV_ENABLE_FAST_SCSI 0x0010 -#define NCV_FAST_INTERRUPTS 0x0100 - -u_int ncv_io_control = NCV_IO_CONTROL_FLAGS; -int ncv_data_read_bytes = 4096; -int ncv_data_write_bytes = 4096; - -/*************************************************** - * DEBUG - ***************************************************/ -#ifdef NCV_DEBUG -int ncv_debug; -#endif /* NCV_DEBUG */ - -#ifdef NCV_STATICS -struct ncv_statics { - int disconnect; - int reselect; -} ncv_statics; -#endif /* NCV_STATICS */ - -/************************************************************** - * DECLARE - **************************************************************/ -/* static */ -static void ncv_pio_read (struct ncv_softc *, u_int8_t *, u_int); -static void ncv_pio_write (struct ncv_softc *, u_int8_t *, u_int); -static int ncv_msg (struct ncv_softc *, struct targ_info *, u_int); -static int ncv_reselected (struct ncv_softc *); -static int ncv_disconnected (struct ncv_softc *, struct targ_info *); - -static __inline void ncvhw_set_count (bus_space_tag_t, bus_space_handle_t, int); -static __inline u_int ncvhw_get_count (bus_space_tag_t, bus_space_handle_t); -static __inline void ncvhw_select_register_0 (bus_space_tag_t, bus_space_handle_t, struct ncv_hw *); -static __inline void ncvhw_select_register_1 (bus_space_tag_t, bus_space_handle_t, struct ncv_hw *); -static __inline void ncvhw_fpush (bus_space_tag_t, bus_space_handle_t, u_int8_t *, int); - -static void ncv_pdma_end (struct ncv_softc *sc, struct targ_info *); -static int ncv_world_start (struct ncv_softc *, int); -static void ncvhw_bus_reset (struct ncv_softc *); -static void ncvhw_reset (bus_space_tag_t, bus_space_handle_t, struct ncv_hw *); -static int ncvhw_check (bus_space_tag_t, bus_space_handle_t, struct ncv_hw *); -static void ncvhw_init (bus_space_tag_t, bus_space_handle_t, struct ncv_hw *); -static int ncvhw_start_selection (struct ncv_softc *sc, struct slccb *); -static void ncvhw_attention (struct ncv_softc *); -static int ncv_ccb_nexus_establish (struct ncv_softc *); -static int ncv_lun_nexus_establish (struct ncv_softc *); -static int ncv_target_nexus_establish (struct ncv_softc *); -static int ncv_targ_init (struct ncv_softc *, struct targ_info *, int); -static int ncv_catch_intr (struct ncv_softc *); -#ifdef NCV_POWER_CONTROL -static int ncvhw_power (struct ncv_softc *, u_int); -#endif /* NCV_POWER_CONTROL */ -static __inline void ncv_setup_and_start_pio (struct ncv_softc *, u_int); - -struct scsi_low_funcs ncv_funcs = { - SC_LOW_INIT_T ncv_world_start, - SC_LOW_BUSRST_T ncvhw_bus_reset, - SC_LOW_TARG_INIT_T ncv_targ_init, - SC_LOW_LUN_INIT_T NULL, - - SC_LOW_SELECT_T ncvhw_start_selection, - SC_LOW_NEXUS_T ncv_lun_nexus_establish, - SC_LOW_NEXUS_T ncv_ccb_nexus_establish, - - SC_LOW_ATTEN_T ncvhw_attention, - SC_LOW_MSG_T ncv_msg, - - SC_LOW_TIMEOUT_T NULL, - SC_LOW_POLL_T ncvintr, - - NULL, /* SC_LOW_POWER_T ncvhw_power, */ -}; - -/************************************************************** - * hwfuncs - **************************************************************/ -static __inline void -ncvhw_select_register_0(bus_space_tag_t iot, bus_space_handle_t ioh, - struct ncv_hw *hw) -{ - - bus_space_write_1(iot, ioh, cr0_cfg4, hw->hw_cfg4); -} - -static __inline void -ncvhw_select_register_1(bus_space_tag_t iot, bus_space_handle_t ioh, - struct ncv_hw *hw) -{ - - bus_space_write_1(iot, ioh, cr1_cfg5, hw->hw_cfg5); -} - -static __inline void -ncvhw_fpush(bus_space_tag_t iot, bus_space_handle_t ioh, u_int8_t *buf, - int len) -{ - int ptr; - - for (ptr = 0; ptr < len; ptr ++) - bus_space_write_1(iot, ioh, cr0_sfifo, buf[ptr]); -} - -static __inline void -ncvhw_set_count(bus_space_tag_t iot, bus_space_handle_t ioh, int count) -{ - - bus_space_write_1(iot, ioh, cr0_tclsb, (u_int8_t) count); - bus_space_write_1(iot, ioh, cr0_tcmsb, (u_int8_t) (count >> NBBY)); - bus_space_write_1(iot, ioh, cr0_tchsb, (u_int8_t) (count >> (NBBY * 2))); -} - -static __inline u_int -ncvhw_get_count(bus_space_tag_t iot, bus_space_handle_t ioh) -{ - u_int count; - - count = (u_int) bus_space_read_1(iot, ioh, cr0_tclsb); - count |= ((u_int) bus_space_read_1(iot, ioh, cr0_tcmsb)) << NBBY; - count |= ((u_int) bus_space_read_1(iot, ioh, cr0_tchsb)) << (NBBY * 2); - return count; -} - -static int -ncvhw_check(bus_space_tag_t iot, bus_space_handle_t ioh, struct ncv_hw *hw) -{ - u_int8_t stat; - - ncvhw_select_register_0(iot, ioh, hw); - bus_space_write_1(iot, ioh, cr0_cmd, CMD_NOP | CMD_DMA); - if (bus_space_read_1(iot, ioh, cr0_cmd) != (CMD_NOP | CMD_DMA)) - { -#ifdef NCV_DEBUG - kprintf("ncv: cr0_cmd CMD_NOP|CMD_DMA failed\n"); -#endif /* NCV_DEBUG */ - return ENODEV; - } - - bus_space_write_1(iot, ioh, cr0_cmd, CMD_NOP); - if (bus_space_read_1(iot, ioh, cr0_cmd) != CMD_NOP) - { -#ifdef NCV_DEBUG - kprintf("ncv: cr0_cmd CMD_NOP failed\n"); -#endif /* NCV_DEBUG */ - return ENODEV; - } - - /* hardware reset */ - ncvhw_reset(iot, ioh, hw); - ncvhw_init(iot, ioh, hw); - - /* bus reset */ - ncvhw_select_register_0(iot, ioh, hw); - bus_space_write_1(iot, ioh, cr0_cmd, CMD_FLUSH); - bus_space_write_1(iot, ioh, cr0_cmd, CMD_RSTSCSI); - bus_space_write_1(iot, ioh, cr0_cmd, CMD_NOP | CMD_DMA); - SCSI_LOW_DELAY(100 * 1000); - - /* check response */ - bus_space_read_1(iot, ioh, cr0_stat); - stat = bus_space_read_1(iot, ioh, cr0_istat); - SCSI_LOW_DELAY(1000); - - if (((stat & INTR_SBR) == 0) || - (bus_space_read_1(iot, ioh, cr0_istat) & INTR_SBR)) - { -#ifdef NCV_DEBUG - kprintf("ncv: cr0_istat SCSI BUS RESET failed\n"); -#endif /* NCV_DEBUG */ - return ENODEV; - } - - return 0; -} - -static void -ncvhw_reset(bus_space_tag_t iot, bus_space_handle_t ioh, - struct ncv_hw *hw) -{ - - ncvhw_select_register_0(iot, ioh, hw); - - /* dummy cmd twice */ - bus_space_write_1(iot, ioh, cr0_cmd, CMD_NOP); - bus_space_write_1(iot, ioh, cr0_cmd, CMD_NOP); - - /* chip reset */ - bus_space_write_1(iot, ioh, cr0_cmd, CMD_RSTCHIP); - - /* again dummy cmd twice */ - bus_space_write_1(iot, ioh, cr0_cmd, CMD_NOP); - bus_space_write_1(iot, ioh, cr0_cmd, CMD_NOP); -} - -static void -ncvhw_init(bus_space_tag_t iot, bus_space_handle_t ioh, - struct ncv_hw *hw) -{ - - ncvhw_select_register_0(iot, ioh, hw); - bus_space_write_1(iot, ioh, cr0_clk, hw->hw_clk); - bus_space_write_1(iot, ioh, cr0_srtout, SEL_TOUT); - bus_space_write_1(iot, ioh, cr0_period, 0); - bus_space_write_1(iot, ioh, cr0_offs, 0); - - bus_space_write_1(iot, ioh, cr0_cfg1, hw->hw_cfg1); - bus_space_write_1(iot, ioh, cr0_cfg2, hw->hw_cfg2); - bus_space_write_1(iot, ioh, cr0_cfg3, hw->hw_cfg3); - bus_space_write_1(iot, ioh, cr0_tchsb, 0); - - ncvhw_select_register_1(iot, ioh, hw); - bus_space_write_1(iot, ioh, cr1_fstat, 0x0); - bus_space_write_1(iot, ioh, cr1_pflag, 0x0); - bus_space_write_1(iot, ioh, cr1_atacmd, ATACMD_ENGAGE); - - ncvhw_select_register_0(iot, ioh, hw); -} - -#ifdef NCV_POWER_CONTROL -static int -ncvhw_power(struct ncv_softc *sc, u_int flags) -{ - struct scsi_low_softc *slp = &sc->sc_sclow; - bus_space_tag_t iot = sc->sc_iot; - bus_space_handle_t ioh = sc->sc_ioh; - - if (flags == SCSI_LOW_POWDOWN) - { - kprintf("%s power down\n", slp->sl_xname); - ncvhw_select_register_1(iot, ioh, &sc->sc_hw); - bus_space_write_1(iot, ioh, cr1_atacmd, ATACMD_POWDOWN); - } - else - { - switch (sc->sc_rstep) - { - case 0: - kprintf("%s resume step O\n", slp->sl_xname); - ncvhw_select_register_1(iot, ioh, &sc->sc_hw); - bus_space_write_1(iot, ioh, cr1_atacmd, ATACMD_ENGAGE); - break; - - case 1: - kprintf("%s resume step I\n", slp->sl_xname); - ncvhw_reset(iot, ioh, &sc->sc_hw); - ncvhw_init(iot, ioh, &sc->sc_hw); - break; - } - } - - return 0; -} -#endif /* NCV_POWER_CONTROL */ - -/************************************************************** - * scsi low interface - **************************************************************/ -static void -ncvhw_attention(struct ncv_softc *sc) -{ - - bus_space_write_1(sc->sc_iot, sc->sc_ioh, cr0_cmd, CMD_SETATN); - SCSI_LOW_DELAY(10); -} - -static void -ncvhw_bus_reset(struct ncv_softc *sc) -{ - bus_space_tag_t iot = sc->sc_iot; - bus_space_handle_t ioh = sc->sc_ioh; - - ncvhw_select_register_0(iot, ioh, &sc->sc_hw); - bus_space_write_1(iot, ioh, cr0_cmd, CMD_FLUSH); - bus_space_write_1(iot, ioh, cr0_cmd, CMD_RSTSCSI); - bus_space_write_1(iot, ioh, cr0_cmd, CMD_NOP | CMD_DMA); -} - -static int -ncvhw_start_selection(struct ncv_softc *sc, struct slccb *cb) -{ - struct scsi_low_softc *slp = &sc->sc_sclow; - bus_space_tag_t iot = sc->sc_iot; - bus_space_handle_t ioh = sc->sc_ioh; - struct targ_info *ti = cb->ti; - int len; - u_int flags; - u_int8_t cmd; - - sc->sc_tmaxcnt = cb->ccb_tcmax * 1000 * 1000; - sc->sc_compseq = 0; - if (scsi_low_is_msgout_continue(ti, SCSI_LOW_MSG_IDENTIFY) == 0) - { - cmd = CMD_SELATN; - sc->sc_selstop = 0; - flags = SCSI_LOW_MSGOUT_UNIFY | SCSI_LOW_MSGOUT_INIT; - } - else if (scsi_low_is_msgout_continue(ti, - SCSI_LOW_MSG_IDENTIFY | SCSI_LOW_MSG_SIMPLE_QTAG) == 0) - { - cmd = CMD_SELATN3; - sc->sc_selstop = 0; - flags = SCSI_LOW_MSGOUT_UNIFY | SCSI_LOW_MSGOUT_INIT; - } - else - { - cmd = CMD_SELATNS; - sc->sc_selstop = 1; - flags = SCSI_LOW_MSGOUT_INIT; - } - - ncvhw_select_register_0(iot, ioh, &sc->sc_hw); - if ((bus_space_read_1(iot, ioh, cr0_stat) & STAT_INT) != 0) - return SCSI_LOW_START_FAIL; - - ncv_target_nexus_establish(sc); - - len = scsi_low_msgout(slp, ti, flags); - if (sc->sc_selstop == 0) - scsi_low_cmd(slp, ti); - - crit_enter(); - if ((bus_space_read_1(iot, ioh, cr0_stat) & STAT_INT) != 0) - { - crit_exit(); - return SCSI_LOW_START_FAIL; - } - - bus_space_write_1(iot, ioh, cr0_dstid, ti->ti_id); - bus_space_write_1(iot, ioh, cr0_cmd, CMD_FLUSH); - ncvhw_fpush(iot, ioh, ti->ti_msgoutstr, len); - if (sc->sc_selstop == 0) - { - ncvhw_fpush(iot, ioh, - slp->sl_scp.scp_cmd, slp->sl_scp.scp_cmdlen); - } - bus_space_write_1(iot, ioh, cr0_cmd, cmd); - crit_exit(); - - SCSI_LOW_SETUP_PHASE(ti, PH_SELSTART); - return SCSI_LOW_START_OK; -} - -static int -ncv_world_start(struct ncv_softc *sc, int fdone) -{ - struct scsi_low_softc *slp = &sc->sc_sclow; - bus_space_tag_t iot = sc->sc_iot; - bus_space_handle_t ioh = sc->sc_ioh; - u_int8_t stat; - - if ((slp->sl_cfgflags & CFG_NOPARITY) == 0) - sc->sc_hw.hw_cfg1 |= C1_PARENB; - else - sc->sc_hw.hw_cfg1 &= ~C1_PARENB; - - ncvhw_reset(iot, ioh, &sc->sc_hw); - ncvhw_init(iot, ioh, &sc->sc_hw); - - scsi_low_bus_reset(slp); - - ncvhw_select_register_0(iot, ioh, &sc->sc_hw); - bus_space_read_1(sc->sc_iot, sc->sc_ioh, cr0_stat); - stat = bus_space_read_1(sc->sc_iot, sc->sc_ioh, cr0_istat); - SCSI_LOW_DELAY(1000); - - if (((stat & INTR_SBR) == 0) || - (bus_space_read_1(sc->sc_iot, sc->sc_ioh, cr0_istat) & INTR_SBR)) - return ENODEV; - - SOFT_INTR_REQUIRED(slp); - return 0; -} - -static int -ncv_msg(struct ncv_softc *sc, struct targ_info *ti, u_int msg) -{ - bus_space_tag_t iot = sc->sc_iot; - bus_space_handle_t ioh = sc->sc_ioh; - struct ncv_targ_info *nti = (void *) ti; - u_int hwcycle, period; - - if ((msg & SCSI_LOW_MSG_WIDE) != 0) - { - if (ti->ti_width != SCSI_LOW_BUS_WIDTH_8) - { - ti->ti_width = SCSI_LOW_BUS_WIDTH_8; - return EINVAL; - } - return 0; - } - - if ((msg & SCSI_LOW_MSG_SYNCH) == 0) - return 0; - - period = ti->ti_maxsynch.period; - hwcycle = (sc->sc_hw.hw_clk == 0) ? 40 : (5 * sc->sc_hw.hw_clk); - hwcycle = 1000 / hwcycle; - - if (period < 200 / 4 && period >= 100 / 4) - nti->nti_reg_cfg3 |= sc->sc_hw.hw_cfg3_fscsi; - else - nti->nti_reg_cfg3 &= ~sc->sc_hw.hw_cfg3_fscsi; - - period = ((period * 40 / hwcycle) + 5) / 10; - nti->nti_reg_period = period & 0x1f; - nti->nti_reg_offset = ti->ti_maxsynch.offset; - - bus_space_write_1(iot, ioh, cr0_period, nti->nti_reg_period); - bus_space_write_1(iot, ioh, cr0_offs, nti->nti_reg_offset); - bus_space_write_1(iot, ioh, cr0_cfg3, nti->nti_reg_cfg3); - return 0; -} - -static int -ncv_targ_init(struct ncv_softc *sc, struct targ_info *ti, int action) -{ - struct ncv_targ_info *nti = (void *) ti; - - if (action == SCSI_LOW_INFO_ALLOC || action == SCSI_LOW_INFO_REVOKE) - { - ti->ti_width = SCSI_LOW_BUS_WIDTH_8; - ti->ti_maxsynch.period = sc->sc_hw.hw_mperiod; - ti->ti_maxsynch.offset = sc->sc_hw.hw_moffset; - - nti->nti_reg_cfg3 = sc->sc_hw.hw_cfg3; - nti->nti_reg_period = 0; - nti->nti_reg_offset = 0; - } - return 0; -} - -/************************************************************** - * General probe attach - **************************************************************/ -static int ncv_setup_img (struct ncv_hw *, u_int, int); - -static int -ncv_setup_img(struct ncv_hw *hw, u_int dvcfg, int hostid) -{ - - if (NCV_CLKFACTOR(dvcfg) > CLK_35M_F) - { - kprintf("ncv: invalid dvcfg flags\n"); - return EINVAL; - } - - if (NCV_C5IMG(dvcfg) != 0) - { - hw->hw_cfg5 = NCV_C5IMG(dvcfg); - hw->hw_clk = NCV_CLKFACTOR(dvcfg); - - if ((ncv_io_control & NCV_ENABLE_FAST_SCSI) != 0 && - (NCV_SPECIAL(dvcfg) & NCVHWCFG_MAX10M) != 0) - hw->hw_mperiod = 100 / 4; - - if (NCV_SPECIAL(dvcfg) & NCVHWCFG_FIFOBUG) - hw->hw_cfg3_fclk = 0x04; - - if (NCV_SPECIAL(dvcfg) & NCVHWCFG_SCSI1) - hw->hw_cfg2 &= ~C2_SCSI2; - - if (NCV_SPECIAL(dvcfg) & NCVHWCFG_SLOW) - hw->hw_cfg1 |= C1_SLOW; - } - - /* setup configuration image 3 */ - if (hw->hw_clk != CLK_40M_F && hw->hw_clk <= CLK_25M_F) - hw->hw_cfg3 &= ~hw->hw_cfg3_fclk; - else - hw->hw_cfg3 |= hw->hw_cfg3_fclk; - - /* setup configuration image 1 */ - hw->hw_cfg1 = (hw->hw_cfg1 & 0xf0) | hostid; - return 0; -} - -int -ncvprobesubr(bus_space_tag_t iot, bus_space_handle_t ioh, u_int dvcfg, - int hsid) -{ - struct ncv_hw hwtab; - - hwtab = ncv_template; - if (ncv_setup_img(&hwtab, dvcfg, hsid)) - return 0; - if (ncvhw_check(iot, ioh, &hwtab) != 0) - return 0; - - return 1; -} - -int -ncvprint(void *aux, const char *name) -{ - - if (name != NULL) - kprintf("%s: scsibus ", name); - return UNCONF; -} - -void -ncvattachsubr(struct ncv_softc *sc) -{ - struct scsi_low_softc *slp = &sc->sc_sclow; - - kprintf("\n"); - sc->sc_hw = ncv_template; - ncv_setup_img(&sc->sc_hw, slp->sl_cfgflags, slp->sl_hostid); - slp->sl_funcs = &ncv_funcs; - slp->sl_flags |= HW_READ_PADDING; - sc->sc_tmaxcnt = SCSI_LOW_MIN_TOUT * 1000 * 1000; /* default */ - - (void) scsi_low_attach(slp, 0, NCV_NTARGETS, NCV_NLUNS, - sizeof(struct ncv_targ_info), 0); -} - -/************************************************************** - * PDMA - **************************************************************/ -static __inline void -ncv_setup_and_start_pio(struct ncv_softc *sc, u_int reqlen) -{ - bus_space_tag_t iot = sc->sc_iot; - bus_space_handle_t ioh = sc->sc_ioh; - - ncvhw_select_register_0(iot, ioh, &sc->sc_hw); - ncvhw_set_count(iot, ioh, reqlen); - bus_space_write_1(iot, ioh, cr0_cmd, CMD_TRANS | CMD_DMA); - - ncvhw_select_register_1(iot, ioh, &sc->sc_hw); - bus_space_write_1(iot, ioh, cr1_fstat, FIFO_EN); -} - -static void -ncv_pdma_end(struct ncv_softc *sc, struct targ_info *ti) -{ - struct scsi_low_softc *slp = &sc->sc_sclow; - bus_space_tag_t iot = sc->sc_iot; - bus_space_handle_t ioh = sc->sc_ioh; - int len; - - slp->sl_flags &= ~HW_PDMASTART; - if (slp->sl_Qnexus == NULL) - { - slp->sl_error |= PDMAERR; - goto out; - } - - if (ti->ti_phase == PH_DATA) - { - len = ncvhw_get_count(sc->sc_iot, sc->sc_ioh); - if (slp->sl_scp.scp_direction == SCSI_LOW_WRITE) - len += (bus_space_read_1(sc->sc_iot, sc->sc_ioh, - cr0_sffl) & CR0_SFFLR_BMASK); - - if ((u_int) len <= (u_int) sc->sc_sdatalen) - { - if ((slp->sl_scp.scp_direction == SCSI_LOW_READ) && - sc->sc_tdatalen != len) - goto bad; - - len = sc->sc_sdatalen - len; - if ((u_int) len > (u_int) slp->sl_scp.scp_datalen) - goto bad; - - slp->sl_scp.scp_data += len; - slp->sl_scp.scp_datalen -= len; - } - else - { -bad: - if ((slp->sl_error & PDMAERR) == 0) - { - kprintf("%s: strange cnt hw 0x%x soft 0x%x\n", - slp->sl_xname, len, - slp->sl_scp.scp_datalen); - } - slp->sl_error |= PDMAERR; - } - scsi_low_data_finish(slp); - } - else - { - kprintf("%s: data phase miss\n", slp->sl_xname); - slp->sl_error |= PDMAERR; - } - -out: - ncvhw_select_register_1(iot, ioh, &sc->sc_hw); - bus_space_write_1(iot, ioh, cr1_fstat, 0); - ncvhw_select_register_0(iot, ioh, &sc->sc_hw); -} - -static void -ncv_pio_read(struct ncv_softc *sc, u_int8_t *buf, u_int reqlen) -{ - struct scsi_low_softc *slp = &sc->sc_sclow; - bus_space_tag_t iot = sc->sc_iot; - bus_space_handle_t ioh = sc->sc_ioh; - int tout; - u_int8_t fstat; - - ncv_setup_and_start_pio(sc, reqlen); - slp->sl_flags |= HW_PDMASTART; - sc->sc_sdatalen = reqlen; - tout = sc->sc_tmaxcnt; - - while (reqlen >= FIFO_F_SZ && tout -- > 0) - { - fstat = bus_space_read_1(iot, ioh, cr1_fstat); - if (fstat == (u_int8_t) -1) - goto out; - if (fstat & FIFO_F) - { -#define NCV_FAST32_ACCESS -#ifdef NCV_FAST32_ACCESS - bus_space_read_multi_4(iot, ioh, cr1_fdata, - (u_int32_t *) buf, FIFO_F_SZ / 4); -#else /* !NCV_FAST32_ACCESS */ - bus_space_read_multi_2(iot, ioh, cr1_fdata, - (u_int16_t *) buf, FIFO_F_SZ / 2); -#endif /* !NCV_FAST32_ACCESS */ - buf += FIFO_F_SZ; - reqlen -= FIFO_F_SZ; - } - else - { - if (fstat & FIFO_BRK) - break; - - SCSI_LOW_DELAY(1); - } - } - - while (reqlen > 0 && tout -- > 0) - { - fstat = bus_space_read_1(iot, ioh, cr1_fstat); - if ((fstat & FIFO_E) == 0) - { - *buf++ = bus_space_read_1(iot, ioh, cr1_fdata); - reqlen --; - } - else - { - if (fstat & FIFO_BRK) - break; - - SCSI_LOW_DELAY(1); - } - } - -out: - ncvhw_select_register_0(iot, ioh, &sc->sc_hw); - sc->sc_tdatalen = reqlen; -} - -static void -ncv_pio_write(struct ncv_softc *sc, u_int8_t *buf, u_int reqlen) -{ - struct scsi_low_softc *slp = &sc->sc_sclow; - bus_space_tag_t iot = sc->sc_iot; - bus_space_handle_t ioh = sc->sc_ioh; - int tout; - u_int8_t fstat; - - ncv_setup_and_start_pio(sc, reqlen); - sc->sc_sdatalen = reqlen; - tout = sc->sc_tmaxcnt; - slp->sl_flags |= HW_PDMASTART; - - while (reqlen >= FIFO_F_SZ && tout -- > 0) - { - fstat = bus_space_read_1(iot, ioh, cr1_fstat); - if (fstat & FIFO_BRK) - goto done; - - if ((fstat & FIFO_E) != 0) - { -#ifdef NCV_FAST32_ACCESS - bus_space_write_multi_4(iot, ioh, cr1_fdata, - (u_int32_t *) buf, FIFO_F_SZ / 4); -#else /* !NCV_FAST32_ACCESS */ - bus_space_write_multi_2(iot, ioh, cr1_fdata, - (u_int16_t *) buf, FIFO_F_SZ / 2); -#endif /* !NCV_FAST32_ACCESS */ - buf += FIFO_F_SZ; - reqlen -= FIFO_F_SZ; - } - else - { - SCSI_LOW_DELAY(1); - } - } - - while (reqlen > 0 && tout -- > 0) - { - fstat = bus_space_read_1(iot, ioh, cr1_fstat); - if (fstat & FIFO_BRK) - break; - - if ((fstat & FIFO_F) == 0) /* fifo not full */ - { - bus_space_write_1(iot, ioh, cr1_fdata, *buf++); - reqlen --; - } - else - { - SCSI_LOW_DELAY(1); - } - } - -done: - ncvhw_select_register_0(iot, ioh, &sc->sc_hw); -} - -/************************************************************** - * disconnect & reselect (HW low) - **************************************************************/ -static int -ncv_reselected(struct ncv_softc *sc) -{ - struct scsi_low_softc *slp = &sc->sc_sclow; - bus_space_tag_t iot = sc->sc_iot; - bus_space_handle_t ioh = sc->sc_ioh; - struct targ_info *ti; - u_int sid; - - if ((bus_space_read_1(iot, ioh, cr0_sffl) & CR0_SFFLR_BMASK) != 2) - { - kprintf("%s illegal fifo bytes\n", slp->sl_xname); - scsi_low_restart(slp, SCSI_LOW_RESTART_HARD, "chip confused"); - return EJUSTRETURN; - } - - sid = (u_int) bus_space_read_1(iot, ioh, cr0_sfifo); - sid &= ~(1 << slp->sl_hostid); - sid = ffs(sid) - 1; - ti = scsi_low_reselected((struct scsi_low_softc *) sc, sid); - if (ti == NULL) - return EJUSTRETURN; - -#ifdef NCV_STATICS - ncv_statics.reselect ++; -#endif /* NCV_STATICS */ - bus_space_write_1(iot, ioh, cr0_dstid, sid); - return 0; -} - -static int -ncv_disconnected(struct ncv_softc *sc, struct targ_info *ti) -{ - struct scsi_low_softc *slp = &sc->sc_sclow; - bus_space_tag_t iot = sc->sc_iot; - bus_space_handle_t ioh = sc->sc_ioh; - - bus_space_write_1(iot, ioh, cr0_cmd, CMD_FLUSH); - bus_space_write_1(iot, ioh, cr0_cmd, CMD_ENSEL); - -#ifdef NCV_STATICS - ncv_statics.disconnect ++; -#endif /* NCV_STATICS */ - - scsi_low_disconnected(slp, ti); - return 1; -} - -/************************************************************** - * SEQUENCER - **************************************************************/ -static int -ncv_target_nexus_establish(struct ncv_softc *sc) -{ - struct scsi_low_softc *slp = &sc->sc_sclow; - struct targ_info *ti = slp->sl_Tnexus; - struct ncv_targ_info *nti = (void *) ti; - bus_space_tag_t iot = sc->sc_iot; - bus_space_handle_t ioh = sc->sc_ioh; - - bus_space_write_1(iot, ioh, cr0_period, nti->nti_reg_period); - bus_space_write_1(iot, ioh, cr0_offs, nti->nti_reg_offset); - bus_space_write_1(iot, ioh, cr0_cfg3, nti->nti_reg_cfg3); - return 0; -} - -static int -ncv_lun_nexus_establish(struct ncv_softc *sc) -{ - - return 0; -} - -static int -ncv_ccb_nexus_establish(struct ncv_softc *sc) -{ - struct scsi_low_softc *slp = &sc->sc_sclow; - struct slccb *cb = slp->sl_Qnexus; - - sc->sc_tmaxcnt = cb->ccb_tcmax * 1000 * 1000; - return 0; -} - -static int -ncv_catch_intr(struct ncv_softc *sc) -{ - bus_space_tag_t iot = sc->sc_iot; - bus_space_handle_t ioh = sc->sc_ioh; - int wc; - u_int8_t status; - - for (wc = 0; wc < NCV_DELAY_MAX / NCV_DELAY_INTERVAL; wc ++) - { - status = bus_space_read_1(iot, ioh, cr0_stat); - if ((status & STAT_INT) != 0) - return 0; - - SCSI_LOW_DELAY(NCV_DELAY_INTERVAL); - } - return EJUSTRETURN; -} - -int -ncvintr(void *arg) -{ - struct ncv_softc *sc = arg; - struct scsi_low_softc *slp = &sc->sc_sclow; - bus_space_tag_t iot = sc->sc_iot; - bus_space_handle_t ioh = sc->sc_ioh; - struct targ_info *ti; - struct buf *bp; - u_int derror, flags; - int len; - u_int8_t regv, status, ireason; - -again: - if (slp->sl_flags & HW_INACTIVE) - return 0; - - /******************************************** - * Status - ********************************************/ - ncvhw_select_register_0(iot, ioh, &sc->sc_hw); - status = bus_space_read_1(iot, ioh, cr0_stat); - if ((status & STAT_INT) == 0 || status == (u_int8_t) -1) - return 0; - - ireason = bus_space_read_1(iot, ioh, cr0_istat); - if ((ireason & INTR_SBR) != 0) - { - u_int8_t val; - - /* avoid power off hangup */ - val = bus_space_read_1(iot, ioh, cr0_cfg1); - bus_space_write_1(iot, ioh, cr0_cfg1, val | C1_SRR); - - /* status init */ - scsi_low_restart(slp, SCSI_LOW_RESTART_SOFT, - "bus reset (power off?)"); - return 1; - } - - /******************************************** - * Debug section - ********************************************/ -#ifdef NCV_DEBUG - if (ncv_debug) - { - scsi_low_print(slp, NULL); - kprintf("%s st %x ist %x\n\n", slp->sl_xname, - status, ireason); -#ifdef DDB - if (ncv_debug > 1) - SCSI_LOW_DEBUGGER("ncv"); -#endif /* DDB */ - } -#endif /* NCV_DEBUG */ - - /******************************************** - * Reselect or Disconnect or Nexus check - ********************************************/ - /* (I) reselect */ - if (ireason == INTR_RESELECT) - { - if (ncv_reselected(sc) == EJUSTRETURN) - return 1; - } - - /* (II) nexus */ - if ((ti = slp->sl_Tnexus) == NULL) - return 0; - - derror = 0; - if ((status & (STAT_PE | STAT_GE)) != 0) - { - slp->sl_error |= PARITYERR; - if ((status & PHASE_MASK) == MESSAGE_IN_PHASE) - scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_PARITY, 0); - else - scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ERROR, 1); - derror = SCSI_LOW_DATA_PE; - } - - if ((ireason & (INTR_DIS | INTR_ILL)) != 0) - { - if ((ireason & INTR_ILL) == 0) - return ncv_disconnected(sc, ti); - - slp->sl_error |= FATALIO; - scsi_low_restart(slp, SCSI_LOW_RESTART_HARD, "illegal cmd"); - return 1; - } - - /******************************************** - * Internal scsi phase - ********************************************/ - switch (ti->ti_phase) - { - case PH_SELSTART: - scsi_low_arbit_win(slp); - SCSI_LOW_SETUP_PHASE(ti, PH_SELECTED); - - if (sc->sc_selstop == 0) - { - /* XXX: - * Here scsi phases expected are - * DATA PHASE: - * MSGIN : target wants to disconnect the host. - * STATUSIN : immediate command completed. - * CMD PHASE : command out failed - * MSGOUT : identify command failed. - */ - if ((status & PHASE_MASK) != MESSAGE_OUT_PHASE) - break; - } - else - { - if ((status & PHASE_MASK) != MESSAGE_OUT_PHASE) - break; - if ((ireason & INTR_FC) != 0) - { - SCSI_LOW_ASSERT_ATN(slp); - } - } - SCSI_LOW_SETUP_PHASE(ti, PH_MSGOUT); - break; - - case PH_RESEL: - ncv_target_nexus_establish(sc); - if ((status & PHASE_MASK) != MESSAGE_IN_PHASE) - { - kprintf("%s: unexpected phase after reselect\n", - slp->sl_xname); - slp->sl_error |= FATALIO; - scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 1); - return 1; - } - break; - - default: - if ((slp->sl_flags & HW_PDMASTART) != 0) - { - ncv_pdma_end(sc, ti); - } - break; - } - - /******************************************** - * Scsi phase sequencer - ********************************************/ - switch (status & PHASE_MASK) - { - case DATA_OUT_PHASE: /* data out */ - SCSI_LOW_SETUP_PHASE(ti, PH_DATA); - if (scsi_low_data(slp, ti, &bp, SCSI_LOW_WRITE) != 0) - { - scsi_low_attention(slp); - } - - if (slp->sl_scp.scp_datalen <= 0) - { - if ((ireason & INTR_BS) == 0) - break; - - if ((slp->sl_error & PDMAERR) == 0) - kprintf("%s: data underrun\n", slp->sl_xname); - slp->sl_error |= PDMAERR; - - if ((slp->sl_flags & HW_WRITE_PADDING) != 0) - { - u_int8_t padding[NCV_PADDING_SIZE]; - - SCSI_LOW_BZERO(padding, sizeof(padding)); - ncv_pio_write(sc, padding, sizeof(padding)); - } - else - { - kprintf("%s: write padding required\n", - slp->sl_xname); - } - } - else - { - len = slp->sl_scp.scp_datalen; - if ((ncv_io_control & NCV_WRITE_INTERRUPTS_DRIVEN) != 0) - { - if (len > ncv_data_write_bytes) - len = ncv_data_write_bytes; - } - ncv_pio_write(sc, slp->sl_scp.scp_data, len); - } - break; - - case DATA_IN_PHASE: /* data in */ - SCSI_LOW_SETUP_PHASE(ti, PH_DATA); - if (scsi_low_data(slp, ti, &bp, SCSI_LOW_READ) != 0) - { - scsi_low_attention(slp); - } - - if (slp->sl_scp.scp_datalen <= 0) - { - if ((ireason & INTR_BS) == 0) - break; - - if ((slp->sl_error & PDMAERR) == 0) - kprintf("%s: data overrun\n", slp->sl_xname); - slp->sl_error |= PDMAERR; - - if ((slp->sl_flags & HW_READ_PADDING) != 0) - { - u_int8_t padding[NCV_PADDING_SIZE]; - - ncv_pio_read(sc, padding, sizeof(padding)); - } - else - { - kprintf("%s: read padding required\n", - slp->sl_xname); - break; - } - } - else - { - len = slp->sl_scp.scp_datalen; - if ((ncv_io_control & NCV_READ_INTERRUPTS_DRIVEN) != 0) - { - if (len > ncv_data_read_bytes) - len = ncv_data_read_bytes; - } - ncv_pio_read(sc, slp->sl_scp.scp_data, len); - } - break; - - case COMMAND_PHASE: /* cmd out */ - SCSI_LOW_SETUP_PHASE(ti, PH_CMD); - if (scsi_low_cmd(slp, ti) != 0) - { - scsi_low_attention(slp); - } - - bus_space_write_1(iot, ioh, cr0_cmd, CMD_FLUSH); - ncvhw_fpush(iot, ioh, - slp->sl_scp.scp_cmd, slp->sl_scp.scp_cmdlen); - bus_space_write_1(iot, ioh, cr0_cmd, CMD_TRANS); - break; - - case STATUS_PHASE: /* status in */ - SCSI_LOW_SETUP_PHASE(ti, PH_STAT); - bus_space_write_1(iot, ioh, cr0_cmd, CMD_FLUSH); - bus_space_write_1(iot, ioh, cr0_cmd, CMD_ICCS); - sc->sc_compseq = 1; - break; - - default: - break; - - case MESSAGE_OUT_PHASE: /* msg out */ - SCSI_LOW_SETUP_PHASE(ti, PH_MSGOUT); - bus_space_write_1(iot, ioh, cr0_cmd, CMD_FLUSH); - - flags = SCSI_LOW_MSGOUT_UNIFY; - if (ti->ti_ophase != ti->ti_phase) - flags |= SCSI_LOW_MSGOUT_INIT; - len = scsi_low_msgout(slp, ti, flags); - - if (len > 1 && slp->sl_atten == 0) - { - scsi_low_attention(slp); - } - - ncvhw_fpush(iot, ioh, ti->ti_msgoutstr, len); - bus_space_write_1(iot, ioh, cr0_cmd, CMD_TRANS); - SCSI_LOW_DEASSERT_ATN(slp); - break; - - case MESSAGE_IN_PHASE: /* msg in */ - SCSI_LOW_SETUP_PHASE(ti, PH_MSGIN); - - len = bus_space_read_1(iot, ioh, cr0_sffl) & CR0_SFFLR_BMASK; - if (sc->sc_compseq != 0) - { - sc->sc_compseq = 0; - if ((ireason & INTR_FC) && len == 2) - { - regv = bus_space_read_1(iot, ioh, cr0_sfifo); - scsi_low_statusin(slp, ti, regv | derror); - len --; - } - else - { - slp->sl_error |= FATALIO; - scsi_low_assert_msg(slp, ti, - SCSI_LOW_MSG_ABORT, 1); - bus_space_write_1(sc->sc_iot, sc->sc_ioh, - cr0_cmd, CMD_MSGOK); - break; - } - } - else if (ireason & INTR_BS) - { - bus_space_write_1(iot, ioh, cr0_cmd, CMD_FLUSH); - bus_space_write_1(iot, ioh, cr0_cmd, CMD_TRANS); - if ((ncv_io_control & NCV_FAST_INTERRUPTS) != 0) - { - if (ncv_catch_intr(sc) == 0) - goto again; - } - break; - } - - if ((ireason & INTR_FC) && len == 1) - { - regv = bus_space_read_1(sc->sc_iot, sc->sc_ioh, - cr0_sfifo); - if (scsi_low_msgin(slp, ti, regv | derror) == 0) - { - if (scsi_low_is_msgout_continue(ti, 0) != 0) - { - scsi_low_attention(slp); - } - } - bus_space_write_1(sc->sc_iot, sc->sc_ioh, cr0_cmd, - CMD_MSGOK); - if ((ncv_io_control & NCV_FAST_INTERRUPTS) != 0) - { - /* XXX: - * clear a pending interrupt and sync with - * a next interrupt! - */ - ncv_catch_intr(sc); - } - } - else - { - slp->sl_error |= FATALIO; - scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 1); - bus_space_write_1(sc->sc_iot, sc->sc_ioh, cr0_cmd, - CMD_MSGOK); - } - break; - } - - return 1; -} diff --git a/sys/dev/disk/ncv/ncr53c500_pccard.c b/sys/dev/disk/ncv/ncr53c500_pccard.c deleted file mode 100644 index 37f23cd651..0000000000 --- a/sys/dev/disk/ncv/ncr53c500_pccard.c +++ /dev/null @@ -1,366 +0,0 @@ -/* $FreeBSD: src/sys/dev/ncv/ncr53c500_pccard.c,v 1.2.2.5 2001/12/17 13:30:18 non Exp $ */ -/* $NecBSD: ncr53c500_pisa.c,v 1.28 1998/11/26 01:59:11 honda Exp $ */ -/* $NetBSD$ */ - -/* - * [Ported for FreeBSD] - * Copyright (c) 2000 - * Noriaki Mitsunaga, Mitsuru Iwasaki and Takanori Watanabe. - * All rights reserved. - * [NetBSD for NEC PC-98 series] - * Copyright (c) 1995, 1996, 1997, 1998 - * NetBSD/pc98 porting staff. All rights reserved. - * Copyright (c) 1995, 1996, 1997, 1998 - * Naofumi HONDA. All rights reserved. - * - * 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. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "dvcfg.h" - -#include -#include - -#include - -#include "pccarddevs.h" - -#include -#include - -#include "ncr53c500reg.h" -#include "ncr53c500hw.h" -#include "ncr53c500var.h" - -#define KME_KXLC004_01 0x100 -#define OFFSET_KME_KXLC004_01 0x10 - -#include -#include - -static int ncvprobe(DEVPORT_PDEVICE devi); -static int ncvattach(DEVPORT_PDEVICE devi); - -static void ncv_card_unload (DEVPORT_PDEVICE); - -static const struct ncv_product { - struct pccard_product prod; - int flags; -} ncv_products[] = { - { PCMCIA_CARD(EPSON, SC200, 0), 0}, - { PCMCIA_CARD(PANASONIC, KXLC002, 0), 0xb4d00000 }, - { PCMCIA_CARD(PANASONIC, KXLC004, 0), 0xb4d00100 }, - { PCMCIA_CARD(MACNICA, MPS100, 0), 0xb6250000 }, - { PCMCIA_CARD(MACNICA, MPS110, 0), 0 }, - { PCMCIA_CARD(NEC, PC9801N_J03R, 0), 0 }, - { PCMCIA_CARD(NEWMEDIA, BASICS_SCSI, 0), 0 }, - { PCMCIA_CARD(QLOGIC, PC05, 0), 0x84d00000 }, -#define FLAGS_REX5572 0x84d00000 - { PCMCIA_CARD(RATOC, REX5572, 0), FLAGS_REX5572 }, - { PCMCIA_CARD(RATOC, REX9530, 0), 0x84d00000 }, - { { NULL }, 0 } -}; - -/* - * Additional code for FreeBSD new-bus PCCard frontend - */ - -static void -ncv_pccard_intr(void * arg) -{ - ncvintr(arg); -} - -static void -ncv_release_resource(DEVPORT_PDEVICE dev) -{ - struct ncv_softc *sc = device_get_softc(dev); - - if (sc->ncv_intrhand) { - bus_teardown_intr(dev, sc->irq_res, sc->ncv_intrhand); - } - - if (sc->port_res) { - bus_release_resource(dev, SYS_RES_IOPORT, - sc->port_rid, sc->port_res); - } - - if (sc->port_res_dmy) { - bus_release_resource(dev, SYS_RES_IOPORT, - sc->port_rid_dmy, sc->port_res_dmy); - } - - if (sc->irq_res) { - bus_release_resource(dev, SYS_RES_IRQ, - sc->irq_rid, sc->irq_res); - } - - if (sc->mem_res) { - bus_release_resource(dev, SYS_RES_MEMORY, - sc->mem_rid, sc->mem_res); - } -} - -static int -ncv_alloc_resource(DEVPORT_PDEVICE dev) -{ - struct ncv_softc *sc = device_get_softc(dev); - u_int32_t flags = DEVPORT_PDEVFLAGS(dev); - u_long ioaddr, iosize, maddr, msize; - int error; - bus_addr_t offset = 0; - - if(flags & KME_KXLC004_01) - offset = OFFSET_KME_KXLC004_01; - - error = bus_get_resource(dev, SYS_RES_IOPORT, 0, &ioaddr, &iosize); - if (error || (iosize < (offset + NCVIOSZ))) { - return(ENOMEM); - } - - sc->port_rid = 0; - sc->port_res = bus_alloc_resource(dev, SYS_RES_IOPORT, &sc->port_rid, - ioaddr+offset, ioaddr+iosize-offset, - iosize-offset, RF_ACTIVE); - if (sc->port_res == NULL) { - ncv_release_resource(dev); - return(ENOMEM); - } - - if (offset != 0) { - sc->port_rid_dmy = 0; - sc->port_res_dmy = bus_alloc_resource(dev, SYS_RES_IOPORT, - &sc->port_rid_dmy, - ioaddr, ioaddr+offset, offset, - RF_ACTIVE); - if (sc->port_res_dmy == NULL) { - kprintf("Warning: cannot allocate IOPORT partially.\n"); - } - } else { - sc->port_rid_dmy = 0; - sc->port_res_dmy = NULL; - } - - sc->irq_rid = 0; - sc->irq_res = bus_alloc_resource(dev, SYS_RES_IRQ, &sc->irq_rid, - 0, ~0, 1, RF_ACTIVE); - if (sc->irq_res == NULL) { - ncv_release_resource(dev); - return(ENOMEM); - } - - error = bus_get_resource(dev, SYS_RES_MEMORY, 0, &maddr, &msize); - if (error) { - return(0); /* XXX */ - } - - /* no need to allocate memory if not configured */ - if (maddr == 0 || msize == 0) { - return(0); - } - - sc->mem_rid = 0; - sc->mem_res = bus_alloc_resource(dev, SYS_RES_MEMORY, &sc->mem_rid, - 0, ~0, 1, RF_ACTIVE); - if (sc->mem_res == NULL) { - ncv_release_resource(dev); - return(ENOMEM); - } - - return(0); -} - -static int ncv_pccard_match(device_t dev) -{ - const struct ncv_product *pp; - const char *vendorstr; - const char *prodstr; - - if ((pp = (const struct ncv_product *) pccard_product_lookup(dev, - (const struct pccard_product *) ncv_products, - sizeof(ncv_products[0]), NULL)) != NULL) { - if (pp->prod.pp_name != NULL) - device_set_desc(dev, pp->prod.pp_name); - device_set_flags(dev, pp->flags); - return(0); - } - vendorstr = pccard_get_vendor_str(dev); - prodstr = pccard_get_product_str(dev); - if (strcmp(vendorstr, "RATOC System Inc.") == 0 && - strncmp(prodstr, "SOUND/SCSI2 CARD", 16) == 0) { - device_set_desc(dev, "RATOC REX-5572"); - device_set_flags(dev, FLAGS_REX5572); - return (0); - } - return(EIO); -} - -static int -ncv_pccard_probe(DEVPORT_PDEVICE dev) -{ - struct ncv_softc *sc = device_get_softc(dev); - int error; - - bzero(sc, sizeof(struct ncv_softc)); - - error = ncv_alloc_resource(dev); - if (error) { - return(error); - } - - if (ncvprobe(dev) == 0) { - ncv_release_resource(dev); - return(ENXIO); - } - - ncv_release_resource(dev); - - return(0); -} - -static int -ncv_pccard_attach(DEVPORT_PDEVICE dev) -{ - struct ncv_softc *sc = device_get_softc(dev); - int error; - - error = ncv_alloc_resource(dev); - if (error) { - return(error); - } - - error = bus_setup_intr(dev, sc->irq_res, 0, - ncv_pccard_intr, (void *)sc, - &sc->ncv_intrhand, NULL); - if (error) { - ncv_release_resource(dev); - return(error); - } - - if (ncvattach(dev) == 0) { - ncv_release_resource(dev); - return(ENXIO); - } - - return(0); -} - -static void -ncv_pccard_detach(DEVPORT_PDEVICE dev) -{ - ncv_card_unload(dev); - ncv_release_resource(dev); -} - -static device_method_t ncv_pccard_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, pccard_compat_probe), - DEVMETHOD(device_attach, pccard_compat_attach), - DEVMETHOD(device_detach, ncv_pccard_detach), - - /* Card interface */ - DEVMETHOD(card_compat_match, ncv_pccard_match), - DEVMETHOD(card_compat_probe, ncv_pccard_probe), - DEVMETHOD(card_compat_attach, ncv_pccard_attach), - - DEVMETHOD_END -}; - -static driver_t ncv_pccard_driver = { - "ncv", - ncv_pccard_methods, - sizeof(struct ncv_softc), -}; - -static devclass_t ncv_devclass; - -MODULE_DEPEND(ncv, scsi_low, 1, 1, 1); -DRIVER_MODULE(ncv, pccard, ncv_pccard_driver, ncv_devclass, NULL, NULL); - -static void -ncv_card_unload(DEVPORT_PDEVICE devi) -{ - struct ncv_softc *sc = DEVPORT_PDEVGET_SOFTC(devi); - - kprintf("%s: unload\n", sc->sc_sclow.sl_xname); - crit_enter(); - scsi_low_deactivate((struct scsi_low_softc *)sc); - scsi_low_dettach(&sc->sc_sclow); - crit_exit(); -} - -static int -ncvprobe(DEVPORT_PDEVICE devi) -{ - int rv; - struct ncv_softc *sc = device_get_softc(devi); - u_int32_t flags = DEVPORT_PDEVFLAGS(devi); - - rv = ncvprobesubr(rman_get_bustag(sc->port_res), - rman_get_bushandle(sc->port_res), - flags, NCV_HOSTID); - - return rv; -} - -static int -ncvattach(DEVPORT_PDEVICE devi) -{ - struct ncv_softc *sc; - struct scsi_low_softc *slp; - u_int32_t flags = DEVPORT_PDEVFLAGS(devi); - char dvname[16]; /* SCSI_LOW_DVNAME_LEN */ - - strcpy(dvname, "ncv"); - - sc = DEVPORT_PDEVALLOC_SOFTC(devi); - if (sc == NULL) { - return(0); - } - - slp = &sc->sc_sclow; - slp->sl_dev = devi; - sc->sc_iot = rman_get_bustag(sc->port_res); - sc->sc_ioh = rman_get_bushandle(sc->port_res); - - slp->sl_hostid = NCV_HOSTID; - slp->sl_cfgflags = flags; - - crit_enter(); - ncvattachsubr(sc); - crit_exit(); - - return(NCVIOSZ); -} diff --git a/sys/dev/disk/ncv/ncr53c500hw.h b/sys/dev/disk/ncv/ncr53c500hw.h deleted file mode 100644 index c3cacec69e..0000000000 --- a/sys/dev/disk/ncv/ncr53c500hw.h +++ /dev/null @@ -1,72 +0,0 @@ -/* $FreeBSD: src/sys/dev/ncv/ncr53c500hw.h,v 1.1.2.2 2001/07/22 00:21:39 non Exp $ */ -/* $DragonFly: src/sys/dev/disk/ncv/ncr53c500hw.h,v 1.3 2006/11/07 19:56:22 dillon Exp $ */ -/* $NecBSD: ncr53c500hw.h,v 1.6 1998/11/26 01:59:12 honda Exp $ */ -/* $NetBSD$ */ - -/* - * [NetBSD for NEC PC-98 series] - * Copyright (c) 1996, 1997, 1998 - * NetBSD/pc98 porting staff. All rights reserved. - * Copyright (c) 1996, 1997, 1998 - * Naofumi HONDA. All rights reserved. - * - * 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. - */ - -#ifndef __NCR53C500HW_H_ -#define __NCR53C500HW_H_ - -#include "dvcfg.h" - -#define NCV_HOSTID 7 -#define NCV_NTARGETS 8 -#define NCV_NLUNS 8 - -struct ncv_hw { - /* configuration images */ - u_int8_t hw_cfg1; - u_int8_t hw_cfg2; - u_int8_t hw_cfg3; - u_int8_t hw_cfg4; - u_int8_t hw_cfg5; - - /* synch */ - u_int8_t hw_clk; - u_int8_t hw_mperiod; - u_int8_t hw_moffset; - - /* cfg3 quirks */ - u_int8_t hw_cfg3_fscsi; - u_int8_t hw_cfg3_fclk; -}; - -/* dvcfg */ -#define NCV_C5IMG(flags) ((DVCFG_MAJOR(flags) >> 8) & 0xff) -#define NCV_CLKFACTOR(flags) (DVCFG_MAJOR(flags) & 0x0f) -#define NCVHWCFG_MAX10M 0x01 -#define NCVHWCFG_SCSI1 0x02 -#define NCVHWCFG_SLOW 0x04 -#define NCVHWCFG_FIFOBUG 0x08 -#define NCV_SPECIAL(flags) ((DVCFG_MAJOR(flags) >> 4) & 0x0f) -#endif /* !__NCR53C500HW_H_ */ diff --git a/sys/dev/disk/ncv/ncr53c500hwtab.h b/sys/dev/disk/ncv/ncr53c500hwtab.h deleted file mode 100644 index 7fb7c012ca..0000000000 --- a/sys/dev/disk/ncv/ncr53c500hwtab.h +++ /dev/null @@ -1,50 +0,0 @@ -/* $FreeBSD: src/sys/dev/ncv/ncr53c500hwtab.h,v 1.1.2.2 2001/07/22 00:21:39 non Exp $ */ -/* $DragonFly: src/sys/dev/disk/ncv/ncr53c500hwtab.h,v 1.2 2003/06/17 04:28:28 dillon Exp $ */ -/* $NecBSD: ncr53c500hwtab.h,v 1.2 1998/11/26 01:59:13 honda Exp $ */ -/* $NetBSD$ */ - -/* - * [NetBSD for NEC PC-98 series] - * Copyright (c) 1996, 1997, 1998 - * NetBSD/pc98 porting staff. All rights reserved. - * Copyright (c) 1996, 1997, 1998 - * Naofumi HONDA. All rights reserved. - * - * 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. - */ - -static struct ncv_hw ncv_template = { - 0, /* CFG1 img */ - C2_FE | C2_SCSI2, /* CFG2 img */ - 0, /* CFG3 img */ - C4_ANE, /* CFG4 img */ - 0x80, /* CFG5 img */ - - CLK_40M_F, /* clock */ - 200 / 4, /* max period */ - 15, /* max offset */ - - 0x10, /* CFG3_FSCSI bit */ - 0x08, /* CFG3_FCLK bit */ -}; diff --git a/sys/dev/disk/ncv/ncr53c500reg.h b/sys/dev/disk/ncv/ncr53c500reg.h deleted file mode 100644 index fe832e9467..0000000000 --- a/sys/dev/disk/ncv/ncr53c500reg.h +++ /dev/null @@ -1,188 +0,0 @@ -/* $FreeBSD: src/sys/dev/ncv/ncr53c500reg.h,v 1.1.2.2 2001/07/22 00:21:39 non Exp $ */ -/* $DragonFly: src/sys/dev/disk/ncv/ncr53c500reg.h,v 1.2 2003/06/17 04:28:28 dillon Exp $ */ -/* $NecBSD: ncr53c500reg.h,v 1.5 1998/12/26 11:50:01 honda Exp $ */ -/* $NetBSD$ */ - -/* - * [NetBSD for NEC PC-98 series] - * Copyright (c) 1995, 1996, 1997, 1998 - * NetBSD/pc98 porting staff. All rights reserved. - * Copyright (c) 1995, 1996, 1997, 1998 - * Naofumi HONDA. All rights reserved. - * Copyright (c) 1995, 1996, 1997, 1998 - * Kouichi Matsuda. All rights reserved. - * - * 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. - */ - -#ifndef _NCR53C500REG_H_ -#define _NCR53C500REG_H_ - -/* Control Register Set 0 */ -#define NCVIOSZ 0x10 - -#define cr0_tclsb 0x00 /* RW - Transfer Count Low */ -#define cr0_tcmsb 0x01 /* RW - Transfer Count Mid */ -#define cr0_sfifo 0x02 /* RW - FIFO data */ -#define cr0_cmd 0x03 /* RW - Command (2 deep) */ -#define cr0_stat 0x04 /* RO - Status */ -#define cr0_dstid 0x04 /* WO - Select/Reselect Bus ID */ -#define cr0_istat 0x05 /* RO - Interrupt */ -#define cr0_srtout 0x05 /* WO - Select/Reselect Timeout */ -#define cr0_seq 0x06 /* RO - Sequence Step */ -#define cr0_period 0x06 /* WO - Synch Transfer Period */ -#define cr0_sffl 0x07 /* RO - FIFO FLags */ -#define cr0_offs 0x07 /* WO - Synch Ofset */ -#define cr0_cfg1 0x08 /* RW - Configuration #1 */ -#define cr0_clk 0x09 /* WO - Clock Conversion Factor */ -#define cr0_tst 0x0a /* WO - Test (Chip Test Only) */ -#define cr0_cfg2 0x0b /* RW - Configuration #2 */ -#define cr0_cfg3 0x0c /* RW - Configuration #3 */ -#define cr0_cfg4 0x0d /* RW - Configuration #4 */ -#define cr0_tchsb 0x0e /* RW - Transfer Count High */ -#define cr0_fifo_bottom 0x0f /* WO - FIFO bottom */ - -/* Control Register Set 1 */ -#define cr1_jumper 0x00 /* RW - Jumper Sense Port */ -#define cr1_sram_ptr 0x01 /* RW - SRAM Address Pointer */ -#define cr1_sram_data 0x02 /* RW - SRAM Data */ -#define cr1_fdata 0x04 /* RW - PIO FIFO */ -#define cr1_fstat 0x08 /* RW - PIO Status */ -#define cr1_atacmd 0x09 /* RW - ATA Command/Status */ -#define cr1_ataerr 0x0a /* RW - ATA Features/Error */ -#define cr1_pflag 0x0b /* RW - PIO Flag Interrupt Enable */ -#define cr1_cfg5 0x0d /* RW - Configuration #5 */ -#define cr1_sig 0x0e /* RO - Signature */ -#define cr1_cfg6 0x0f /* RW - Configuration #6 */ - -/* atacmd (MPS110 ONLY) */ -#define ATACMD_POWDOWN 0x2d -#define ATACMD_ENGAGE 0x24 - -/* cr0_sffl regster */ -#define CR0_SFFLR_BMASK 0x1f /* scsi fifo byte mask */ - -/* cfg4 */ -#define C4_ANE 0x04 - -/* cfg2 */ -#define C2_SCSI2 0x08 /* SCSI-2 Enable */ -#define C2_FE 0x40 /* Features Enable */ - -/* cfg1 */ -#define C1_SLOW 0x80 /* Slow Cable Mode */ -#define C1_SRR 0x40 /* SCSI Reset Rep Int Dis */ -#define C1_PARENB 0x10 /* Enable Parity Check */ - -/* clk factor */ -#define CLK_40M_F 0x00 -#define CLK_25M_F 0x05 -#define CLK_30M_F 0x06 -#define CLK_35M_F 0x07 - -/* interrupt status register */ -#define INTR_SBR 0x80 /* SCSI Bus Reset */ -#define INTR_ILL 0x40 /* Illegal Command */ -#define INTR_DIS 0x20 /* Disconnect */ -#define INTR_BS 0x10 /* Bus Service */ -#define INTR_FC 0x08 /* Function Complete */ -#define INTR_RESEL 0x04 /* Reselected */ -#define INTR_SELATN 0x02 /* Select with ATN */ -#define INTR_SEL 0x01 /* Selected */ -#define INTR_RESELECT (INTR_RESEL | INTR_FC) - -/* status register */ -#define STAT_INT 0x80 /* Interrupt */ -#define STAT_GE 0x40 /* Gross Error */ -#define STAT_PE 0x20 /* Parity Error */ -#define STAT_TC 0x10 /* Terminal Count */ - -/* phase bits */ -#define IOI 0x01 -#define CDI 0x02 -#define MSGI 0x04 - -/* Information transfer phases */ -#define DATA_OUT_PHASE (0) -#define DATA_IN_PHASE (IOI) -#define COMMAND_PHASE (CDI) -#define STATUS_PHASE (CDI|IOI) -#define MESSAGE_OUT_PHASE (MSGI|CDI) -#define MESSAGE_IN_PHASE (MSGI|CDI|IOI) - -#define PHASE_MASK (MSGI|CDI|IOI) - -/* fifo status register */ -#define FIFO_SMASK 0x1e -#define FIFO_E 0x10 /* fifo empty */ -#define FIFO_B 0x00 /* there exists any */ -#define FIFO_1 0x08 /* 1/3 <= bytes < 2/3 */ -#define FIFO_2 0x04 /* 2/3 <= bytes < full */ -#define FIFO_F 0x02 /* full */ -#define FIFO_EN 0x01 /* fifo direction */ -#define FIFO_BRK 0x40 /* phase miss */ - -#define FIFO_F_SZ 128 -#define FIFO_1_SZ 44 -#define FIFO_2_SZ 84 - -/* pflags */ -#define PFR_WRITE 0x01 - -/* Commands */ -#define CMD_DMA 0x80 /* DMA Bit */ -#define CMD_NOP 0x00 /* No Operation */ -#define CMD_FLUSH 0x01 /* Flush FIFO */ -#define CMD_RSTCHIP 0x02 /* Reset Chip */ -#define CMD_RSTSCSI 0x03 /* Reset SCSI Bus */ -#define CMD_RESEL 0x40 /* Reselect Sequence */ -#define CMD_SELNATN 0x41 /* Select without ATN */ -#define CMD_SELATN 0x42 /* Select with ATN */ -#define CMD_SELATNS 0x43 /* Select with ATN & Stop */ -#define CMD_ENSEL 0x44 /* Enable (Re)Selection */ -#define CMD_DISSEL 0x45 /* Disable (Re)Selection */ -#define CMD_SELATN3 0x46 /* Select with ATN3 */ -#define CMD_RESEL3 0x47 /* Reselect3 Sequence */ -#define CMD_SNDMSG 0x20 /* Send Message */ -#define CMD_SNDSTAT 0x21 /* Send Status */ -#define CMD_SNDDATA 0x22 /* Send Data */ -#define CMD_DISCSEQ 0x23 /* Disconnect Sequence */ -#define CMD_TERMSEQ 0x24 /* Terminate Sequence */ -#define CMD_TCCS 0x25 /* Target Command Comp Seq */ -#define CMD_DISC 0x27 /* Disconnect */ -#define CMD_RECMSG 0x28 /* Receive Message */ -#define CMD_RECCMD 0x29 /* Receive Command */ -#define CMD_RECDATA 0x2a /* Receive Data */ -#define CMD_RECCSEQ 0x2b /* Receive Command Sequence */ -#define CMD_ABORT 0x04 /* Target Abort DMA */ -#define CMD_TRANS 0x10 /* Transfer Information */ -#define CMD_ICCS 0x11 /* Initiator Cmd Comp Seq */ -#define CMD_MSGOK 0x12 /* Message Accepted */ -#define CMD_TRPAD 0x18 /* Transfer Pad */ -#define CMD_SETATN 0x1a /* Set ATN */ -#define CMD_RSTATN 0x1b /* Reset ATN */ - -/* Default timeout */ -#define SEL_TOUT 0xa3 -#endif /* !_NCR53C500REG_H_ */ diff --git a/sys/dev/disk/ncv/ncr53c500var.h b/sys/dev/disk/ncv/ncr53c500var.h deleted file mode 100644 index 958e6103b1..0000000000 --- a/sys/dev/disk/ncv/ncr53c500var.h +++ /dev/null @@ -1,101 +0,0 @@ -/* $FreeBSD: src/sys/dev/ncv/ncr53c500var.h,v 1.1.2.4 2001/12/17 13:30:18 non Exp $ */ -/* $DragonFly: src/sys/dev/disk/ncv/ncr53c500var.h,v 1.4 2004/02/12 00:00:15 dillon Exp $ */ -/* $NecBSD: ncr53c500var.h,v 1.11.18.1 2001/06/08 06:27:45 honda Exp $ */ -/* $NetBSD$ */ - -/* - * [NetBSD for NEC PC-98 series] - * Copyright (c) 1995, 1996, 1997, 1998, 1999, 2000, 2001 - * NetBSD/pc98 porting staff. All rights reserved. - * Copyright (c) 1995, 1996, 1997, 1998, 1999, 2000, 2001 - * Naofumi HONDA. All rights reserved. - * - * 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. - */ - -#ifndef _NCR53C500VAR_H_ -#define _NCR53C500VAR_H_ - -/***************************************************************** - * Host adapter structure - *****************************************************************/ -struct ncv_softc { - struct scsi_low_softc sc_sclow; /* generic data */ - -#ifdef __NetBSD__ - bus_space_tag_t sc_iot; - bus_space_tag_t sc_memt; - bus_space_handle_t sc_ioh; - - void *sc_ih; -#endif /* __NetBSD__ */ - -#ifdef __DragonFly__ - bus_space_tag_t sc_iot; - bus_space_tag_t sc_memt; - bus_space_handle_t sc_ioh; - - int port_rid; - int port_rid_dmy; - int irq_rid; - int mem_rid; - struct resource *port_res; - struct resource *port_res_dmy; - struct resource *irq_res; - struct resource *mem_res; - - void *ncv_intrhand; -#endif /* __DragonFly__ */ - - int sc_tmaxcnt; - int sc_selstop; /* sel atn stop asserted */ - int sc_compseq; /* completion seq cmd asserted */ - int sc_sdatalen; /* start datalen */ - int sc_tdatalen; /* temp xfer data len */ - - struct ncv_hw sc_hw; /* hardware register images */ -}; - -/***************************************************************** - * Lun information - *****************************************************************/ -struct ncv_targ_info { - struct targ_info nti_ti; - - u_int8_t nti_reg_cfg3; /* cfg3 images per lun */ - u_int8_t nti_reg_offset; /* synch offset register per lun */ - u_int8_t nti_reg_period; /* synch period register per lun */ -}; - -/***************************************************************** - * Proto - *****************************************************************/ -int ncvprobesubr (bus_space_tag_t, bus_space_handle_t ioh, u_int, int); -void ncvattachsubr (struct ncv_softc *); -int ncvprint (void *, const char *); -int ncvintr (void *); - -#define SOFT_INTR_REQUIRED(slp) - -#endif /* !_NCR53C500VAR_H_ */ diff --git a/sys/dev/disk/nsp/Makefile b/sys/dev/disk/nsp/Makefile deleted file mode 100644 index f039022e5c..0000000000 --- a/sys/dev/disk/nsp/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -# $FreeBSD: src/sys/modules/nsp/Makefile,v 1.1.2.2 2002/01/02 07:59:12 non Exp $ - -KMOD= nsp -SRCS= nsp.c nsp_pccard.c -SRCS+= device_if.h bus_if.h pci_if.h isa_if.h card_if.h pccarddevs.h -SRCS+= opt_cam.h opt_scsi.h opt_ddb.h - -.include diff --git a/sys/dev/disk/nsp/nsp.c b/sys/dev/disk/nsp/nsp.c deleted file mode 100644 index da2b0d98dc..0000000000 --- a/sys/dev/disk/nsp/nsp.c +++ /dev/null @@ -1,1826 +0,0 @@ -/* $FreeBSD: src/sys/dev/nsp/nsp.c,v 1.1.2.6 2001/12/17 13:30:18 non Exp $ */ -/* $NecBSD: nsp.c,v 1.21.12.6 2001/06/29 06:27:52 honda Exp $ */ -/* $NetBSD$ */ - -#define NSP_DEBUG -#define NSP_STATICS -#define NSP_IO_CONTROL_FLAGS \ - (NSP_READ_SUSPEND_IO | NSP_WRITE_SUSPEND_IO | \ - NSP_READ_FIFO_INTERRUPTS | NSP_WRITE_FIFO_INTERRUPTS | \ - NSP_USE_MEMIO | NSP_WAIT_FOR_SELECT) - -/* - * Copyright (c) 1998, 1999, 2000, 2001 - * NetBSD/pc98 porting staff. All rights reserved. - * - * Copyright (c) 1998, 1999, 2000, 2001 - * Naofumi HONDA. All rights reserved. - * - * 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. - */ -#include "opt_ddb.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include "nspreg.h" -#include "nspvar.h" - -/*************************************************** - * USER SETTINGS - ***************************************************/ -/* DEVICE CONFIGURATION FLAGS (MINOR) - * - * 0x01 DISCONECT OFF - * 0x02 PARITY LINE OFF - * 0x04 IDENTIFY MSG OFF ( = single lun) - * 0x08 SYNC TRANSFER OFF - */ - -/*************************************************** - * PARAMS - ***************************************************/ -#define NSP_NTARGETS 8 -#define NSP_NLUNS 8 - -#define NSP_MAX_DATA_SIZE (64 * 1024) -#define NSP_SELTIMEOUT (200) -#define NSP_DELAY_MAX (2 * 1000 * 1000) -#define NSP_DELAY_INTERVAL (1) -#define NSP_TIMER_1MS (1000 / 51) - -/*************************************************** - * DEBUG - ***************************************************/ -#ifdef NSP_DEBUG -int nsp_debug; -#endif /* NSP_DEBUG */ - -#ifdef NSP_STATICS -struct nsp_statics { - int arbit_conflict_1; - int arbit_conflict_2; - int device_data_write; - int device_busy; - int disconnect; - int reselect; - int data_phase_bypass; -} nsp_statics; -#endif /* NSP_STATICS */ - -/*************************************************** - * IO control - ***************************************************/ -#define NSP_READ_SUSPEND_IO 0x0001 -#define NSP_WRITE_SUSPEND_IO 0x0002 -#define NSP_USE_MEMIO 0x0004 -#define NSP_READ_FIFO_INTERRUPTS 0x0010 -#define NSP_WRITE_FIFO_INTERRUPTS 0x0020 -#define NSP_WAIT_FOR_SELECT 0x0100 - -u_int nsp_io_control = NSP_IO_CONTROL_FLAGS; -int nsp_read_suspend_bytes = DEV_BSIZE; -int nsp_write_suspend_bytes = DEV_BSIZE; -int nsp_read_interrupt_bytes = 4096; -int nsp_write_interrupt_bytes = 4096; - -/************************************************************** - * DECLARE - **************************************************************/ -#define NSP_FIFO_ON 1 -#define NSP_FIFO_OFF 0 -static void nsp_pio_read (struct nsp_softc *, int); -static void nsp_pio_write (struct nsp_softc *, int); -static int nsp_xfer (struct nsp_softc *, u_int8_t *, int, int, int); -static int nsp_msg (struct nsp_softc *, struct targ_info *, u_int); -static int nsp_reselected (struct nsp_softc *); -static int nsp_disconnected (struct nsp_softc *, struct targ_info *); -static void nsp_pdma_end (struct nsp_softc *, struct targ_info *); -static void nsphw_init (struct nsp_softc *); -static int nsp_target_nexus_establish (struct nsp_softc *); -static int nsp_lun_nexus_establish (struct nsp_softc *); -static int nsp_ccb_nexus_establish (struct nsp_softc *); -static int nsp_world_start (struct nsp_softc *, int); -static int nsphw_start_selection (struct nsp_softc *sc, struct slccb *); -static void nsphw_bus_reset (struct nsp_softc *); -static void nsphw_attention (struct nsp_softc *); -static u_int nsp_fifo_count (struct nsp_softc *); -static u_int nsp_request_count (struct nsp_softc *); -static int nsp_negate_signal (struct nsp_softc *, u_int8_t, u_char *); -static int nsp_expect_signal (struct nsp_softc *, u_int8_t, u_int8_t); -static void nsp_start_timer (struct nsp_softc *, int); -static void nsp_setup_fifo (struct nsp_softc *, int, int, int); -static int nsp_targ_init (struct nsp_softc *, struct targ_info *, int); -static void nsphw_selection_done_and_expect_msgout (struct nsp_softc *); -static void nsp_data_padding (struct nsp_softc *, int, u_int); -static int nsp_timeout (struct nsp_softc *); -static int nsp_read_fifo (struct nsp_softc *, int); -static int nsp_write_fifo (struct nsp_softc *, int); -static int nsp_phase_match (struct nsp_softc *, u_int8_t, u_int8_t); -static int nsp_wait_interrupt (struct nsp_softc *); - -struct scsi_low_funcs nspfuncs = { - SC_LOW_INIT_T nsp_world_start, - SC_LOW_BUSRST_T nsphw_bus_reset, - SC_LOW_TARG_INIT_T nsp_targ_init, - SC_LOW_LUN_INIT_T NULL, - - SC_LOW_SELECT_T nsphw_start_selection, - SC_LOW_NEXUS_T nsp_lun_nexus_establish, - SC_LOW_NEXUS_T nsp_ccb_nexus_establish, - - SC_LOW_ATTEN_T nsphw_attention, - SC_LOW_MSG_T nsp_msg, - - SC_LOW_TIMEOUT_T nsp_timeout, - SC_LOW_POLL_T nspintr, - - NULL, -}; - -/**************************************************** - * hwfuncs - ****************************************************/ -static __inline u_int8_t nsp_cr_read_1 (bus_space_tag_t bst, bus_space_handle_t bsh, bus_addr_t ofs); -static __inline void nsp_cr_write_1 (bus_space_tag_t bst, bus_space_handle_t bsh, bus_addr_t ofs, u_int8_t va); - -static __inline u_int8_t -nsp_cr_read_1(bus_space_tag_t bst, bus_space_handle_t bsh, bus_addr_t ofs) -{ - - bus_space_write_1(bst, bsh, nsp_idxr, ofs); - return bus_space_read_1(bst, bsh, nsp_datar); -} - -static __inline void -nsp_cr_write_1(bus_space_tag_t bst, bus_space_handle_t bsh, bus_addr_t ofs, - u_int8_t va) -{ - - bus_space_write_1(bst, bsh, nsp_idxr, ofs); - bus_space_write_1(bst, bsh, nsp_datar, va); -} - -static int -nsp_expect_signal(struct nsp_softc *sc, u_int8_t curphase, u_int8_t mask) -{ - struct scsi_low_softc *slp = &sc->sc_sclow; - bus_space_tag_t bst = sc->sc_iot; - bus_space_handle_t bsh = sc->sc_ioh; - int wc; - u_int8_t ph, isrc; - - for (wc = 0; wc < NSP_DELAY_MAX / NSP_DELAY_INTERVAL; wc ++) - { - ph = nsp_cr_read_1(bst, bsh, NSPR_SCBUSMON); - if (ph == (u_int8_t) -1) - return -1; - - isrc = bus_space_read_1(bst, bsh, nsp_irqsr); - if (isrc & IRQSR_SCSI) - return 0; - - if ((ph & mask) != 0 && (ph & SCBUSMON_PHMASK) == curphase) - return 1; - - SCSI_LOW_DELAY(NSP_DELAY_INTERVAL); - } - - kprintf("%s: nsp_expect_signal timeout\n", slp->sl_xname); - return -1; -} - -static void -nsphw_init(struct nsp_softc *sc) -{ - bus_space_tag_t bst = sc->sc_iot; - bus_space_handle_t bsh = sc->sc_ioh; - - /* block all interrupts */ - bus_space_write_1(bst, bsh, nsp_irqcr, IRQCR_ALLMASK); - - /* setup SCSI interface */ - bus_space_write_1(bst, bsh, nsp_ifselr, IFSELR_IFSEL); - - nsp_cr_write_1(bst, bsh, NSPR_SCIENR, 0); - - nsp_cr_write_1(bst, bsh, NSPR_XFERMR, XFERMR_IO8); - nsp_cr_write_1(bst, bsh, NSPR_CLKDIVR, sc->sc_iclkdiv); - - nsp_cr_write_1(bst, bsh, NSPR_SCIENR, sc->sc_icr); - nsp_cr_write_1(bst, bsh, NSPR_PARITYR, sc->sc_parr); - nsp_cr_write_1(bst, bsh, NSPR_PTCLRR, - PTCLRR_ACK | PTCLRR_REQ | PTCLRR_HOST | PTCLRR_RSS); - - /* setup fifo asic */ - bus_space_write_1(bst, bsh, nsp_ifselr, IFSELR_REGSEL); - nsp_cr_write_1(bst, bsh, NSPR_TERMPWRC, 0); - if ((nsp_cr_read_1(bst, bsh, NSPR_OCR) & OCR_TERMPWRS) == 0) - nsp_cr_write_1(bst, bsh, NSPR_TERMPWRC, TERMPWRC_POWON); - - nsp_cr_write_1(bst, bsh, NSPR_XFERMR, XFERMR_IO8); - nsp_cr_write_1(bst, bsh, NSPR_CLKDIVR, sc->sc_clkdiv); - nsp_cr_write_1(bst, bsh, NSPR_TIMERCNT, 0); - nsp_cr_write_1(bst, bsh, NSPR_TIMERCNT, 0); - - nsp_cr_write_1(bst, bsh, NSPR_SYNCR, 0); - nsp_cr_write_1(bst, bsh, NSPR_ACKWIDTH, 0); - - /* enable interrupts and ack them */ - nsp_cr_write_1(bst, bsh, NSPR_SCIENR, sc->sc_icr); - bus_space_write_1(bst, bsh, nsp_irqcr, IRQSR_MASK); - - nsp_setup_fifo(sc, NSP_FIFO_OFF, SCSI_LOW_READ, 0); -} - -/**************************************************** - * scsi low interface - ****************************************************/ -static void -nsphw_attention(struct nsp_softc *sc) -{ - bus_space_tag_t bst = sc->sc_iot; - bus_space_handle_t bsh = sc->sc_ioh; - u_int8_t cr; - - cr = nsp_cr_read_1(bst, bsh, NSPR_SCBUSCR)/* & ~SCBUSCR_ACK */; - nsp_cr_write_1(bst, bsh, NSPR_SCBUSCR, cr | SCBUSCR_ATN); - SCSI_LOW_DELAY(10); -} - -static void -nsphw_bus_reset(struct nsp_softc *sc) -{ - bus_space_tag_t bst = sc->sc_iot; - bus_space_handle_t bsh = sc->sc_ioh; - int i; - - bus_space_write_1(bst, bsh, nsp_irqcr, IRQCR_ALLMASK); - - nsp_cr_write_1(bst, bsh, NSPR_SCBUSCR, SCBUSCR_RST); - SCSI_LOW_DELAY(100 * 1000); /* 100ms */ - nsp_cr_write_1(bst, bsh, NSPR_SCBUSCR, 0); - for (i = 0; i < 5; i ++) - (void) nsp_cr_read_1(bst, bsh, NSPR_IRQPHS); - - bus_space_write_1(bst, bsh, nsp_irqcr, IRQSR_MASK); -} - -static void -nsphw_selection_done_and_expect_msgout(struct nsp_softc *sc) -{ - struct scsi_low_softc *slp = &sc->sc_sclow; - bus_space_tag_t bst = sc->sc_iot; - bus_space_handle_t bsh = sc->sc_ioh; - - /* clear ack counter */ - sc->sc_cnt = 0; - nsp_cr_write_1(bst, bsh, NSPR_PTCLRR, PTCLRR_PT | PTCLRR_ACK | - PTCLRR_REQ | PTCLRR_HOST); - - /* deassert sel and assert atten */ - sc->sc_seltout = 0; - nsp_cr_write_1(bst, bsh, NSPR_SCBUSCR, sc->sc_busc); - SCSI_LOW_DELAY(1); - nsp_cr_write_1(bst, bsh, NSPR_SCBUSCR, - sc->sc_busc | SCBUSCR_ADIR | SCBUSCR_ACKEN); - SCSI_LOW_ASSERT_ATN(slp); -} - -static int -nsphw_start_selection(struct nsp_softc *sc, struct slccb *cb) -{ - struct scsi_low_softc *slp = &sc->sc_sclow; - bus_space_tag_t bst = sc->sc_iot; - bus_space_handle_t bsh = sc->sc_ioh; - struct targ_info *ti = cb->ti; - u_int8_t arbs, ph; - int wc; - - wc = sc->sc_tmaxcnt = cb->ccb_tcmax * 1000 * 1000; - sc->sc_dataout_timeout = 0; - - /* check bus free */ - crit_enter(); - ph = nsp_cr_read_1(bst, bsh, NSPR_SCBUSMON); - if (ph != SCBUSMON_FREE) - { - crit_exit(); -#ifdef NSP_STATICS - nsp_statics.arbit_conflict_1 ++; -#endif /* NSP_STATICS */ - return SCSI_LOW_START_FAIL; - } - - /* start arbitration */ - nsp_cr_write_1(bst, bsh, NSPR_ARBITS, ARBITS_EXEC); - crit_exit(); - - SCSI_LOW_SETUP_PHASE(ti, PH_ARBSTART); - do - { - /* XXX: what a stupid chip! */ - arbs = nsp_cr_read_1(bst, bsh, NSPR_ARBITS); - SCSI_LOW_DELAY(1); - } - while ((arbs & (ARBITS_WIN | ARBITS_FAIL)) == 0 && wc -- > 0); - - if ((arbs & ARBITS_WIN) == 0) - { - nsp_cr_write_1(bst, bsh, NSPR_ARBITS, ARBITS_CLR); -#ifdef NSP_STATICS - nsp_statics.arbit_conflict_2 ++; -#endif /* NSP_STATICS */ - return SCSI_LOW_START_FAIL; - } - - /* assert select line */ - SCSI_LOW_SETUP_PHASE(ti, PH_SELSTART); - scsi_low_arbit_win(slp); - - crit_enter(); - SCSI_LOW_DELAY(3); - nsp_cr_write_1(bst, bsh, NSPR_DATA, - sc->sc_idbit | (1 << ti->ti_id)); - nsp_cr_write_1(bst, bsh, NSPR_SCBUSCR, - SCBUSCR_SEL | SCBUSCR_BSY | sc->sc_busc); - SCSI_LOW_DELAY(3); - nsp_cr_write_1(bst, bsh, NSPR_SCBUSCR, SCBUSCR_SEL | - SCBUSCR_BSY | SCBUSCR_DOUT | sc->sc_busc); - nsp_cr_write_1(bst, bsh, NSPR_ARBITS, ARBITS_CLR); - SCSI_LOW_DELAY(3); - nsp_cr_write_1(bst, bsh, NSPR_SCBUSCR, - SCBUSCR_SEL | SCBUSCR_DOUT | sc->sc_busc); - SCSI_LOW_DELAY(1); - - if ((nsp_io_control & NSP_WAIT_FOR_SELECT) != 0) - { -#define NSP_FIRST_SEL_WAIT 300 -#define NSP_SEL_CHECK_INTERVAL 10 - - /* wait for a selection response */ - for (wc = 0; wc < NSP_FIRST_SEL_WAIT / NSP_SEL_CHECK_INTERVAL; - wc ++) - { - ph = nsp_cr_read_1(bst, bsh, NSPR_SCBUSMON); - if ((ph & SCBUSMON_BSY) == 0) - { - SCSI_LOW_DELAY(NSP_SEL_CHECK_INTERVAL); - continue; - } - - SCSI_LOW_DELAY(1); - ph = nsp_cr_read_1(bst, bsh, NSPR_SCBUSMON); - if ((ph & SCBUSMON_BSY) != 0) - { - nsphw_selection_done_and_expect_msgout(sc); - crit_exit(); - - SCSI_LOW_SETUP_PHASE(ti, PH_SELECTED); - return SCSI_LOW_START_OK; - } - } - } - crit_exit(); - - /* check a selection timeout */ - nsp_start_timer(sc, NSP_TIMER_1MS); - sc->sc_seltout = 1; - return SCSI_LOW_START_OK; -} - -static int -nsp_world_start(struct nsp_softc *sc, int fdone) -{ - struct scsi_low_softc *slp = &sc->sc_sclow; - - sc->sc_cnt = 0; - sc->sc_seltout = 0; - - if ((slp->sl_cfgflags & CFG_NOATTEN) == 0) - sc->sc_busc = SCBUSCR_ATN; - else - sc->sc_busc = 0; - - if ((slp->sl_cfgflags & CFG_NOPARITY) == 0) - sc->sc_parr = PARITYR_ENABLE | PARITYR_CLEAR; - else - sc->sc_parr = 0; - - sc->sc_icr = (SCIENR_SCCHG | SCIENR_RESEL | SCIENR_RST); - - nsphw_init(sc); - scsi_low_bus_reset(slp); - - SOFT_INTR_REQUIRED(slp); - return 0; -} - -struct ncp_synch_data { - u_int min_period; - u_int max_period; - u_int chip_period; - u_int ack_width; -}; - -static struct ncp_synch_data ncp_sync_data_40M[] = { - {0x0c,0x0c,0x1,0}, /* 20MB 50ns*/ - {0x19,0x19,0x3,1}, /* 10MB 100ns*/ - {0x1a,0x25,0x5,2}, /* 7.5MB 150ns*/ - {0x26,0x32,0x7,3}, /* 5MB 200ns*/ - {0x0, 0, 0, 0} -}; - -static struct ncp_synch_data ncp_sync_data_20M[] = { - {0x19,0x19,0x1,0}, /* 10MB 100ns*/ - {0x1a,0x25,0x2,0}, /* 7.5MB 150ns*/ - {0x26,0x32,0x3,1}, /* 5MB 200ns*/ - {0x0, 0, 0, 0} -}; - -static int -nsp_msg(struct nsp_softc *sc, struct targ_info *ti, u_int msg) -{ - bus_space_tag_t bst = sc->sc_iot; - bus_space_handle_t bsh = sc->sc_ioh; - struct ncp_synch_data *sdp; - struct nsp_targ_info *nti = (void *) ti; - u_int period, offset; - int i, error; - - if ((msg & SCSI_LOW_MSG_WIDE) != 0) - { - if (ti->ti_width != SCSI_LOW_BUS_WIDTH_8) - { - ti->ti_width = SCSI_LOW_BUS_WIDTH_8; - return EINVAL; - } - return 0; - } - - if ((msg & SCSI_LOW_MSG_SYNCH) == 0) - return 0; - - period = ti->ti_maxsynch.period; - offset = ti->ti_maxsynch.offset; - if (sc->sc_iclkdiv == CLKDIVR_20M) - sdp = &ncp_sync_data_20M[0]; - else - sdp = &ncp_sync_data_40M[0]; - - for (i = 0; sdp->max_period != 0; i ++, sdp ++) - { - if (period >= sdp->min_period && period <= sdp->max_period) - break; - } - - if (period != 0 && sdp->max_period == 0) - { - /* - * NO proper period/offset found, - * Retry neg with the target. - */ - ti->ti_maxsynch.period = 0; - ti->ti_maxsynch.offset = 0; - nti->nti_reg_syncr = 0; - nti->nti_reg_ackwidth = 0; - error = EINVAL; - } - else - { - nti->nti_reg_syncr = (sdp->chip_period << SYNCR_PERS) | - (offset & SYNCR_OFFM); - nti->nti_reg_ackwidth = sdp->ack_width; - error = 0; - } - - nsp_cr_write_1(bst, bsh, NSPR_SYNCR, nti->nti_reg_syncr); - nsp_cr_write_1(bst, bsh, NSPR_ACKWIDTH, nti->nti_reg_ackwidth); - return error; -} - -static int -nsp_targ_init(struct nsp_softc *sc, struct targ_info *ti, int action) -{ - struct nsp_targ_info *nti = (void *) ti; - - if (action == SCSI_LOW_INFO_ALLOC || action == SCSI_LOW_INFO_REVOKE) - { - ti->ti_width = SCSI_LOW_BUS_WIDTH_8; - ti->ti_maxsynch.period = 100 / 4; - ti->ti_maxsynch.offset = 15; - nti->nti_reg_syncr = 0; - nti->nti_reg_ackwidth = 0; - } - return 0; -} - -static void -nsp_start_timer(struct nsp_softc *sc, int time) -{ - bus_space_tag_t bst = sc->sc_iot; - bus_space_handle_t bsh = sc->sc_ioh; - - sc->sc_timer = time; - nsp_cr_write_1(bst, bsh, NSPR_TIMERCNT, time); -} - -/************************************************************** - * General probe attach - **************************************************************/ -int -nspprobesubr(bus_space_tag_t iot, bus_space_handle_t ioh, u_int dvcfg) -{ - u_int8_t regv; - - regv = bus_space_read_1(iot, ioh, nsp_fifosr); - if (regv < 0x11 || regv >= 0x20) - return 0; - return 1; -} - -int -nspprint(void *aux, const char *name) -{ - - if (name != NULL) - kprintf("%s: scsibus ", name); - return UNCONF; -} - -void -nspattachsubr(struct nsp_softc *sc) -{ - struct scsi_low_softc *slp = &sc->sc_sclow; - - kprintf("\n"); - - sc->sc_idbit = (1 << slp->sl_hostid); - slp->sl_flags |= HW_READ_PADDING; - slp->sl_funcs = &nspfuncs; - sc->sc_tmaxcnt = SCSI_LOW_MIN_TOUT * 1000 * 1000; /* default */ - - (void) scsi_low_attach(slp, 0, NSP_NTARGETS, NSP_NLUNS, - sizeof(struct nsp_targ_info), 0); -} - -/************************************************************** - * PDMA functions - **************************************************************/ -static u_int -nsp_fifo_count(struct nsp_softc *sc) -{ - bus_space_tag_t bst = sc->sc_iot; - bus_space_handle_t bsh = sc->sc_ioh; - u_int count; - - nsp_cr_write_1(bst, bsh, NSPR_PTCLRR, PTCLRR_RSS_ACK | PTCLRR_PT); - count = bus_space_read_1(bst, bsh, nsp_datar); - count += (((u_int) bus_space_read_1(bst, bsh, nsp_datar)) << 8); - count += (((u_int) bus_space_read_1(bst, bsh, nsp_datar)) << 16); - return count; -} - -static u_int -nsp_request_count(struct nsp_softc *sc) -{ - bus_space_tag_t bst = sc->sc_iot; - bus_space_handle_t bsh = sc->sc_ioh; - u_int count; - - nsp_cr_write_1(bst, bsh, NSPR_PTCLRR, PTCLRR_RSS_REQ | PTCLRR_PT); - count = bus_space_read_1(bst, bsh, nsp_datar); - count += (((u_int) bus_space_read_1(bst, bsh, nsp_datar)) << 8); - count += (((u_int) bus_space_read_1(bst, bsh, nsp_datar)) << 16); - return count; -} - -static void -nsp_setup_fifo(struct nsp_softc *sc, int on, int direction, int datalen) -{ - u_int8_t xfermode; - - sc->sc_suspendio = 0; - if (on == NSP_FIFO_OFF) - { - xfermode = XFERMR_IO8; - goto out; - } - - /* check if suspend io OK ? */ - if (datalen > 0) - { - if (direction == SCSI_LOW_READ) - { - if ((nsp_io_control & NSP_READ_SUSPEND_IO) != 0 && - (datalen % nsp_read_suspend_bytes) == 0) - sc->sc_suspendio = nsp_read_suspend_bytes; - } - else - { - if ((nsp_io_control & NSP_WRITE_SUSPEND_IO) != 0 && - (datalen % nsp_write_suspend_bytes) == 0) - sc->sc_suspendio = nsp_write_suspend_bytes; - } - } - - /* determine a transfer type */ - if (datalen < DEV_BSIZE || (datalen & 3) != 0) - { - if (sc->sc_memh != 0 && - (nsp_io_control & NSP_USE_MEMIO) != 0) - xfermode = XFERMR_XEN | XFERMR_MEM8; - else - xfermode = XFERMR_XEN | XFERMR_IO8; - } - else - { - if (sc->sc_memh != 0 && - (nsp_io_control & NSP_USE_MEMIO) != 0) - xfermode = XFERMR_XEN | XFERMR_MEM32; - else - xfermode = XFERMR_XEN | XFERMR_IO32; - - if (sc->sc_suspendio > 0) - xfermode |= XFERMR_FIFOEN; - } - -out: - sc->sc_xfermr = xfermode; - nsp_cr_write_1(sc->sc_iot, sc->sc_ioh, NSPR_XFERMR, sc->sc_xfermr); -} - -static void -nsp_pdma_end(struct nsp_softc *sc, struct targ_info *ti) -{ - struct scsi_low_softc *slp = &sc->sc_sclow; - struct slccb *cb = slp->sl_Qnexus; - u_int len = 0, cnt; - - sc->sc_dataout_timeout = 0; - slp->sl_flags &= ~HW_PDMASTART; - nsp_setup_fifo(sc, NSP_FIFO_OFF, SCSI_LOW_READ, 0); - if ((sc->sc_icr & SCIENR_FIFO) != 0) - { - sc->sc_icr &= ~SCIENR_FIFO; - nsp_cr_write_1(sc->sc_iot, sc->sc_ioh, NSPR_SCIENR, sc->sc_icr); - } - - if (cb == NULL) - { - slp->sl_error |= PDMAERR; - return; - } - - if (ti->ti_phase == PH_DATA) - { - cnt = nsp_fifo_count(sc); - if (slp->sl_scp.scp_direction == SCSI_LOW_WRITE) - { - len = sc->sc_cnt - cnt; - if (sc->sc_cnt >= cnt && - slp->sl_scp.scp_datalen + len <= - cb->ccb_scp.scp_datalen) - { - slp->sl_scp.scp_data -= len; - slp->sl_scp.scp_datalen += len; - } - else - { - slp->sl_error |= PDMAERR; - kprintf("%s len %x >= datalen %x\n", - slp->sl_xname, - len, slp->sl_scp.scp_datalen); - } - } - else if (slp->sl_scp.scp_direction == SCSI_LOW_READ) - { - if (sc->sc_cnt != cnt || - sc->sc_cnt > cb->ccb_scp.scp_datalen) - { - slp->sl_error |= PDMAERR; - kprintf("%s: data read count error %x != %x (%x)\n", - slp->sl_xname, sc->sc_cnt, cnt, - cb->ccb_scp.scp_datalen); - } - } - sc->sc_cnt = cnt; - scsi_low_data_finish(slp); - } - else - { - - kprintf("%s data phase miss\n", slp->sl_xname); - slp->sl_error |= PDMAERR; - } -} - -#define RFIFO_CRIT 64 -#define WFIFO_CRIT 32 - -static void -nsp_data_padding(struct nsp_softc *sc, int direction, u_int count) -{ - bus_space_tag_t bst = sc->sc_iot; - bus_space_handle_t bsh = sc->sc_ioh; - - if (count > NSP_MAX_DATA_SIZE) - count = NSP_MAX_DATA_SIZE; - - nsp_cr_write_1(bst, bsh, NSPR_XFERMR, XFERMR_XEN | XFERMR_IO8); - if (direction == SCSI_LOW_READ) - { - while (count -- > 0) - (void) bus_space_read_1(bst, bsh, nsp_fifodr); - } - else - { - while (count -- > 0) - (void) bus_space_write_1(bst, bsh, nsp_fifodr, 0); - } - nsp_cr_write_1(bst, bsh, NSPR_XFERMR, sc->sc_xfermr); -} - -static int -nsp_read_fifo(struct nsp_softc *sc, int suspendio) -{ - struct scsi_low_softc *slp = &sc->sc_sclow; - bus_space_tag_t bst = sc->sc_iot; - bus_space_handle_t bsh = sc->sc_ioh; - u_int res; - - res = nsp_fifo_count(sc); - if (res == sc->sc_cnt) - return 0; - -#ifdef NSP_DEBUG - if (res < sc->sc_cnt || res == (u_int) -1) - { - kprintf("%s: strange fifo ack count 0x%x < 0x%x\n", - slp->sl_xname, res, sc->sc_cnt); - return 0; - } -#endif /* NSP_DEBUG */ - - res = res - sc->sc_cnt; - if (res > slp->sl_scp.scp_datalen) - { - if ((slp->sl_error & PDMAERR) == 0) - { - kprintf("%s: data overrun 0x%x > 0x%x\n", - slp->sl_xname, res, slp->sl_scp.scp_datalen); - } - - slp->sl_error |= PDMAERR; - slp->sl_scp.scp_datalen = 0; - - if ((slp->sl_flags & HW_READ_PADDING) == 0) - { - kprintf("%s: read padding required\n", slp->sl_xname); - return 0; - } - - nsp_data_padding(sc, SCSI_LOW_READ, res); - sc->sc_cnt += res; - return 1; /* padding start */ - } - - if (suspendio > 0 && slp->sl_scp.scp_datalen >= suspendio) - res = suspendio; - - if ((sc->sc_xfermr & (XFERMR_MEM32 | XFERMR_MEM8)) != 0) - { - if ((sc->sc_xfermr & XFERMR_MEM32) != 0) - { - res &= ~3; - bus_space_read_region_4(sc->sc_memt, sc->sc_memh, 0, - (u_int32_t *) slp->sl_scp.scp_data, res >> 2); - } - else - { - bus_space_read_region_1(sc->sc_memt, sc->sc_memh, 0, - (u_int8_t *) slp->sl_scp.scp_data, res); - } - } - else - { - if ((sc->sc_xfermr & XFERMR_IO32) != 0) - { - res &= ~3; - bus_space_read_multi_4(bst, bsh, nsp_fifodr, - (u_int32_t *) slp->sl_scp.scp_data, res >> 2); - } - else - { - bus_space_read_multi_1(bst, bsh, nsp_fifodr, - (u_int8_t *) slp->sl_scp.scp_data, res); - } - } - - if (nsp_cr_read_1(bst, bsh, NSPR_PARITYR) & PARITYR_PE) - { - nsp_cr_write_1(bst, bsh, NSPR_PARITYR, - PARITYR_ENABLE | PARITYR_CLEAR); - scsi_low_assert_msg(slp, slp->sl_Tnexus, SCSI_LOW_MSG_ERROR, 1); - } - - slp->sl_scp.scp_data += res; - slp->sl_scp.scp_datalen -= res; - sc->sc_cnt += res; - return 0; -} - -static int -nsp_write_fifo(struct nsp_softc *sc, int suspendio) -{ - struct scsi_low_softc *slp = &sc->sc_sclow; - bus_space_tag_t bst = sc->sc_iot; - bus_space_handle_t bsh = sc->sc_ioh; - u_int res; - u_int8_t stat; - - if (suspendio > 0) - { -#ifdef NSP_DEBUG - if ((slp->sl_scp.scp_datalen % WFIFO_CRIT) != 0) - { - kprintf("%s: strange write length 0x%x\n", - slp->sl_xname, slp->sl_scp.scp_datalen); - } -#endif /* NSP_DEBUG */ - res = slp->sl_scp.scp_datalen % suspendio; - if (res == 0) - { - res = suspendio; - } - } - else - { - res = WFIFO_CRIT; - } - - if (res > slp->sl_scp.scp_datalen) - res = slp->sl_scp.scp_datalen; - - /* XXX: reconfirm! */ - stat = nsp_cr_read_1(bst, bsh, NSPR_SCBUSMON) & SCBUSMON_PHMASK; - if (stat != PHASE_DATAOUT) - return 0; - - if ((sc->sc_xfermr & (XFERMR_MEM32 | XFERMR_MEM8)) != 0) - { - if ((sc->sc_xfermr & XFERMR_MEM32) != 0) - { - bus_space_write_region_4(sc->sc_memt, sc->sc_memh, 0, - (u_int32_t *) slp->sl_scp.scp_data, res >> 2); - } - else - { - bus_space_write_region_1(sc->sc_memt, sc->sc_memh, 0, - (u_int8_t *) slp->sl_scp.scp_data, res); - } - } - else - { - if ((sc->sc_xfermr & XFERMR_IO32) != 0) - { - bus_space_write_multi_4(bst, bsh, nsp_fifodr, - (u_int32_t *) slp->sl_scp.scp_data, res >> 2); - } - else - { - bus_space_write_multi_1(bst, bsh, nsp_fifodr, - (u_int8_t *) slp->sl_scp.scp_data, res); - } - } - - slp->sl_scp.scp_datalen -= res; - slp->sl_scp.scp_data += res; - sc->sc_cnt += res; - return 0; -} - -static int -nsp_wait_interrupt(struct nsp_softc *sc) -{ - bus_space_tag_t bst = sc->sc_iot; - bus_space_handle_t bsh = sc->sc_ioh; - int tout; - u_int8_t isrc; - - for (tout = 0; tout < DEV_BSIZE / 10; tout ++) - { - isrc = bus_space_read_1(bst, bsh, nsp_irqsr); - if ((isrc & (IRQSR_SCSI | IRQSR_FIFO)) != 0) - { - if ((isrc & IRQSR_FIFO) != 0) - { - bus_space_write_1(bst, bsh, - nsp_irqcr, IRQCR_FIFOCL); - } - return 1; - } - SCSI_LOW_DELAY(1); - } - return 0; -} - -static void -nsp_pio_read(struct nsp_softc *sc, int suspendio) -{ - struct scsi_low_softc *slp = &sc->sc_sclow; - bus_space_tag_t bst = sc->sc_iot; - bus_space_handle_t bsh = sc->sc_ioh; - int tout, padding, datalen; - u_int8_t stat, fstat; - - padding = 0; - tout = sc->sc_tmaxcnt; - slp->sl_flags |= HW_PDMASTART; - datalen = slp->sl_scp.scp_datalen; - -ReadLoop: - while (1) - { - stat = nsp_cr_read_1(bst, bsh, NSPR_SCBUSMON); - if (stat == (u_int8_t) -1) - return; - - /* out of data phase */ - if ((stat & SCBUSMON_PHMASK) != PHASE_DATAIN) - { - nsp_read_fifo(sc, 0); - return; - } - - /* data phase */ - fstat = bus_space_read_1(bst, bsh, nsp_fifosr); - if ((fstat & FIFOSR_FULLEMP) != 0) - { - if ((sc->sc_icr & SCIENR_FIFO) != 0) - { - bus_space_write_1(bst, bsh, nsp_irqcr, - IRQCR_FIFOCL); - } - - if (suspendio > 0) - { - padding |= nsp_read_fifo(sc, suspendio); - } - else - { - padding |= nsp_read_fifo(sc, 0); - } - - if ((sc->sc_icr & SCIENR_FIFO) != 0) - break; - } - else - { - if (padding == 0 && slp->sl_scp.scp_datalen <= 0) - return; - - if ((sc->sc_icr & SCIENR_FIFO) != 0) - break; - - SCSI_LOW_DELAY(1); - } - - if ((-- tout) <= 0) - { - kprintf("%s: nsp_pio_read: timeout\n", slp->sl_xname); - return; - } - } - - - if (slp->sl_scp.scp_datalen > 0 && - slp->sl_scp.scp_datalen > datalen - nsp_read_interrupt_bytes) - { - if (nsp_wait_interrupt(sc) != 0) - goto ReadLoop; - } -} - -static void -nsp_pio_write(struct nsp_softc *sc, int suspendio) -{ - struct scsi_low_softc *slp = &sc->sc_sclow; - bus_space_tag_t bst = sc->sc_iot; - bus_space_handle_t bsh = sc->sc_ioh; - u_int rcount, acount; - int tout, datalen; - u_int8_t stat, fstat; - - tout = sc->sc_tmaxcnt; - slp->sl_flags |= HW_PDMASTART; - datalen = slp->sl_scp.scp_datalen; - -WriteLoop: - while (1) - { - stat = nsp_cr_read_1(bst, bsh, NSPR_SCBUSMON) & SCBUSMON_PHMASK; - if (stat != PHASE_DATAOUT) - return; - - if (slp->sl_scp.scp_datalen <= 0) - { - if (sc->sc_dataout_timeout == 0) - sc->sc_dataout_timeout = SCSI_LOW_TIMEOUT_HZ; - return; - } - - fstat = bus_space_read_1(bst, bsh, nsp_fifosr); - if ((fstat & FIFOSR_FULLEMP) != 0) - { - if ((sc->sc_icr & SCIENR_FIFO) != 0) - { - bus_space_write_1(bst, bsh, nsp_irqcr, - IRQCR_FIFOCL); - } - - if (suspendio > 0) - { - /* XXX:IMPORTANT: - * To avoid timeout of pcmcia bus - * (not scsi bus!), we should check - * the scsi device sends us request - * signals, which means the scsi device - * is ready to recieve data without - * heavy delays. - */ - if ((slp->sl_scp.scp_datalen % suspendio) == 0) - { - /* Step I: - * fill the nsp fifo, and waiting for - * the fifo empty. - */ - nsp_write_fifo(sc, 0); - } - else - { - /* Step II: - * check the request singals. - */ - acount = nsp_fifo_count(sc); - rcount = nsp_request_count(sc); - if (rcount <= acount) - { - nsp_write_fifo(sc, 0); -#ifdef NSP_STATICS - nsp_statics.device_busy ++; -#endif /* NSP_STATICS */ - } - else - { - nsp_write_fifo(sc, suspendio); -#ifdef NSP_STATICS - nsp_statics.device_data_write ++; -#endif /* NSP_STATICS */ - } - } - } - else - { - nsp_write_fifo(sc, 0); - } - - if ((sc->sc_icr & SCIENR_FIFO) != 0) - break; - } - else - { - if ((sc->sc_icr & SCIENR_FIFO) != 0) - break; - - SCSI_LOW_DELAY(1); - } - - if ((-- tout) <= 0) - { - kprintf("%s: nsp_pio_write: timeout\n", slp->sl_xname); - return; - } - } - - if (slp->sl_scp.scp_datalen > 0 && - slp->sl_scp.scp_datalen > datalen - nsp_write_interrupt_bytes) - { - if (nsp_wait_interrupt(sc) != 0) - goto WriteLoop; - } -} - -static int -nsp_negate_signal(struct nsp_softc *sc, u_int8_t mask, u_char *s) -{ - struct scsi_low_softc *slp = &sc->sc_sclow; - bus_space_tag_t bst = sc->sc_iot; - bus_space_handle_t bsh = sc->sc_ioh; - int wc; - u_int8_t regv; - - for (wc = 0; wc < NSP_DELAY_MAX / NSP_DELAY_INTERVAL; wc ++) - { - regv = nsp_cr_read_1(bst, bsh, NSPR_SCBUSMON); - if (regv == (u_int8_t) -1) - return -1; - if ((regv & mask) == 0) - return 1; - SCSI_LOW_DELAY(NSP_DELAY_INTERVAL); - } - - kprintf("%s: %s nsp_negate_signal timeout\n", slp->sl_xname, s); - return -1; -} - -static int -nsp_xfer(struct nsp_softc *sc, u_int8_t *buf, int len, int phase, - int clear_atn) -{ - bus_space_tag_t bst = sc->sc_iot; - bus_space_handle_t bsh = sc->sc_ioh; - int ptr, rv; - - for (ptr = 0; len > 0; len --, ptr ++) - { - rv = nsp_expect_signal(sc, phase, SCBUSMON_REQ); - if (rv <= 0) - goto out; - - if (len == 1 && clear_atn != 0) - { - nsp_cr_write_1(bst, bsh, NSPR_SCBUSCR, - SCBUSCR_ADIR | SCBUSCR_ACKEN); - SCSI_LOW_DEASSERT_ATN(&sc->sc_sclow); - } - - if (phase & SCBUSMON_IO) - { - buf[ptr] = nsp_cr_read_1(bst, bsh, NSPR_DATAACK); - } - else - { - nsp_cr_write_1(bst, bsh, NSPR_DATAACK, buf[ptr]); - } - nsp_negate_signal(sc, SCBUSMON_ACK, "xfer"); - } - -out: - return len; -} - -/************************************************************** - * disconnect & reselect (HW low) - **************************************************************/ -static int -nsp_reselected(struct nsp_softc *sc) -{ - struct scsi_low_softc *slp = &sc->sc_sclow; - bus_space_tag_t bst = sc->sc_iot; - bus_space_handle_t bsh = sc->sc_ioh; - struct targ_info *ti; - u_int sid; - u_int8_t cr; - - sid = (u_int) nsp_cr_read_1(bst, bsh, NSPR_RESELR); - sid &= ~sc->sc_idbit; - sid = ffs(sid) - 1; - if ((ti = scsi_low_reselected(slp, sid)) == NULL) - return EJUSTRETURN; - - nsp_negate_signal(sc, SCBUSMON_SEL, "reselect"); - - cr = nsp_cr_read_1(bst, bsh, NSPR_SCBUSCR); - cr &= ~(SCBUSCR_BSY | SCBUSCR_ATN); - nsp_cr_write_1(bst, bsh, NSPR_SCBUSCR, cr); - cr |= SCBUSCR_ADIR | SCBUSCR_ACKEN; - nsp_cr_write_1(bst, bsh, NSPR_SCBUSCR, cr); - -#ifdef NSP_STATICS - nsp_statics.reselect ++; -#endif /* NSP_STATCIS */ - return EJUSTRETURN; -} - -static int -nsp_disconnected(struct nsp_softc *sc, struct targ_info *ti) -{ - struct scsi_low_softc *slp = &sc->sc_sclow; - bus_space_tag_t bst = sc->sc_iot; - bus_space_handle_t bsh = sc->sc_ioh; - - nsp_cr_write_1(bst, bsh, NSPR_PTCLRR, PTCLRR_PT | PTCLRR_ACK | - PTCLRR_REQ | PTCLRR_HOST); - if ((sc->sc_icr & SCIENR_FIFO) != 0) - { - sc->sc_icr &= ~SCIENR_FIFO; - nsp_cr_write_1(bst, bsh, NSPR_SCIENR, sc->sc_icr); - } - sc->sc_cnt = 0; - sc->sc_dataout_timeout = 0; -#ifdef NSP_STATICS - nsp_statics.disconnect ++; -#endif /* NSP_STATICS */ - scsi_low_disconnected(slp, ti); - return 1; -} - -/************************************************************** - * SEQUENCER - **************************************************************/ -static void nsp_error (struct nsp_softc *, u_char *, u_int8_t, u_int8_t, u_int8_t); - -static void -nsp_error(struct nsp_softc *sc, u_char *s, u_int8_t isrc, u_int8_t ph, - u_int8_t irqphs) -{ - struct scsi_low_softc *slp = &sc->sc_sclow; - - kprintf("%s: %s\n", slp->sl_xname, s); - kprintf("%s: isrc 0x%x scmon 0x%x irqphs 0x%x\n", - slp->sl_xname, (u_int) isrc, (u_int) ph, (u_int) irqphs); -} - -static int -nsp_target_nexus_establish(struct nsp_softc *sc) -{ - struct scsi_low_softc *slp = &sc->sc_sclow; - bus_space_tag_t bst = sc->sc_iot; - bus_space_handle_t bsh = sc->sc_ioh; - struct targ_info *ti = slp->sl_Tnexus; - struct nsp_targ_info *nti = (void *) ti; - - /* setup synch transfer registers */ - nsp_cr_write_1(bst, bsh, NSPR_SYNCR, nti->nti_reg_syncr); - nsp_cr_write_1(bst, bsh, NSPR_ACKWIDTH, nti->nti_reg_ackwidth); - - /* setup pdma fifo (minimum) */ - nsp_setup_fifo(sc, NSP_FIFO_ON, SCSI_LOW_READ, 0); - return 0; -} - -static int -nsp_lun_nexus_establish(struct nsp_softc *sc) -{ - - return 0; -} - -static int -nsp_ccb_nexus_establish(struct nsp_softc *sc) -{ - struct scsi_low_softc *slp = &sc->sc_sclow; - struct slccb *cb = slp->sl_Qnexus; - - sc->sc_tmaxcnt = cb->ccb_tcmax * 1000 * 1000; - - /* setup pdma fifo */ - nsp_setup_fifo(sc, NSP_FIFO_ON, - slp->sl_scp.scp_direction, slp->sl_scp.scp_datalen); - - if (slp->sl_scp.scp_direction == SCSI_LOW_READ) - { - if (sc->sc_suspendio > 0 && - (nsp_io_control & NSP_READ_FIFO_INTERRUPTS) != 0) - { - sc->sc_icr |= SCIENR_FIFO; - nsp_cr_write_1(sc->sc_iot, sc->sc_ioh, - NSPR_SCIENR, sc->sc_icr); - } - } - else - { - if (sc->sc_suspendio > 0 && - (nsp_io_control & NSP_WRITE_FIFO_INTERRUPTS) != 0) - { - sc->sc_icr |= SCIENR_FIFO; - nsp_cr_write_1(sc->sc_iot, sc->sc_ioh, - NSPR_SCIENR, sc->sc_icr); - } - } - return 0; -} - -static int -nsp_phase_match(struct nsp_softc *sc, u_int8_t phase, u_int8_t stat) -{ - struct scsi_low_softc *slp = &sc->sc_sclow; - - if ((stat & SCBUSMON_PHMASK) != phase) - { - kprintf("%s: phase mismatch 0x%x != 0x%x\n", - slp->sl_xname, (u_int) phase, (u_int) stat); - return EINVAL; - } - - if ((stat & SCBUSMON_REQ) == 0) - return EINVAL; - - return 0; -} - -int -nspintr(void *arg) -{ - struct nsp_softc *sc = arg; - struct scsi_low_softc *slp = &sc->sc_sclow; - bus_space_tag_t bst = sc->sc_iot; - bus_space_handle_t bsh = sc->sc_ioh; - struct targ_info *ti; - struct buf *bp; - u_int derror, flags; - int len, rv; - u_int8_t isrc, ph, irqphs, cr, regv; - - /******************************************* - * interrupt check - *******************************************/ - if (slp->sl_flags & HW_INACTIVE) - return 0; - - bus_space_write_1(bst, bsh, nsp_irqcr, IRQCR_IRQDIS); - isrc = bus_space_read_1(bst, bsh, nsp_irqsr); - if (isrc == (u_int8_t) -1 || (isrc & IRQSR_MASK) == 0) - { - bus_space_write_1(bst, bsh, nsp_irqcr, 0); - return 0; - } - - /* XXX: IMPORTANT - * Do not read an irqphs register if no scsi phase interrupt. - * Unless, you should lose a scsi phase interrupt. - */ - ph = nsp_cr_read_1(bst, bsh, NSPR_SCBUSMON); - if ((isrc & IRQSR_SCSI) != 0) - { - irqphs = nsp_cr_read_1(bst, bsh, NSPR_IRQPHS); - } - else - irqphs = 0; - - /* - * timer interrupt handler (scsi vs timer interrupts) - */ - if (sc->sc_timer != 0) - { - nsp_cr_write_1(bst, bsh, NSPR_TIMERCNT, 0); - nsp_cr_write_1(bst, bsh, NSPR_TIMERCNT, 0); - sc->sc_timer = 0; - } - - /* check a timer interrupt */ - regv = 0; - if ((isrc & IRQSR_TIMER) != 0) - { - if ((isrc & IRQSR_MASK) == IRQSR_TIMER && sc->sc_seltout == 0) - { - bus_space_write_1(bst, bsh, nsp_irqcr, IRQCR_TIMERCL); - return 1; - } - regv |= IRQCR_TIMERCL; - } - - /* check a fifo interrupt */ - if ((isrc & IRQSR_FIFO) != 0) - { - regv |= IRQCR_FIFOCL; - } - - /* OK. enable all interrupts */ - bus_space_write_1(bst, bsh, nsp_irqcr, regv); - - /******************************************* - * debug section - *******************************************/ -#ifdef NSP_DEBUG - if (nsp_debug) - { - nsp_error(sc, "current status", isrc, ph, irqphs); - scsi_low_print(slp, NULL); -#ifdef DDB - if (nsp_debug > 1) - SCSI_LOW_DEBUGGER("nsp"); -#endif /* DDB */ - } -#endif /* NSP_DEBUG */ - - /******************************************* - * Parse hardware SCSI irq reasons register - *******************************************/ - if ((isrc & IRQSR_SCSI) != 0) - { - if ((irqphs & IRQPHS_RST) != 0) - { - scsi_low_restart(slp, SCSI_LOW_RESTART_SOFT, - "bus reset (power off?)"); - return 1; - } - - if ((irqphs & IRQPHS_RSEL) != 0) - { - bus_space_write_1(bst, bsh, nsp_irqcr, IRQCR_RESCL); - if (nsp_reselected(sc) == EJUSTRETURN) - return 1; - } - - if ((irqphs & (IRQPHS_PCHG | IRQPHS_LBF)) == 0) - return 1; - } - - /******************************************* - * nexus check - *******************************************/ - if ((ti = slp->sl_Tnexus) == NULL) - { - /* unknown scsi phase changes */ - nsp_error(sc, "unknown scsi phase changes", isrc, ph, irqphs); - return 0; - } - - /******************************************* - * aribitration & selection - *******************************************/ - switch (ti->ti_phase) - { - case PH_SELSTART: - if ((ph & SCBUSMON_BSY) == 0) - { - if (sc->sc_seltout >= NSP_SELTIMEOUT) - { - sc->sc_seltout = 0; - nsp_cr_write_1(bst, bsh, NSPR_SCBUSCR, 0); - return nsp_disconnected(sc, ti); - } - sc->sc_seltout ++; - nsp_start_timer(sc, NSP_TIMER_1MS); - return 1; - } - - SCSI_LOW_SETUP_PHASE(ti, PH_SELECTED); - nsphw_selection_done_and_expect_msgout(sc); - return 1; - - case PH_SELECTED: - if ((isrc & IRQSR_SCSI) == 0) - return 1; - - nsp_target_nexus_establish(sc); - break; - - case PH_RESEL: - if ((isrc & IRQSR_SCSI) == 0) - return 1; - - nsp_target_nexus_establish(sc); - if ((ph & SCBUSMON_PHMASK) != PHASE_MSGIN) - { - kprintf("%s: unexpected phase after reselect\n", - slp->sl_xname); - slp->sl_error |= FATALIO; - scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 1); - return 1; - } - break; - - case PH_DATA: - if ((isrc & IRQSR_SCSI) != 0) - break; - if ((isrc & IRQSR_FIFO) != 0) - { - if (NSP_IS_PHASE_DATA(ph) == 0) - return 1; - irqphs = (ph & IRQPHS_PHMASK); - break; - } - return 1; - - default: - if ((isrc & IRQSR_SCSI) == 0) - return 1; - break; - } - - /******************************************* - * data phase control - *******************************************/ - if (slp->sl_flags & HW_PDMASTART) - { - if ((isrc & IRQSR_SCSI) != 0 && - NSP_IS_IRQPHS_DATA(irqphs) == 0) - { - if (slp->sl_scp.scp_direction == SCSI_LOW_READ) - nsp_pio_read(sc, 0); - nsp_pdma_end(sc, ti); - } - } - - /******************************************* - * scsi seq - *******************************************/ - if (slp->sl_msgphase != 0 && (irqphs & IRQPHS_LBF) != 0) - return nsp_disconnected(sc, ti); - - /* check unexpected bus free state */ - if (ph == 0) - { - nsp_error(sc, "unexpected bus free", isrc, ph, irqphs); - return nsp_disconnected(sc, ti); - } - - /* check normal scsi phase */ - switch (irqphs & IRQPHS_PHMASK) - { - case IRQPHS_CMD: - if (nsp_phase_match(sc, PHASE_CMD, ph) != 0) - return 1; - - SCSI_LOW_SETUP_PHASE(ti, PH_CMD); - if (scsi_low_cmd(slp, ti) != 0) - { - scsi_low_attention(slp); - } - - nsp_cr_write_1(bst, bsh, NSPR_CMDCR, CMDCR_PTCLR); - for (len = 0; len < slp->sl_scp.scp_cmdlen; len ++) - nsp_cr_write_1(bst, bsh, NSPR_CMDDR, - slp->sl_scp.scp_cmd[len]); - - nsp_cr_write_1(bst, bsh, NSPR_CMDCR, CMDCR_PTCLR | CMDCR_EXEC); - break; - - case IRQPHS_DATAOUT: - SCSI_LOW_SETUP_PHASE(ti, PH_DATA); - if (scsi_low_data(slp, ti, &bp, SCSI_LOW_WRITE) != 0) - { - scsi_low_attention(slp); - } - - nsp_pio_write(sc, sc->sc_suspendio); - break; - - case IRQPHS_DATAIN: - SCSI_LOW_SETUP_PHASE(ti, PH_DATA); - if (scsi_low_data(slp, ti, &bp, SCSI_LOW_READ) != 0) - { - scsi_low_attention(slp); - } - - nsp_pio_read(sc, sc->sc_suspendio); - break; - - case IRQPHS_STATUS: - if (nsp_phase_match(sc, PHASE_STATUS, ph) != 0) - return 1; - - SCSI_LOW_SETUP_PHASE(ti, PH_STAT); - regv = nsp_cr_read_1(bst, bsh, NSPR_DATA); - if (nsp_cr_read_1(bst, bsh, NSPR_PARITYR) & PARITYR_PE) - { - nsp_cr_write_1(bst, bsh, NSPR_PARITYR, - PARITYR_ENABLE | PARITYR_CLEAR); - derror = SCSI_LOW_DATA_PE; - } - else - derror = 0; - - /* assert ACK */ - cr = SCBUSCR_ACK | nsp_cr_read_1(bst, bsh, NSPR_SCBUSCR); - nsp_cr_write_1(bst, bsh, NSPR_SCBUSCR, cr); - - if (scsi_low_statusin(slp, ti, derror | regv) != 0) - { - scsi_low_attention(slp); - } - - /* check REQ nagated */ - nsp_negate_signal(sc, SCBUSMON_REQ, "statin"); - - /* deassert ACK */ - cr = nsp_cr_read_1(bst, bsh, NSPR_SCBUSCR) & (~SCBUSCR_ACK); - nsp_cr_write_1(bst, bsh, NSPR_SCBUSCR, cr); - break; - - case IRQPHS_MSGOUT: - if (nsp_phase_match(sc, PHASE_MSGOUT, ph) != 0) - return 1; - -#ifdef NSP_MSGOUT_SERIALIZE - /* - * XXX: NSP QUIRK - * NSP invoke interrupts only in the case of scsi phase changes, - * therefore we should poll the scsi phase here to catch - * the next "msg out" if exists (no scsi phase changes). - */ - rv = len = 16; - do { - SCSI_LOW_SETUP_PHASE(ti, PH_MSGOUT); - flags = (ti->ti_ophase != ti->ti_phase) ? - SCSI_LOW_MSGOUT_INIT : 0; - len = scsi_low_msgout(slp, ti, flags); - - if (len > 1 && slp->sl_atten == 0) - { - scsi_low_attention(slp); - } - - if (nsp_xfer(sc, ti->ti_msgoutstr, len, PHASE_MSGOUT, - slp->sl_clear_atten) != 0) - { - slp->sl_error |= FATALIO; - nsp_error(sc, "MSGOUT: xfer short", - isrc, ph, irqphs); - } - - /* catch a next signal */ - rv = nsp_expect_signal(sc, PHASE_MSGOUT, SCBUSMON_REQ); - } - while (rv > 0 && len -- > 0); - -#else /* !NSP_MSGOUT_SERIALIZE */ - SCSI_LOW_SETUP_PHASE(ti, PH_MSGOUT); - flags = SCSI_LOW_MSGOUT_UNIFY; - if (ti->ti_ophase != ti->ti_phase) - flags |= SCSI_LOW_MSGOUT_INIT; - len = scsi_low_msgout(slp, ti, flags); - - if (len > 1 && slp->sl_atten == 0) - { - scsi_low_attention(slp); - } - - if (nsp_xfer(sc, ti->ti_msgoutstr, len, PHASE_MSGOUT, - slp->sl_clear_atten) != 0) - { - nsp_error(sc, "MSGOUT: xfer short", isrc, ph, irqphs); - } - -#endif /* !NSP_MSGOUT_SERIALIZE */ - break; - - case IRQPHS_MSGIN: - if (nsp_phase_match(sc, PHASE_MSGIN, ph) != 0) - return 1; - - /* - * XXX: NSP QUIRK - * NSP invoke interrupts only in the case of scsi phase changes, - * therefore we should poll the scsi phase here to catch - * the next "msg in" if exists (no scsi phase changes). - */ - rv = len = 16; - do { - SCSI_LOW_SETUP_PHASE(ti, PH_MSGIN); - - /* read a data */ - regv = nsp_cr_read_1(bst, bsh, NSPR_DATA); - if (nsp_cr_read_1(bst, bsh, NSPR_PARITYR) & PARITYR_PE) - { - nsp_cr_write_1(bst, bsh, - NSPR_PARITYR, - PARITYR_ENABLE | PARITYR_CLEAR); - derror = SCSI_LOW_DATA_PE; - } - else - { - derror = 0; - } - - /* assert ack */ - cr = nsp_cr_read_1(bst, bsh, NSPR_SCBUSCR) | SCBUSCR_ACK; - nsp_cr_write_1(bst, bsh, NSPR_SCBUSCR, cr); - - if (scsi_low_msgin(slp, ti, regv | derror) == 0) - { - if (scsi_low_is_msgout_continue(ti, 0) != 0) - { - scsi_low_attention(slp); - } - } - - /* check REQ nagated */ - nsp_negate_signal(sc, SCBUSMON_REQ, "msgin"); - - /* deassert ack */ - cr = nsp_cr_read_1(bst, bsh, NSPR_SCBUSCR) & (~SCBUSCR_ACK); - nsp_cr_write_1(bst, bsh, NSPR_SCBUSCR, cr); - - /* catch a next signal */ - rv = nsp_expect_signal(sc, PHASE_MSGIN, SCBUSMON_REQ); - } - while (rv > 0 && len -- > 0); - break; - - default: - slp->sl_error |= FATALIO; - nsp_error(sc, "unknown scsi phase", isrc, ph, irqphs); - break; - } - - return 1; - -#if 0 -timerout: - nsp_start_timer(sc, NSP_TIMER_1MS); - return 0; -#endif -} - -static int -nsp_timeout(struct nsp_softc *sc) -{ - struct scsi_low_softc *slp = &sc->sc_sclow; - bus_space_tag_t iot = sc->sc_iot; - bus_space_handle_t ioh = sc->sc_ioh; - int tout; - u_int8_t ph, regv; - - if (slp->sl_Tnexus == NULL) - return 0; - - ph = nsp_cr_read_1(iot, ioh, NSPR_SCBUSMON); - switch (ph & SCBUSMON_PHMASK) - { - case PHASE_DATAOUT: - if (sc->sc_dataout_timeout == 0) - break; - - /* check a fifo empty */ - regv = bus_space_read_1(iot, ioh, nsp_fifosr); - if ((regv & FIFOSR_FULLEMP) == 0) - break; - bus_space_write_1(iot, ioh, nsp_irqcr, IRQCR_FIFOCL); - - /* check still requested */ - ph = nsp_cr_read_1(iot, ioh, NSPR_SCBUSMON); - if ((ph & SCBUSMON_REQ) == 0) - break; - /* check timeout */ - if ((-- sc->sc_dataout_timeout) > 0) - break; - - slp->sl_error |= PDMAERR; - if ((slp->sl_flags & HW_WRITE_PADDING) == 0) - { - kprintf("%s: write padding required\n", slp->sl_xname); - break; - } - - tout = NSP_DELAY_MAX; - while (tout -- > 0) - { - ph = nsp_cr_read_1(iot, ioh, NSPR_SCBUSMON); - if ((ph & SCBUSMON_PHMASK) != PHASE_DATAOUT) - break; - regv = bus_space_read_1(iot, ioh, nsp_fifosr); - if ((regv & FIFOSR_FULLEMP) == 0) - { - SCSI_LOW_DELAY(1); - continue; - } - - bus_space_write_1(iot, ioh, nsp_irqcr, IRQCR_FIFOCL); - nsp_data_padding(sc, SCSI_LOW_WRITE, 32); - } - ph = nsp_cr_read_1(iot, ioh, NSPR_SCBUSMON); - if ((ph & SCBUSMON_PHMASK) == PHASE_DATAOUT) - sc->sc_dataout_timeout = SCSI_LOW_TIMEOUT_HZ; - break; - - default: - break; - } - return 0; -} diff --git a/sys/dev/disk/nsp/nsp_pccard.c b/sys/dev/disk/nsp/nsp_pccard.c deleted file mode 100644 index e5783e7038..0000000000 --- a/sys/dev/disk/nsp/nsp_pccard.c +++ /dev/null @@ -1,338 +0,0 @@ -/* $FreeBSD: src/sys/dev/nsp/nsp_pccard.c,v 1.2.2.6 2001/12/17 13:30:19 non Exp $ */ -/* $NecBSD: nsp_pisa.c,v 1.4 1999/04/15 01:35:54 kmatsuda Exp $ */ -/* $NetBSD$ */ - -/* - * [Ported for FreeBSD] - * Copyright (c) 2000 - * Noriaki Mitsunaga, Mitsuru Iwasaki and Takanori Watanabe. - * All rights reserved. - * [NetBSD for NEC PC-98 series] - * Copyright (c) 1998 - * NetBSD/pc98 porting staff. All rights reserved. - * - * 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. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -#include - -#include -#include - -#include "pccarddevs.h" - -#include "nspreg.h" -#include "nspvar.h" - -#define NSP_HOSTID 7 - -#include -#include -#if !defined(__FreeBSD__) || __FreeBSD_version < 500014 -#include -#endif - -#define PIO_MODE 0x100 /* pd_flags */ - -static int nspprobe(DEVPORT_PDEVICE devi); -static int nspattach(DEVPORT_PDEVICE devi); - -static void nsp_card_unload (DEVPORT_PDEVICE); - -static const struct pccard_product nsp_products[] = { - PCMCIA_CARD(IODATA3, CBSC16, 0), - PCMCIA_CARD(PANASONIC, KME, 0), - PCMCIA_CARD(WORKBIT2, NINJA_SCSI3, 0), - PCMCIA_CARD(WORKBIT, ULTRA_NINJA_16, 0), - { NULL } -}; - -/* - * Additional code for FreeBSD new-bus PCCard frontend - */ - -static void -nsp_pccard_intr(void * arg) -{ - nspintr(arg); -} - -static void -nsp_release_resource(DEVPORT_PDEVICE dev) -{ - struct nsp_softc *sc = device_get_softc(dev); - - if (sc->nsp_intrhand) { - bus_teardown_intr(dev, sc->irq_res, sc->nsp_intrhand); - } - - if (sc->port_res) { - bus_release_resource(dev, SYS_RES_IOPORT, - sc->port_rid, sc->port_res); - } - - if (sc->irq_res) { - bus_release_resource(dev, SYS_RES_IRQ, - sc->irq_rid, sc->irq_res); - } - - if (sc->mem_res) { - bus_release_resource(dev, SYS_RES_MEMORY, - sc->mem_rid, sc->mem_res); - } -} - -static int -nsp_alloc_resource(DEVPORT_PDEVICE dev) -{ - struct nsp_softc *sc = device_get_softc(dev); - u_long ioaddr, iosize, maddr, msize; - int error; - - error = bus_get_resource(dev, SYS_RES_IOPORT, 0, &ioaddr, &iosize); - if (error || iosize < NSP_IOSIZE) - return(ENOMEM); - - sc->port_rid = 0; - sc->port_res = bus_alloc_resource(dev, SYS_RES_IOPORT, &sc->port_rid, - 0, ~0, NSP_IOSIZE, RF_ACTIVE); - if (sc->port_res == NULL) { - nsp_release_resource(dev); - return(ENOMEM); - } - - sc->irq_rid = 0; - sc->irq_res = bus_alloc_resource(dev, SYS_RES_IRQ, &sc->irq_rid, - 0, ~0, 1, RF_ACTIVE); - if (sc->irq_res == NULL) { - nsp_release_resource(dev); - return(ENOMEM); - } - - error = bus_get_resource(dev, SYS_RES_MEMORY, 0, &maddr, &msize); - if (error) { - return(0); /* XXX */ - } - - /* No need to allocate memory if not configured and it's in PIO mode */ - if (maddr == 0 || msize == 0) { - if ((DEVPORT_PDEVFLAGS(dev) & PIO_MODE) == 0) { - kprintf("Memory window was not configured. Configure or use in PIO mode."); - nsp_release_resource(dev); - return(ENOMEM); - } - /* no need to allocate memory if PIO mode */ - return(0); - } - - sc->mem_rid = 0; - sc->mem_res = bus_alloc_resource(dev, SYS_RES_MEMORY, &sc->mem_rid, - 0, ~0, 1, RF_ACTIVE); - if (sc->mem_res == NULL) { - nsp_release_resource(dev); - return(ENOMEM); - } - - return(0); -} - -static int nsp_pccard_match(device_t dev) -{ - const struct pccard_product *pp; - - if ((pp = pccard_product_lookup(dev, nsp_products, - sizeof(nsp_products[0]), NULL)) != NULL) { - device_set_desc(dev, pp->pp_name); - return (0); - } - return (ENXIO); -} - -static int -nsp_pccard_probe(DEVPORT_PDEVICE dev) -{ - struct nsp_softc *sc = device_get_softc(dev); - int error; - - bzero(sc, sizeof(struct nsp_softc)); - - error = nsp_alloc_resource(dev); - if (error) { - return(error); - } - - if (nspprobe(dev) == 0) { - nsp_release_resource(dev); - return(ENXIO); - } - - nsp_release_resource(dev); - - return(0); -} - -static int -nsp_pccard_attach(DEVPORT_PDEVICE dev) -{ - struct nsp_softc *sc = device_get_softc(dev); - int error; - - error = nsp_alloc_resource(dev); - if (error) { - return(error); - } - - error = bus_setup_intr(dev, sc->irq_res, 0, - nsp_pccard_intr, (void *)sc, - &sc->nsp_intrhand, NULL); - if (error) { - nsp_release_resource(dev); - return(error); - } - - if (nspattach(dev) == 0) { - nsp_release_resource(dev); - return(ENXIO); - } - - return(0); -} - -static void -nsp_pccard_detach(DEVPORT_PDEVICE dev) -{ - nsp_card_unload(dev); - nsp_release_resource(dev); -} - -static device_method_t nsp_pccard_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, pccard_compat_probe), - DEVMETHOD(device_attach, pccard_compat_attach), - DEVMETHOD(device_detach, nsp_pccard_detach), - - /* Card interface */ - DEVMETHOD(card_compat_match, nsp_pccard_match), - DEVMETHOD(card_compat_probe, nsp_pccard_probe), - DEVMETHOD(card_compat_attach, nsp_pccard_attach), - - DEVMETHOD_END -}; - -static driver_t nsp_pccard_driver = { - "nsp", - nsp_pccard_methods, - sizeof(struct nsp_softc), -}; - -static devclass_t nsp_devclass; - -MODULE_DEPEND(nsp, scsi_low, 1, 1, 1); -DRIVER_MODULE(nsp, pccard, nsp_pccard_driver, nsp_devclass, NULL, NULL); - -static void -nsp_card_unload(DEVPORT_PDEVICE devi) -{ - struct nsp_softc *sc = DEVPORT_PDEVGET_SOFTC(devi); - - kprintf("%s: unload\n",sc->sc_sclow.sl_xname); - crit_enter(); - scsi_low_deactivate((struct scsi_low_softc *)sc); - scsi_low_dettach(&sc->sc_sclow); - crit_exit(); -} - -static int -nspprobe(DEVPORT_PDEVICE devi) -{ - int rv; - struct nsp_softc *sc = device_get_softc(devi); - - rv = nspprobesubr(rman_get_bustag(sc->port_res), - rman_get_bushandle(sc->port_res), - DEVPORT_PDEVFLAGS(devi)); - - return rv; -} - -static int -nspattach(DEVPORT_PDEVICE devi) -{ - struct nsp_softc *sc; - struct scsi_low_softc *slp; - u_int32_t flags = DEVPORT_PDEVFLAGS(devi); - u_int iobase = DEVPORT_PDEVIOBASE(devi); - char dvname[16]; - - strcpy(dvname,"nsp"); - - if (iobase == 0) - { - kprintf("%s: no ioaddr is given\n", dvname); - return (0); - } - - sc = DEVPORT_PDEVALLOC_SOFTC(devi); - if (sc == NULL) { - return (0); - } - - slp = &sc->sc_sclow; - slp->sl_dev = devi; - sc->sc_iot = rman_get_bustag(sc->port_res); - sc->sc_ioh = rman_get_bushandle(sc->port_res); - - if((flags & PIO_MODE) == 0) { - sc->sc_memt = rman_get_bustag(sc->mem_res); - sc->sc_memh = rman_get_bushandle(sc->mem_res); - } else { - sc->sc_memh = 0; - } - /* slp->sl_irq = devi->pd_irq; */ - sc->sc_iclkdiv = CLKDIVR_20M; - sc->sc_clkdiv = CLKDIVR_40M; - - slp->sl_hostid = NSP_HOSTID; - slp->sl_cfgflags = flags; - - crit_enter(); - nspattachsubr(sc); - crit_exit(); - - return(NSP_IOSIZE); -} diff --git a/sys/dev/disk/nsp/nspreg.h b/sys/dev/disk/nsp/nspreg.h deleted file mode 100644 index af233702c4..0000000000 --- a/sys/dev/disk/nsp/nspreg.h +++ /dev/null @@ -1,222 +0,0 @@ -/* $FreeBSD: src/sys/dev/nsp/nspreg.h,v 1.1.2.2 2001/07/22 00:21:39 non Exp $ */ -/* $DragonFly: src/sys/dev/disk/nsp/nspreg.h,v 1.2 2003/06/17 04:28:28 dillon Exp $ */ -/* $NecBSD: nspreg.h,v 1.4.3 2001/06/29 06:27:53 honda Exp $ */ -/* $NetBSD$ */ - -/* - * [NetBSD for NEC PC-98 series] - * Copyright (c) 1998 - * NetBSD/pc98 porting staff. All rights reserved. - * - * 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. - */ - -#ifndef _NSPREG_H_ -#define _NSPREG_H_ - -/* base registers */ -#define nsp_irqcr 0 -#define IRQCR_RESCL 0x01 -#define IRQCR_PHCL 0x02 -#define IRQCR_TIMERCL 0x04 -#define IRQCR_FIFOCL 0x08 -#define IRQCR_SCSIIDIS 0x10 -#define IRQCR_EXTIDIS 0x20 -#define IRQCR_TIMERIDIS 0x40 -#define IRQCR_FIFOIDIS 0x80 -#define IRQCR_ALLMASK 0xff -#define IRQCR_IRQDIS 0xf0 - -#define nsp_irqsr 0 -#define IRQSR_SCSI 0x01 -#define IRQSR_EXT 0x02 -#define IRQSR_TIMER 0x04 -#define IRQSR_FIFO 0x08 -#define IRQSR_MASK 0x0f - -#define nsp_ifselr 1 -#define IFSELR_IFSEL 0x01 -#define IFSELR_REGSEL 0x04 - -#define nsp_fifosr 1 -#define FIFOSR_CHIPREVM 0x0f -#define FIFOSR_CHIPIDM 0x70 -#define FIFOSR_FULLEMP 0x80 - -#define nsp_idxr 2 -#define nsp_datar 3 -#define nsp_fifodr 4 - -/* indexed registers */ -#define NSPR_EXTBUSC 0x10 - -#define NSPR_CLKDIVR 0x11 -#define CLKDIVR_40M 0x02 -#define CLKDIVR_20M 0x01 - -#define NSPR_TERMPWRC 0x13 -#define TERMPWRC_POWON 0x01 - -#define NSPR_SCIENR 0x15 -#define SCIENR_SCCHG 0x01 -#define SCIENR_RESEL 0x10 -#define SCIENR_FIFO 0x20 -#define SCIENR_RST 0x40 - -#define NSPR_IRQPHS 0x16 -#define IRQPHS_LMSG 0x01 -#define IRQPHS_LIO 0x02 -#define IRQPHS_LCD 0x04 -#define IRQPHS_LBF 0x08 -#define IRQPHS_PCHG 0x10 -#define IRQPHS_RSEL 0x20 -#define IRQPHS_FIFO 0x40 -#define IRQPHS_RST 0x80 -#define IRQPHS_PHMASK (IRQPHS_LCD | IRQPHS_LMSG | IRQPHS_LIO) - -#define NSPR_TIMERCNT 0x17 - -#define NSPR_SCBUSCR 0x18 -#define SCBUSCR_SEL 0x01 -#define SCBUSCR_RST 0x02 -#define SCBUSCR_DOUT 0x04 -#define SCBUSCR_ATN 0x08 -#define SCBUSCR_ACK 0x10 -#define SCBUSCR_BSY 0x20 -#define SCBUSCR_ADIR 0x40 -#define SCBUSCR_ACKEN 0x80 - -#define NSPR_SCBUSMON 0x19 -#define SCBUSMON_MSG 0x01 -#define SCBUSMON_IO 0x02 -#define SCBUSMON_CD 0x04 -#define SCBUSMON_BSY 0x08 -#define SCBUSMON_ACK 0x10 -#define SCBUSMON_REQ 0x20 -#define SCBUSMON_SEL 0x40 -#define SCBUSMON_ATN 0x80 - -#define NSPR_SETARBIT 0x1A - -#define NSPR_ARBITS 0x1A -#define ARBITS_EXEC 0x01 -#define ARBITS_CLR 0x02 -#define ARBITS_WIN 0x02 -#define ARBITS_FAIL 0x04 -#define ARBITS_RESEL 0x08 - -#define NSPR_PARITYR 0x1B /* (W/R) */ -#define PARITYR_ENABLE 0x01 -#define PARITYR_CLEAR 0x02 -#define PARITYR_PE 0x02 - -#define NSPR_CMDCR 0x1C /* (W) */ -#define CMDCR_PTCLR 0x01 -#define CMDCR_EXEC 0x02 - -#define NSPR_RESELR 0x1C /* (R) */ -#define NSPR_CMDDR 0x1D /* (W/R) */ - -#define NSPR_PTCLRR 0x1E /* (W) */ -#define PTCLRR_PT 0x01 -#define PTCLRR_ACK 0x02 -#define PTCLRR_REQ 0x04 -#define PTCLRR_HOST 0x08 -#define PTCLRR_RSS 0x30 -#define PTCLRR_RSS_ACK 0x00 -#define PTCLRR_RSS_REQ 0x10 -#define PTCLRR_RSS_HOST 0x20 - -#define NSPR_XFERCR 0x1E /* (R) */ - -#define NSPR_XFERMR 0x20 -#define XFERMR_MEM8 0x01 -#define XFERMR_MEM32 0x02 -#define XFERMR_ADR24 0x04 -#define XFERMR_ADR32 0x08 -#define XFERMR_IO8 0x10 -#define XFERMR_IO32 0x20 -#define XFERMR_XEN 0x40 -#define XFERMR_FIFOEN 0x80 - -#define NSPR_SYNCR 0x21 -#define SYNCR_OFFM 0x0f -#define SYNCR_PERM 0xf0 -#define SYNCR_PERS 4 - -#define NSPR_DATA 0x22 -#define NSPR_DATAACK 0x23 -#define NSPR_OCR 0x26 -#define OCR_ROMEN 0x01 -#define OCR_TERMPWROUT 0x02 -#define OCR_TERMPWRS 0x04 - -#define NSPR_ACKWIDTH 0x27 - -/* SCBUSMON phase defs */ -#define SCBUSMON_FREE 0 -#define SCBUSMON_CMD \ - (SCBUSMON_BSY | SCBUSMON_CD | SCBUSMON_REQ) -#define SCBUSMON_MSGIN \ - (SCBUSMON_BSY | SCBUSMON_MSG | SCBUSMON_IO | SCBUSMON_CD | SCBUSMON_REQ) -#define SCBUSMON_MSGOUT \ - (SCBUSMON_BSY | SCBUSMON_MSG | SCBUSMON_CD | SCBUSMON_REQ) -#define SCBUSMON_DATAIN \ - (SCBUSMON_BSY | SCBUSMON_IO | SCBUSMON_REQ) -#define SCBUSMON_DATAOUT \ - (SCBUSMON_BSY | SCBUSMON_REQ) -#define SCBUSMON_STATUS \ - (SCBUSMON_BSY | SCBUSMON_IO | SCBUSMON_CD | SCBUSMON_REQ) -#define SCBUSMON_RESELECT \ - (SCBUSMON_SEL | SCBUSMON_IO) -#define SCBUSMON_PHMASK \ - (SCBUSMON_SEL | SCBUSMON_CD | SCBUSMON_MSG | SCBUSMON_IO) - -/* Data phase */ -#define NSP_IS_PHASE_DATA(ph) \ - ((((ph) & SCBUSMON_PHMASK) & ~SCBUSMON_IO) == 0) -#define NSP_IS_IRQPHS_DATA(ph) \ - ((((ph) & IRQPHS_PHMASK) & ~SCBUSMON_IO) == 0) - -/* SCSI phase */ -#define PHASE_CMD (SCBUSMON_CMD & SCBUSMON_PHMASK) -#define PHASE_DATAIN (SCBUSMON_DATAIN & SCBUSMON_PHMASK) -#define PHASE_DATAOUT (SCBUSMON_DATAOUT & SCBUSMON_PHMASK) -#define PHASE_STATUS (SCBUSMON_STATUS & SCBUSMON_PHMASK) -#define PHASE_MSGIN (SCBUSMON_MSGIN & SCBUSMON_PHMASK) -#define PHASE_MSGOUT (SCBUSMON_MSGOUT & SCBUSMON_PHMASK) -#define PHASE_SEL (SCBUSMON_SEL | SCBUSMON_IO) - -#define IRQPHS_CMD (IRQPHS_LCD) -#define IRQPHS_DATAIN (IRQPHS_LIO) -#define IRQPHS_DATAOUT (0) -#define IRQPHS_STATUS (IRQPHS_LCD | IRQPHS_LIO) -#define IRQPHS_MSGIN (IRQPHS_LCD | IRQPHS_LMSG | IRQPHS_LIO) -#define IRQPHS_MSGOUT (IRQPHS_LCD | IRQPHS_LMSG) - -/* Size */ -#define NSP_MEMSIZE NBPG -#define NSP_IOSIZE 16 -#define NSP_BUFFER_SIZE 512 -#endif /* !_NSPREG_H_ */ diff --git a/sys/dev/disk/nsp/nspvar.h b/sys/dev/disk/nsp/nspvar.h deleted file mode 100644 index 4ddb98b64f..0000000000 --- a/sys/dev/disk/nsp/nspvar.h +++ /dev/null @@ -1,111 +0,0 @@ -/* $FreeBSD: src/sys/dev/nsp/nspvar.h,v 1.1.2.4 2001/12/17 13:30:19 non Exp $ */ -/* $DragonFly: src/sys/dev/disk/nsp/nspvar.h,v 1.4 2004/02/12 00:00:16 dillon Exp $ */ -/* $NecBSD: nspvar.h,v 1.7.14.5 2001/06/29 06:27:54 honda Exp $ */ -/* $NetBSD$ */ - -/* - * [NetBSD for NEC PC-98 series] - * Copyright (c) 1998, 1999, 2000, 2001 - * NetBSD/pc98 porting staff. All rights reserved. - * - * Copyright (c) 1998, 1999, 2000, 2001 - * Naofumi HONDA. All rights reserved. - * - * 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. - */ - -#ifndef _NSPVAR_H_ -#define _NSPVAR_H_ - -/***************************************************************** - * Host adapter structure - *****************************************************************/ -struct nsp_softc { - struct scsi_low_softc sc_sclow; /* generic data */ - -#ifdef __NetBSD__ - bus_space_tag_t sc_iot; - bus_space_handle_t sc_ioh; - bus_space_tag_t sc_memt; - bus_space_handle_t sc_memh; - - void *sc_ih; -#endif /* __NetBSD__ */ - -#ifdef __DragonFly__ - bus_space_tag_t sc_iot; - bus_space_handle_t sc_ioh; - bus_space_tag_t sc_memt; - bus_space_handle_t sc_memh; - - int port_rid; - int irq_rid; - int mem_rid; - struct resource *port_res; - struct resource *irq_res; - struct resource *mem_res; - - void *nsp_intrhand; -#endif /* __DragonFly__ */ - - int sc_tmaxcnt; /* timeout count */ - int sc_seltout; /* selection timeout counter */ - int sc_timer; /* timer start */ - - int sc_suspendio; /* SMIT: data suspendio bytes */ - u_int8_t sc_xfermr; /* SMIT: fifo control reg */ - int sc_dataout_timeout; /* data out timeout counter */ - - u_int sc_idbit; /* host id bit pattern */ - u_int sc_cnt; /* fifo R/W count (host) */ - - u_int8_t sc_iclkdiv; /* scsi chip clock divisor */ - u_int8_t sc_clkdiv; /* asic chip clock divisor */ - u_int8_t sc_icr; /* interrupt control reg */ - - u_int8_t sc_busc; /* busc registers */ - u_int8_t sc_parr; /* parity control register */ -}; - -/***************************************************************** - * Lun information - *****************************************************************/ -struct nsp_targ_info { - struct targ_info nti_ti; /* generic lun info */ - - u_int8_t nti_reg_syncr; /* sync registers per devices */ - u_int8_t nti_reg_ackwidth; /* ackwidth per devices */ -}; - -/***************************************************************** - * Proto - *****************************************************************/ -int nspprobesubr (bus_space_tag_t, bus_space_handle_t, u_int); -void nspattachsubr (struct nsp_softc *); -int nspprint (void *, const char *); -int nspintr (void *); - -#define SOFT_INTR_REQUIRED(slp) - -#endif /* !_NSPVAR_H_ */ diff --git a/sys/dev/disk/stg/Makefile b/sys/dev/disk/stg/Makefile deleted file mode 100644 index c3f59a02d4..0000000000 --- a/sys/dev/disk/stg/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -# $FreeBSD: src/sys/modules/stg/Makefile,v 1.1.2.2 2002/01/02 07:59:12 non Exp $ - -KMOD= stg -SRCS= tmc18c30.c tmc18c30_pccard.c -SRCS+= device_if.h bus_if.h pci_if.h card_if.h pccarddevs.h -SRCS+= opt_cam.h opt_scsi.h opt_ddb.h - -.include diff --git a/sys/dev/disk/stg/tmc18c30.c b/sys/dev/disk/stg/tmc18c30.c deleted file mode 100644 index d3c49c5f40..0000000000 --- a/sys/dev/disk/stg/tmc18c30.c +++ /dev/null @@ -1,1340 +0,0 @@ -/* $FreeBSD: src/sys/dev/stg/tmc18c30.c,v 1.1.2.5 2001/12/17 13:30:19 non Exp $ */ -/* $NecBSD: tmc18c30.c,v 1.28.12.3 2001/06/19 04:35:48 honda Exp $ */ -/* $NetBSD$ */ - -#define STG_DEBUG -#define STG_STATICS -#define STG_IO_CONTROL_FLAGS (STG_FIFO_INTERRUPTS | STG_WAIT_FOR_SELECT) - -/* - * [NetBSD for NEC PC-98 series] - * Copyright (c) 1996, 1997, 1998, 1999, 2000, 2001 - * NetBSD/pc98 porting staff. All rights reserved. - * Copyright (c) 1996, 1997, 1998, 1999, 2000, 2001 - * Naofumi HONDA. All rights reserved. - * Copyright (c) 1996, 1997, 1998, 1999 - * Kouichi Matsuda. All rights reserved. - * - * 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. - */ -#include "opt_ddb.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include "tmc18c30reg.h" -#include "tmc18c30var.h" - -/*************************************************** - * USER SETTINGS - ***************************************************/ -/* DEVICE CONFIGURATION FLAGS (MINOR) - * - * 0x01 DISCONECT OFF - * 0x02 PARITY LINE OFF - * 0x04 IDENTIFY MSG OFF ( = single lun) - * 0x08 SYNC TRANSFER OFF - */ -/* #define STG_SYNC_SUPPORT */ /* NOT YET but easy */ - -/* For the 512 fifo type: change below */ -#define TMC18C30_FIFOSZ 0x800 -#define TMC18C30_FCBSZ 0x200 -#define TMC18C50_FIFOSZ 0x2000 -#define TMC18C50_FCBSZ 0x400 - -#define STG_MAX_DATA_SIZE (64 * 1024) -#define STG_DELAY_MAX (2 * 1000 * 1000) -#define STG_DELAY_INTERVAL (1) -#define STG_DELAY_SELECT_POLLING_MAX (5 * 1000 * 1000) - -/*************************************************** - * PARAMS - ***************************************************/ -#define STG_NTARGETS 8 -#define STG_NLUNS 8 - -/*************************************************** - * DEBUG - ***************************************************/ -#ifdef STG_DEBUG -int stg_debug; -#endif /* STG_DEBUG */ - -#ifdef STG_STATICS -struct stg_statics { - int arbit_fail_0; - int arbit_fail_1; - int disconnect; - int reselect; -} stg_statics; -#endif /* STG_STATICS */ - -/*************************************************** - * IO control flags - ***************************************************/ -#define STG_FIFO_INTERRUPTS 0x0001 -#define STG_WAIT_FOR_SELECT 0x0100 - -int stg_io_control = STG_IO_CONTROL_FLAGS; - -/************************************************************** - * DECLARE - **************************************************************/ -/* static */ -static void stg_pio_read (struct stg_softc *, struct targ_info *, u_int); -static void stg_pio_write (struct stg_softc *, struct targ_info *, u_int); -static int stg_xfer (struct stg_softc *, u_int8_t *, int, int, int); -static int stg_msg (struct stg_softc *, struct targ_info *, u_int); -static int stg_reselected (struct stg_softc *); -static int stg_disconnected (struct stg_softc *, struct targ_info *); -static __inline void stg_pdma_end (struct stg_softc *, struct targ_info *); -static int stghw_select_targ_wait (struct stg_softc *, int); -static int stghw_check (struct stg_softc *); -static void stghw_init (struct stg_softc *); -static int stg_negate_signal (struct stg_softc *, u_int8_t, u_char *); -static int stg_expect_signal (struct stg_softc *, u_int8_t, u_int8_t); -static int stg_world_start (struct stg_softc *, int); -static int stghw_start_selection (struct stg_softc *sc, struct slccb *); -static void stghw_bus_reset (struct stg_softc *); -static void stghw_attention (struct stg_softc *); -static int stg_target_nexus_establish (struct stg_softc *); -static int stg_lun_nexus_establish (struct stg_softc *); -static int stg_ccb_nexus_establish (struct stg_softc *); -static int stg_targ_init (struct stg_softc *, struct targ_info *, int); -static __inline void stghw_bcr_write_1 (struct stg_softc *, u_int8_t); -static int stg_timeout (struct stg_softc *); -static void stg_selection_done_and_expect_msgout (struct stg_softc *); - -struct scsi_low_funcs stgfuncs = { - SC_LOW_INIT_T stg_world_start, - SC_LOW_BUSRST_T stghw_bus_reset, - SC_LOW_TARG_INIT_T stg_targ_init, - SC_LOW_LUN_INIT_T NULL, - - SC_LOW_SELECT_T stghw_start_selection, - SC_LOW_NEXUS_T stg_lun_nexus_establish, - SC_LOW_NEXUS_T stg_ccb_nexus_establish, - - SC_LOW_ATTEN_T stghw_attention, - SC_LOW_MSG_T stg_msg, - - SC_LOW_TIMEOUT_T stg_timeout, - SC_LOW_POLL_T stgintr, - - NULL, -}; - -/**************************************************** - * hwfuncs - ****************************************************/ -static __inline void -stghw_bcr_write_1(struct stg_softc *sc, u_int8_t bcv) -{ - - bus_space_write_1(sc->sc_iot, sc->sc_ioh, tmc_bctl, bcv); - sc->sc_busimg = bcv; -} - -static int -stghw_check(struct stg_softc *sc) -{ - struct scsi_low_softc *slp = &sc->sc_sclow; - bus_space_tag_t iot = sc->sc_iot; - bus_space_handle_t ioh = sc->sc_ioh; - u_int fcbsize, fcb; - u_int16_t lsb, msb; - - lsb = bus_space_read_1(iot, ioh, tmc_idlsb); - msb = bus_space_read_1(iot, ioh, tmc_idmsb); - switch (msb << 8 | lsb) - { - case 0x6127: - /* TMCCHIP_1800 not supported. (it's my policy) */ - sc->sc_chip = TMCCHIP_1800; - return EINVAL; - - case 0x60e9: - if (bus_space_read_1(iot, ioh, tmc_cfg2) & 0x02) - { - sc->sc_chip = TMCCHIP_18C30; - sc->sc_fsz = TMC18C30_FIFOSZ; - fcbsize = TMC18C30_FCBSZ; - } - else - { - sc->sc_chip = TMCCHIP_18C50; - sc->sc_fsz = TMC18C50_FIFOSZ; - fcbsize = TMC18C50_FCBSZ; - } - break; - - default: - sc->sc_chip = TMCCHIP_UNK; - return ENODEV; - } - - sc->sc_fcRinit = FCTL_INTEN; - sc->sc_fcWinit = FCTL_PARENB | FCTL_INTEN; - - if (slp->sl_cfgflags & CFG_NOATTEN) - sc->sc_imsg = 0; - else - sc->sc_imsg = BCTL_ATN; - sc->sc_busc = BCTL_BUSEN; - - sc->sc_wthold = fcbsize + 256; - sc->sc_rthold = fcbsize - 256; - sc->sc_maxwsize = sc->sc_fsz; - - fcb = fcbsize / (sc->sc_fsz / 16); - sc->sc_icinit = ICTL_CD | ICTL_SEL | ICTL_ARBIT | fcb; - return 0; -} - -static void -stghw_init(struct stg_softc *sc) -{ - bus_space_tag_t iot = sc->sc_iot; - bus_space_handle_t ioh = sc->sc_ioh; - - bus_space_write_1(iot, ioh, tmc_ictl, 0); - stghw_bcr_write_1(sc, BCTL_BUSFREE); - bus_space_write_1(iot, ioh, tmc_fctl, - sc->sc_fcRinit | FCTL_CLRFIFO | FCTL_CLRINT); - bus_space_write_1(iot, ioh, tmc_fctl, sc->sc_fcRinit); - bus_space_write_1(iot, ioh, tmc_ictl, sc->sc_icinit); - - bus_space_write_1(iot, ioh, tmc_ssctl, 0); -} - -static int -stg_targ_init(struct stg_softc *sc, struct targ_info *ti, int action) -{ - struct stg_targ_info *sti = (void *) ti; - - if (action == SCSI_LOW_INFO_ALLOC || action == SCSI_LOW_INFO_REVOKE) - { - ti->ti_width = SCSI_LOW_BUS_WIDTH_8; - ti->ti_maxsynch.period = 0; - ti->ti_maxsynch.offset = 0; - sti->sti_reg_synch = 0; - } - return 0; -} - -/**************************************************** - * scsi low interface - ****************************************************/ -static void -stghw_attention(struct stg_softc *sc) -{ - - sc->sc_busc |= BCTL_ATN; - sc->sc_busimg |= BCTL_ATN; - bus_space_write_1(sc->sc_iot, sc->sc_ioh, tmc_bctl, sc->sc_busimg); - SCSI_LOW_DELAY(10); -} - -static void -stghw_bus_reset(struct stg_softc *sc) -{ - bus_space_tag_t iot = sc->sc_iot; - bus_space_handle_t ioh = sc->sc_ioh; - - bus_space_write_1(iot, ioh, tmc_ictl, 0); - bus_space_write_1(iot, ioh, tmc_fctl, 0); - stghw_bcr_write_1(sc, BCTL_RST); - SCSI_LOW_DELAY(100000); - stghw_bcr_write_1(sc, BCTL_BUSFREE); -} - -static int -stghw_start_selection(struct stg_softc *sc, struct slccb *cb) -{ - bus_space_tag_t iot = sc->sc_iot; - bus_space_handle_t ioh = sc->sc_ioh; - struct targ_info *ti = cb->ti; - u_int8_t stat; - - sc->sc_tmaxcnt = cb->ccb_tcmax * 1000 * 1000; - sc->sc_dataout_timeout = 0; - sc->sc_ubf_timeout = 0; - stghw_bcr_write_1(sc, BCTL_BUSFREE); - bus_space_write_1(iot, ioh, tmc_ictl, sc->sc_icinit); - - crit_enter(); - stat = bus_space_read_1(iot, ioh, tmc_astat); - if ((stat & ASTAT_INT) != 0) - { - crit_exit(); - return SCSI_LOW_START_FAIL; - } - - bus_space_write_1(iot, ioh, tmc_scsiid, sc->sc_idbit); - bus_space_write_1(iot, ioh, tmc_fctl, sc->sc_fcRinit | FCTL_ARBIT); - crit_exit(); - - SCSI_LOW_SETUP_PHASE(ti, PH_ARBSTART); - return SCSI_LOW_START_OK; -} - -static int -stg_world_start(struct stg_softc *sc, int fdone) -{ - struct scsi_low_softc *slp = &sc->sc_sclow; - int error; - - if ((slp->sl_cfgflags & CFG_NOPARITY) == 0) - sc->sc_fcRinit |= FCTL_PARENB; - else - sc->sc_fcRinit &= ~FCTL_PARENB; - - if ((error = stghw_check(sc)) != 0) - return error; - - stghw_init(sc); - scsi_low_bus_reset(slp); - stghw_init(sc); - - SOFT_INTR_REQUIRED(slp); - return 0; -} - -static int -stg_msg(struct stg_softc *sc, struct targ_info *ti, u_int msg) -{ - bus_space_tag_t iot = sc->sc_iot; - bus_space_handle_t ioh = sc->sc_ioh; - struct stg_targ_info *sti = (void *) ti; - u_int period; - - if ((msg & SCSI_LOW_MSG_WIDE) != 0) - { - if (ti->ti_width != SCSI_LOW_BUS_WIDTH_8) - { - ti->ti_width = SCSI_LOW_BUS_WIDTH_8; - return EINVAL; - } - return 0; - } - - if ((msg & SCSI_LOW_MSG_SYNCH) == 0) - return 0; - - period = ti->ti_maxsynch.period; - period = period << 2; - if (period >= 200) - { - sti->sti_reg_synch = (period - 200) / 50; - if (period % 50) - sti->sti_reg_synch ++; - sti->sti_reg_synch |= SSCTL_SYNCHEN; - } - else if (period >= 100) - { - sti->sti_reg_synch = (period - 100) / 50; - if (period % 50) - sti->sti_reg_synch ++; - sti->sti_reg_synch |= SSCTL_SYNCHEN | SSCTL_FSYNCHEN; - } - bus_space_write_1(iot, ioh, tmc_ssctl, sti->sti_reg_synch); - return 0; -} - -/************************************************************** - * General probe attach - **************************************************************/ -int -stgprobesubr(bus_space_tag_t iot, bus_space_handle_t ioh, u_int dvcfg) -{ - u_int16_t lsb, msb; - - lsb = bus_space_read_1(iot, ioh, tmc_idlsb); - msb = bus_space_read_1(iot, ioh, tmc_idmsb); - switch (msb << 8 | lsb) - { - default: - return 0; - case 0x6127: - /* not support! */ - return 0; - case 0x60e9: - return 1; - } - return 0; -} - -int -stgprint(void *aux, const char *name) -{ - - if (name != NULL) - kprintf("%s: scsibus ", name); - return UNCONF; -} - -void -stgattachsubr(struct stg_softc *sc) -{ - struct scsi_low_softc *slp = &sc->sc_sclow; - - kprintf("\n"); - - sc->sc_idbit = (1 << slp->sl_hostid); - slp->sl_funcs = &stgfuncs; - sc->sc_tmaxcnt = SCSI_LOW_MIN_TOUT * 1000 * 1000; /* default */ - - slp->sl_flags |= HW_READ_PADDING; - slp->sl_cfgflags |= CFG_ASYNC; /* XXX */ - - (void) scsi_low_attach(slp, 0, STG_NTARGETS, STG_NLUNS, - sizeof(struct stg_targ_info), 0); -} - -/************************************************************** - * PDMA functions - **************************************************************/ -static __inline void -stg_pdma_end(struct stg_softc *sc, struct targ_info *ti) -{ - struct scsi_low_softc *slp = &sc->sc_sclow; - bus_space_tag_t iot = sc->sc_iot; - bus_space_handle_t ioh = sc->sc_ioh; - struct slccb *cb = slp->sl_Qnexus; - u_int len, tres; - - slp->sl_flags &= ~HW_PDMASTART; - sc->sc_icinit &= ~ICTL_FIFO; - sc->sc_dataout_timeout = 0; - - if (cb == NULL) - { - slp->sl_error |= PDMAERR; - goto out; - } - - if (ti->ti_phase == PH_DATA) - { - len = bus_space_read_2(iot, ioh, tmc_fdcnt); - if (slp->sl_scp.scp_direction == SCSI_LOW_WRITE) - { - if (len != 0) - { - tres = len + slp->sl_scp.scp_datalen; - if (tres <= (u_int) cb->ccb_scp.scp_datalen) - { - slp->sl_scp.scp_data -= len; - slp->sl_scp.scp_datalen = tres; - } - else - { - slp->sl_error |= PDMAERR; - kprintf("%s len %x >= datalen %x\n", - slp->sl_xname, - len, slp->sl_scp.scp_datalen); - } - } - } - else if (slp->sl_scp.scp_direction == SCSI_LOW_READ) - { - if (len != 0) - { - slp->sl_error |= PDMAERR; - kprintf("%s: len %x left in fifo\n", - slp->sl_xname, len); - } - } - scsi_low_data_finish(slp); - } - else - { - - kprintf("%s data phase miss\n", slp->sl_xname); - slp->sl_error |= PDMAERR; - } - -out: - bus_space_write_1(iot, ioh, tmc_fctl, sc->sc_fcRinit); -} - -static void -stg_pio_read(struct stg_softc *sc, struct targ_info *ti, u_int thold) -{ - struct scsi_low_softc *slp = &sc->sc_sclow; - bus_space_tag_t iot = sc->sc_iot; - bus_space_handle_t ioh = sc->sc_ioh; - struct sc_p *sp = &slp->sl_scp; - int tout; - u_int res; - u_int8_t stat; - - if ((slp->sl_flags & HW_PDMASTART) == 0) - { - bus_space_write_1(iot, ioh, tmc_fctl, - sc->sc_fcRinit | FCTL_FIFOEN); - slp->sl_flags |= HW_PDMASTART; - } - - tout = sc->sc_tmaxcnt; - while (tout -- > 0) - { - if (thold > 0) - { - crit_enter(); - res = bus_space_read_2(iot, ioh, tmc_fdcnt); - if (res < thold) - { - bus_space_write_1(iot, ioh, tmc_ictl, - sc->sc_icinit); - crit_exit(); - break; - } - crit_exit(); - } - else - { - stat = bus_space_read_1(iot, ioh, tmc_bstat); - res = bus_space_read_2(iot, ioh, tmc_fdcnt); - if (res == 0) - { - if ((stat & PHASE_MASK) != DATA_IN_PHASE) - break; - if (sp->scp_datalen <= 0) - break; - SCSI_LOW_DELAY(1); - continue; - } - } - - /* The assumtion res != 0 is valid here */ - if (res > sp->scp_datalen) - { - if (res == (u_int) -1) - break; - - slp->sl_error |= PDMAERR; - if ((slp->sl_flags & HW_READ_PADDING) == 0) - { - kprintf("%s: read padding required\n", - slp->sl_xname); - break; - } - - sp->scp_datalen = 0; - if (res > STG_MAX_DATA_SIZE) - res = STG_MAX_DATA_SIZE; - while (res -- > 0) - { - (void) bus_space_read_1(iot, ioh, tmc_rfifo); - } - continue; - } - - sp->scp_datalen -= res; - if (res & 1) - { - *sp->scp_data = bus_space_read_1(iot, ioh, tmc_rfifo); - sp->scp_data ++; - res --; - } - - bus_space_read_multi_2(iot, ioh, tmc_rfifo, - (u_int16_t *) sp->scp_data, res >> 1); - sp->scp_data += res; - } - - if (tout <= 0) - kprintf("%s: pio read timeout\n", slp->sl_xname); -} - -static void -stg_pio_write(struct stg_softc *sc, struct targ_info *ti, u_int thold) -{ - struct scsi_low_softc *slp = &sc->sc_sclow; - bus_space_tag_t iot = sc->sc_iot; - bus_space_handle_t ioh = sc->sc_ioh; - struct sc_p *sp = &slp->sl_scp; - u_int res; - int tout; - u_int8_t stat; - - if ((slp->sl_flags & HW_PDMASTART) == 0) - { - stat = sc->sc_fcWinit | FCTL_FIFOEN | FCTL_FIFOW; - bus_space_write_1(iot, ioh, tmc_fctl, stat | FCTL_CLRFIFO); - bus_space_write_1(iot, ioh, tmc_fctl, stat); - slp->sl_flags |= HW_PDMASTART; - } - - tout = sc->sc_tmaxcnt; - while (tout -- > 0) - { - stat = bus_space_read_1(iot, ioh, tmc_bstat); - if ((stat & PHASE_MASK) != DATA_OUT_PHASE) - break; - - if (sp->scp_datalen <= 0) - { - if (sc->sc_dataout_timeout == 0) - sc->sc_dataout_timeout = SCSI_LOW_TIMEOUT_HZ; - break; - } - - if (thold > 0) - { - crit_enter(); - res = bus_space_read_2(iot, ioh, tmc_fdcnt); - if (res > thold) - { - bus_space_write_1(iot, ioh, tmc_ictl, - sc->sc_icinit); - crit_exit(); - break; - } - crit_exit(); - } - else - { - res = bus_space_read_2(iot, ioh, tmc_fdcnt); - if (res > sc->sc_maxwsize / 2) - { - SCSI_LOW_DELAY(1); - continue; - } - } - - if (res == (u_int) -1) - break; - res = sc->sc_maxwsize - res; - if (res > sp->scp_datalen) - res = sp->scp_datalen; - - sp->scp_datalen -= res; - if ((res & 0x1) != 0) - { - bus_space_write_1(iot, ioh, tmc_wfifo, *sp->scp_data); - sp->scp_data ++; - res --; - } - - bus_space_write_multi_2(iot, ioh, tmc_wfifo, - (u_int16_t *) sp->scp_data, res >> 1); - sp->scp_data += res; - } - - if (tout <= 0) - kprintf("%s: pio write timeout\n", slp->sl_xname); -} - -static int -stg_negate_signal(struct stg_softc *sc, u_int8_t mask, u_char *s) -{ - struct scsi_low_softc *slp = &sc->sc_sclow; - bus_space_tag_t bst = sc->sc_iot; - bus_space_handle_t bsh = sc->sc_ioh; - int wc; - u_int8_t regv; - - for (wc = 0; wc < STG_DELAY_MAX / STG_DELAY_INTERVAL; wc ++) - { - regv = bus_space_read_1(bst, bsh, tmc_bstat); - if (regv == (u_int8_t) -1) - return -1; - if ((regv & mask) == 0) - return 1; - - SCSI_LOW_DELAY(STG_DELAY_INTERVAL); - } - - kprintf("%s: %s stg_negate_signal timeout\n", slp->sl_xname, s); - return -1; -} - -static int -stg_expect_signal(struct stg_softc *sc, u_int8_t phase, u_int8_t mask) -{ - struct scsi_low_softc *slp = &sc->sc_sclow; - bus_space_tag_t bst = sc->sc_iot; - bus_space_handle_t bsh = sc->sc_ioh; - int wc; - u_int8_t ph; - - phase &= PHASE_MASK; - for (wc = 0; wc < STG_DELAY_MAX / STG_DELAY_INTERVAL; wc ++) - { - ph = bus_space_read_1(bst, bsh, tmc_bstat); - if (ph == (u_int8_t) -1) - return -1; - if ((ph & PHASE_MASK) != phase) - return 0; - if ((ph & mask) != 0) - return 1; - - SCSI_LOW_DELAY(STG_DELAY_INTERVAL); - } - - kprintf("%s: stg_expect_signal timeout\n", slp->sl_xname); - return -1; -} - -static int -stg_xfer(struct stg_softc *sc, u_int8_t *buf, int len, int phase, - int clear_atn) -{ - bus_space_tag_t iot = sc->sc_iot; - bus_space_handle_t ioh = sc->sc_ioh; - int rv, ptr; - - if (phase & BSTAT_IO) - bus_space_write_1(iot, ioh, tmc_fctl, sc->sc_fcRinit); - else - bus_space_write_1(iot, ioh, tmc_fctl, sc->sc_fcWinit); - - for (ptr = 0; len > 0; len --) - { - rv = stg_expect_signal(sc, phase, BSTAT_REQ); - if (rv <= 0) - goto bad; - - if (len == 1 && clear_atn != 0) - { - sc->sc_busc &= ~BCTL_ATN; - stghw_bcr_write_1(sc, sc->sc_busc); - SCSI_LOW_DEASSERT_ATN(&sc->sc_sclow); - } - - if (phase & BSTAT_IO) - { - buf[ptr ++] = bus_space_read_1(iot, ioh, tmc_rdata); - } - else - { - bus_space_write_1(iot, ioh, tmc_wdata, buf[ptr ++]); - } - - stg_negate_signal(sc, BSTAT_ACK, "xfer"); - } - -bad: - bus_space_write_1(iot, ioh, tmc_fctl, sc->sc_fcRinit); - return len; -} - -/************************************************************** - * disconnect & reselect (HW low) - **************************************************************/ -static int -stg_reselected(struct stg_softc *sc) -{ - struct scsi_low_softc *slp = &sc->sc_sclow; - bus_space_tag_t iot = sc->sc_iot; - bus_space_handle_t ioh = sc->sc_ioh; - int tout; - u_int sid; - u_int8_t regv; - - if (slp->sl_selid != NULL) - { - /* XXX: - * Selection vs Reselection conflicts. - */ - bus_space_write_1(iot, ioh, tmc_fctl, sc->sc_fcRinit); - stghw_bcr_write_1(sc, BCTL_BUSFREE); - } - else if (slp->sl_Tnexus != NULL) - { - kprintf("%s: unexpected termination\n", slp->sl_xname); - stg_disconnected(sc, slp->sl_Tnexus); - } - - /* XXX: - * We should ack the reselection as soon as possible, - * because the target would abort the current reselection seq - * due to reselection timeout. - */ - tout = STG_DELAY_SELECT_POLLING_MAX; - while (tout -- > 0) - { - regv = bus_space_read_1(iot, ioh, tmc_bstat); - if ((regv & (BSTAT_IO | BSTAT_SEL | BSTAT_BSY)) == - (BSTAT_IO | BSTAT_SEL)) - { - SCSI_LOW_DELAY(1); - regv = bus_space_read_1(iot, ioh, tmc_bstat); - if ((regv & (BSTAT_IO | BSTAT_SEL | BSTAT_BSY)) == - (BSTAT_IO | BSTAT_SEL)) - goto reselect_start; - } - SCSI_LOW_DELAY(1); - } - kprintf("%s: reselction timeout I\n", slp->sl_xname); - return EJUSTRETURN; - -reselect_start: - sid = (u_int) bus_space_read_1(iot, ioh, tmc_scsiid); - if ((sid & sc->sc_idbit) == 0) - { - /* not us */ - return EJUSTRETURN; - } - - bus_space_write_1(iot, ioh, tmc_fctl, - sc->sc_fcRinit | FCTL_CLRFIFO | FCTL_CLRINT); - bus_space_write_1(iot, ioh, tmc_fctl, sc->sc_fcRinit); - stghw_bcr_write_1(sc, sc->sc_busc | BCTL_BSY); - - while (tout -- > 0) - { - regv = bus_space_read_1(iot, ioh, tmc_bstat); - if ((regv & (BSTAT_SEL | BSTAT_BSY)) == BSTAT_BSY) - goto reselected; - SCSI_LOW_DELAY(1); - } - kprintf("%s: reselction timeout II\n", slp->sl_xname); - return EJUSTRETURN; - -reselected: - sid &= ~sc->sc_idbit; - sid = ffs(sid) - 1; - if (scsi_low_reselected(slp, sid) == NULL) - return EJUSTRETURN; - -#ifdef STG_STATICS - stg_statics.reselect ++; -#endif /* STG_STATICS */ - return EJUSTRETURN; -} - -static int -stg_disconnected(struct stg_softc *sc, struct targ_info *ti) -{ - struct scsi_low_softc *slp = &sc->sc_sclow; - bus_space_tag_t iot = sc->sc_iot; - bus_space_handle_t ioh = sc->sc_ioh; - - /* clear bus status & fifo */ - bus_space_write_1(iot, ioh, tmc_fctl, sc->sc_fcRinit | FCTL_CLRFIFO); - bus_space_write_1(iot, ioh, tmc_fctl, sc->sc_fcRinit); - stghw_bcr_write_1(sc, BCTL_BUSFREE); - sc->sc_icinit &= ~ICTL_FIFO; - sc->sc_busc &= ~BCTL_ATN; - sc->sc_dataout_timeout = 0; - sc->sc_ubf_timeout = 0; - -#ifdef STG_STATICS - stg_statics.disconnect ++; -#endif /* STG_STATICS */ - scsi_low_disconnected(slp, ti); - return 1; -} - -/************************************************************** - * SEQUENCER - **************************************************************/ -static int -stg_target_nexus_establish(struct stg_softc *sc) -{ - struct scsi_low_softc *slp = &sc->sc_sclow; - bus_space_tag_t iot = sc->sc_iot; - bus_space_handle_t ioh = sc->sc_ioh; - struct targ_info *ti = slp->sl_Tnexus; - struct stg_targ_info *sti = (void *) ti; - - bus_space_write_1(iot, ioh, tmc_ssctl, sti->sti_reg_synch); - if ((stg_io_control & STG_FIFO_INTERRUPTS) != 0) - { - sc->sc_icinit |= ICTL_FIFO; - } - return 0; -} - -static int -stg_lun_nexus_establish(struct stg_softc *sc) -{ - - return 0; -} - -static int -stg_ccb_nexus_establish(struct stg_softc *sc) -{ - struct scsi_low_softc *slp = &sc->sc_sclow; - struct slccb *cb = slp->sl_Qnexus; - - sc->sc_tmaxcnt = cb->ccb_tcmax * 1000 * 1000; - return 0; -} - -#define STGHW_SELECT_INTERVAL 10 - -static int -stghw_select_targ_wait(struct stg_softc *sc, int mu) -{ - bus_space_tag_t iot = sc->sc_iot; - bus_space_handle_t ioh = sc->sc_ioh; - - mu = mu / STGHW_SELECT_INTERVAL; - while (mu -- > 0) - { - if ((bus_space_read_1(iot, ioh, tmc_bstat) & BSTAT_BSY) == 0) - { - SCSI_LOW_DELAY(STGHW_SELECT_INTERVAL); - continue; - } - SCSI_LOW_DELAY(1); - if ((bus_space_read_1(iot, ioh, tmc_bstat) & BSTAT_BSY) != 0) - { - return 0; - } - } - return ENXIO; -} - -static void -stg_selection_done_and_expect_msgout(struct stg_softc *sc) -{ - struct scsi_low_softc *slp = &sc->sc_sclow; - bus_space_tag_t iot = sc->sc_iot; - bus_space_handle_t ioh = sc->sc_ioh; - - bus_space_write_1(iot, ioh, tmc_fctl, sc->sc_fcRinit | FCTL_CLRFIFO); - bus_space_write_1(iot, ioh, tmc_fctl, sc->sc_fcRinit); - stghw_bcr_write_1(sc, sc->sc_imsg | sc->sc_busc); - SCSI_LOW_ASSERT_ATN(slp); -} - -int -stgintr(void *arg) -{ - struct stg_softc *sc = arg; - struct scsi_low_softc *slp = &sc->sc_sclow; - bus_space_tag_t iot = sc->sc_iot; - bus_space_handle_t ioh = sc->sc_ioh; - struct targ_info *ti; - struct buf *bp; - u_int derror, flags; - int len; - u_int8_t status, astatus, regv; - - /******************************************* - * interrupt check - *******************************************/ - if (slp->sl_flags & HW_INACTIVE) - return 0; - - astatus = bus_space_read_1(iot, ioh, tmc_astat); - status = bus_space_read_1(iot, ioh, tmc_bstat); - - if ((astatus & ASTAT_STATMASK) == 0 || astatus == (u_int8_t) -1) - return 0; - - bus_space_write_1(iot, ioh, tmc_ictl, 0); - if (astatus & ASTAT_SCSIRST) - { - bus_space_write_1(iot, ioh, tmc_fctl, - sc->sc_fcRinit | FCTL_CLRFIFO); - bus_space_write_1(iot, ioh, tmc_fctl, sc->sc_fcRinit); - bus_space_write_1(iot, ioh, tmc_ictl, 0); - - scsi_low_restart(slp, SCSI_LOW_RESTART_SOFT, - "bus reset (power off?)"); - return 1; - } - - /******************************************* - * debug section - *******************************************/ -#ifdef STG_DEBUG - if (stg_debug) - { - scsi_low_print(slp, NULL); - kprintf("%s: st %x ist %x\n\n", slp->sl_xname, - status, astatus); -#ifdef DDB - if (stg_debug > 1) - SCSI_LOW_DEBUGGER("stg"); -#endif /* DDB */ - } -#endif /* STG_DEBUG */ - - /******************************************* - * reselection & nexus - *******************************************/ - if ((status & RESEL_PHASE_MASK)== PHASE_RESELECTED) - { - if (stg_reselected(sc) == EJUSTRETURN) - goto out; - } - - if ((ti = slp->sl_Tnexus) == NULL) - return 0; - - derror = 0; - if ((astatus & ASTAT_PARERR) != 0 && ti->ti_phase != PH_ARBSTART && - (sc->sc_fcRinit & FCTL_PARENB) != 0) - { - slp->sl_error |= PARITYERR; - derror = SCSI_LOW_DATA_PE; - if ((status & PHASE_MASK) == MESSAGE_IN_PHASE) - scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_PARITY, 0); - else - scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ERROR, 1); - } - - /******************************************* - * aribitration & selection - *******************************************/ - switch (ti->ti_phase) - { - case PH_ARBSTART: - if ((astatus & ASTAT_ARBIT) == 0) - { -#ifdef STG_STATICS - stg_statics.arbit_fail_0 ++; -#endif /* STG_STATICS */ - goto arb_fail; - } - - status = bus_space_read_1(iot, ioh, tmc_bstat); - if ((status & BSTAT_IO) != 0) - { - /* XXX: - * Selection vs Reselection conflicts. - */ -#ifdef STG_STATICS - stg_statics.arbit_fail_1 ++; -#endif /* STG_STATICS */ -arb_fail: - bus_space_write_1(iot, ioh, tmc_fctl, sc->sc_fcRinit); - stghw_bcr_write_1(sc, BCTL_BUSFREE); - scsi_low_arbit_fail(slp, slp->sl_Qnexus); - goto out; - } - - /* - * selection assert start. - */ - SCSI_LOW_SETUP_PHASE(ti, PH_SELSTART); - scsi_low_arbit_win(slp); - - crit_enter(); - bus_space_write_1(iot, ioh, tmc_scsiid, - sc->sc_idbit | (1 << ti->ti_id)); - stghw_bcr_write_1(sc, sc->sc_imsg | sc->sc_busc | BCTL_SEL); - bus_space_write_1(iot, ioh, tmc_fctl, sc->sc_fcWinit); - if ((stg_io_control & STG_WAIT_FOR_SELECT) != 0) - { - /* selection abort delay 200 + 100 micro sec */ - if (stghw_select_targ_wait(sc, 300) == 0) - { - SCSI_LOW_SETUP_PHASE(ti, PH_SELECTED); - stg_selection_done_and_expect_msgout(sc); - } - } - crit_exit(); - goto out; - - case PH_SELSTART: - if ((status & BSTAT_BSY) == 0) - { - /* selection timeout delay 250 ms */ - if (stghw_select_targ_wait(sc, 250 * 1000) != 0) - { - stg_disconnected(sc, ti); - goto out; - } - } - - SCSI_LOW_SETUP_PHASE(ti, PH_SELECTED); - stg_selection_done_and_expect_msgout(sc); - goto out; - - case PH_SELECTED: - if ((status & BSTAT_REQ) == 0) - goto out; - stg_target_nexus_establish(sc); - break; - - case PH_RESEL: - if ((status & BSTAT_REQ) == 0) - goto out; - - /* clear a busy line */ - bus_space_write_1(iot, ioh, tmc_fctl, sc->sc_fcRinit); - stghw_bcr_write_1(sc, sc->sc_busc); - stg_target_nexus_establish(sc); - if ((status & PHASE_MASK) != MESSAGE_IN_PHASE) - { - kprintf("%s: unexpected phase after reselect\n", - slp->sl_xname); - slp->sl_error |= FATALIO; - scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 1); - goto out; - } - break; - } - - /******************************************* - * data phase - *******************************************/ - if ((slp->sl_flags & HW_PDMASTART) && STG_IS_PHASE_DATA(status) == 0) - { - if (slp->sl_scp.scp_direction == SCSI_LOW_READ) - stg_pio_read(sc, ti, 0); - - stg_pdma_end(sc, ti); - } - - /******************************************* - * scsi seq - *******************************************/ - switch (status & PHASE_MASK) - { - case COMMAND_PHASE: - if (stg_expect_signal(sc, COMMAND_PHASE, BSTAT_REQ) <= 0) - break; - - SCSI_LOW_SETUP_PHASE(ti, PH_CMD); - if (scsi_low_cmd(slp, ti) != 0) - { - scsi_low_attention(slp); - } - - if (stg_xfer(sc, slp->sl_scp.scp_cmd, slp->sl_scp.scp_cmdlen, - COMMAND_PHASE, 0) != 0) - { - kprintf("%s: CMDOUT short\n", slp->sl_xname); - } - break; - - case DATA_OUT_PHASE: - SCSI_LOW_SETUP_PHASE(ti, PH_DATA); - if (scsi_low_data(slp, ti, &bp, SCSI_LOW_WRITE) != 0) - { - scsi_low_attention(slp); - } - - if ((sc->sc_icinit & ICTL_FIFO) != 0) - stg_pio_write(sc, ti, sc->sc_wthold); - else - stg_pio_write(sc, ti, 0); - break; - - case DATA_IN_PHASE: - SCSI_LOW_SETUP_PHASE(ti, PH_DATA); - if (scsi_low_data(slp, ti, &bp, SCSI_LOW_READ) != 0) - { - scsi_low_attention(slp); - } - - if ((sc->sc_icinit & ICTL_FIFO) != 0) - stg_pio_read(sc, ti, sc->sc_rthold); - else - stg_pio_read(sc, ti, 0); - break; - - case STATUS_PHASE: - regv = stg_expect_signal(sc, STATUS_PHASE, BSTAT_REQ); - if (regv <= 0) - break; - - SCSI_LOW_SETUP_PHASE(ti, PH_STAT); - regv = bus_space_read_1(iot, ioh, tmc_sdna); - if (scsi_low_statusin(slp, ti, regv | derror) != 0) - { - scsi_low_attention(slp); - } - if (regv != bus_space_read_1(iot, ioh, tmc_rdata)) - { - kprintf("%s: STATIN: data mismatch\n", slp->sl_xname); - } - stg_negate_signal(sc, BSTAT_ACK, "statin"); - break; - - case MESSAGE_OUT_PHASE: - if (stg_expect_signal(sc, MESSAGE_OUT_PHASE, BSTAT_REQ) <= 0) - break; - - SCSI_LOW_SETUP_PHASE(ti, PH_MSGOUT); - flags = (ti->ti_ophase != ti->ti_phase) ? - SCSI_LOW_MSGOUT_INIT : 0; - len = scsi_low_msgout(slp, ti, flags); - - if (len > 1 && slp->sl_atten == 0) - { - scsi_low_attention(slp); - } - - if (stg_xfer(sc, ti->ti_msgoutstr, len, MESSAGE_OUT_PHASE, - slp->sl_clear_atten) != 0) - { - kprintf("%s: MSGOUT short\n", slp->sl_xname); - } - else - { - if (slp->sl_msgphase >= MSGPH_ABORT) - { - stg_disconnected(sc, ti); - } - } - break; - - case MESSAGE_IN_PHASE: - /* confirm phase and req signal */ - if (stg_expect_signal(sc, MESSAGE_IN_PHASE, BSTAT_REQ) <= 0) - break; - - SCSI_LOW_SETUP_PHASE(ti, PH_MSGIN); - - /* read data with NOACK */ - regv = bus_space_read_1(iot, ioh, tmc_sdna); - - if (scsi_low_msgin(slp, ti, derror | regv) == 0) - { - if (scsi_low_is_msgout_continue(ti, 0) != 0) - { - scsi_low_attention(slp); - } - } - - /* read data with ACK */ - if (regv != bus_space_read_1(iot, ioh, tmc_rdata)) - { - kprintf("%s: MSGIN: data mismatch\n", slp->sl_xname); - } - - /* wait for the ack negated */ - stg_negate_signal(sc, BSTAT_ACK, "msgin"); - - if (slp->sl_msgphase != 0 && slp->sl_msgphase < MSGPH_ABORT) - { - stg_disconnected(sc, ti); - } - break; - - case BUSFREE_PHASE: - kprintf("%s: unexpected disconnect\n", slp->sl_xname); - stg_disconnected(sc, ti); - break; - - default: - slp->sl_error |= FATALIO; - kprintf("%s: unknown phase bus %x intr %x\n", - slp->sl_xname, status, astatus); - break; - } - -out: - bus_space_write_1(iot, ioh, tmc_ictl, sc->sc_icinit); - return 1; -} - -static int -stg_timeout(struct stg_softc *sc) -{ - struct scsi_low_softc *slp = &sc->sc_sclow; - bus_space_tag_t iot = sc->sc_iot; - bus_space_handle_t ioh = sc->sc_ioh; - int tout, count; - u_int8_t status; - - if (slp->sl_Tnexus == NULL) - return 0; - - status = bus_space_read_1(iot, ioh, tmc_bstat); - if ((status & PHASE_MASK) == 0) - { - if (sc->sc_ubf_timeout ++ == 0) - return 0; - - kprintf("%s: unexpected bus free detected\n", slp->sl_xname); - slp->sl_error |= FATALIO; - scsi_low_print(slp, slp->sl_Tnexus); - stg_disconnected(sc, slp->sl_Tnexus); - return 0; - } - - switch (status & PHASE_MASK) - { - case DATA_OUT_PHASE: - if (sc->sc_dataout_timeout == 0) - break; - if ((status & BSTAT_REQ) == 0) - break; - if (bus_space_read_2(iot, ioh, tmc_fdcnt) != 0) - break; - if ((-- sc->sc_dataout_timeout) > 0) - break; - - slp->sl_error |= PDMAERR; - if ((slp->sl_flags & HW_WRITE_PADDING) == 0) - { - kprintf("%s: write padding required\n", - slp->sl_xname); - break; - } - - bus_space_write_1(iot, ioh, tmc_ictl, 0); - - tout = STG_DELAY_MAX; - while (tout --) - { - status = bus_space_read_1(iot, ioh, tmc_bstat); - if ((status & PHASE_MASK) != DATA_OUT_PHASE) - break; - - if (bus_space_read_2(iot, ioh, tmc_fdcnt) != 0) - { - SCSI_LOW_DELAY(1); - continue; - } - - for (count = sc->sc_maxwsize; count > 0; count --) - bus_space_write_1(iot, ioh, tmc_wfifo, 0); - } - - status = bus_space_read_1(iot, ioh, tmc_bstat); - if ((status & PHASE_MASK) == DATA_OUT_PHASE) - sc->sc_dataout_timeout = SCSI_LOW_TIMEOUT_HZ; - - bus_space_write_1(iot, ioh, tmc_ictl, sc->sc_icinit); - break; - - default: - break; - } - return 0; -} diff --git a/sys/dev/disk/stg/tmc18c30_pccard.c b/sys/dev/disk/stg/tmc18c30_pccard.c deleted file mode 100644 index 83768751d4..0000000000 --- a/sys/dev/disk/stg/tmc18c30_pccard.c +++ /dev/null @@ -1,324 +0,0 @@ -/* $FreeBSD: src/sys/dev/stg/tmc18c30_pccard.c,v 1.2.2.6 2001/12/17 13:30:19 non Exp $ */ -/* $NecBSD: tmc18c30_pisa.c,v 1.22 1998/11/26 01:59:21 honda Exp $ */ -/* $NetBSD$ */ - -/* - * [Ported for FreeBSD] - * Copyright (c) 2000 - * Noriaki Mitsunaga, Mitsuru Iwasaki and Takanori Watanabe. - * All rights reserved. - * [NetBSD for NEC PC-98 series] - * Copyright (c) 1996, 1997, 1998 - * NetBSD/pc98 porting staff. All rights reserved. - * Copyright (c) 1996, 1997, 1998 - * Naofumi HONDA. All rights reserved. - * Copyright (c) 1996, 1997, 1998 - * Kouichi Matsuda. All rights reserved. - * - * 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. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -#include - -#include "pccarddevs.h" - -#include -#include - -#include "tmc18c30reg.h" -#include "tmc18c30var.h" - -#define STG_HOSTID 7 - -#include -#include - -static const struct pccard_product stg_products[] = { - PCMCIA_CARD(FUTUREDOMAIN, SCSI2GO, 0), - PCMCIA_CARD(IBM, SCSICARD, 0), - PCMCIA_CARD(RATOC, REX5536, 0), - PCMCIA_CARD(RATOC, REX5536AM, 0), - PCMCIA_CARD(RATOC, REX5536M, 0), - { NULL } -}; - -static int stgprobe(DEVPORT_PDEVICE devi); -static int stgattach(DEVPORT_PDEVICE devi); - -static void stg_card_unload (DEVPORT_PDEVICE); - -/* - * Additional code for FreeBSD new-bus PCCard frontend - */ - -static int stg_pccard_match(device_t dev) -{ - const struct pccard_product *pp; - - if ((pp = pccard_product_lookup(dev, stg_products, - sizeof(stg_products[0]), NULL)) != NULL) { - if (pp->pp_name != NULL) - device_set_desc(dev, pp->pp_name); - return(0); - } - return(EIO); -} - -static void -stg_pccard_intr(void * arg) -{ - stgintr(arg); -} - -static void -stg_release_resource(DEVPORT_PDEVICE dev) -{ - struct stg_softc *sc = device_get_softc(dev); - - if (sc->stg_intrhand) { - bus_teardown_intr(dev, sc->irq_res, sc->stg_intrhand); - } - - if (sc->port_res) { - bus_release_resource(dev, SYS_RES_IOPORT, - sc->port_rid, sc->port_res); - } - - if (sc->irq_res) { - bus_release_resource(dev, SYS_RES_IRQ, - sc->irq_rid, sc->irq_res); - } - - if (sc->mem_res) { - bus_release_resource(dev, SYS_RES_MEMORY, - sc->mem_rid, sc->mem_res); - } -} - -static int -stg_alloc_resource(DEVPORT_PDEVICE dev) -{ - struct stg_softc *sc = device_get_softc(dev); - u_long ioaddr, iosize, maddr, msize; - int error; - - error = bus_get_resource(dev, SYS_RES_IOPORT, 0, &ioaddr, &iosize); - if (error || iosize < STGIOSZ) { - return(ENOMEM); - } - - sc->port_rid = 0; - sc->port_res = bus_alloc_resource(dev, SYS_RES_IOPORT, &sc->port_rid, - 0, ~0, STGIOSZ, RF_ACTIVE); - if (sc->port_res == NULL) { - stg_release_resource(dev); - return(ENOMEM); - } - - sc->irq_rid = 0; - sc->irq_res = bus_alloc_resource(dev, SYS_RES_IRQ, &sc->irq_rid, - 0, ~0, 1, RF_ACTIVE); - if (sc->irq_res == NULL) { - stg_release_resource(dev); - return(ENOMEM); - } - - error = bus_get_resource(dev, SYS_RES_MEMORY, 0, &maddr, &msize); - if (error) { - return(0); /* XXX */ - } - - /* no need to allocate memory if not configured */ - if (maddr == 0 || msize == 0) { - return(0); - } - - sc->mem_rid = 0; - sc->mem_res = bus_alloc_resource(dev, SYS_RES_MEMORY, &sc->mem_rid, - 0, ~0, 1, RF_ACTIVE); - if (sc->mem_res == NULL) { - stg_release_resource(dev); - return(ENOMEM); - } - - return(0); -} - -static int -stg_pccard_probe(DEVPORT_PDEVICE dev) -{ - struct stg_softc *sc = device_get_softc(dev); - int error; - - bzero(sc, sizeof(struct stg_softc)); - - error = stg_alloc_resource(dev); - if (error) { - return(error); - } - - if (stgprobe(dev) == 0) { - stg_release_resource(dev); - return(ENXIO); - } - - stg_release_resource(dev); - - return(0); -} - -static int -stg_pccard_attach(DEVPORT_PDEVICE dev) -{ - struct stg_softc *sc = device_get_softc(dev); - int error; - - error = stg_alloc_resource(dev); - if (error) { - return(error); - } - - error = bus_setup_intr(dev, sc->irq_res, 0, - stg_pccard_intr, (void *)sc, - &sc->stg_intrhand, NULL); - if (error) { - stg_release_resource(dev); - return(error); - } - - if (stgattach(dev) == 0) { - stg_release_resource(dev); - return(ENXIO); - } - - return(0); -} - -static void -stg_pccard_detach(DEVPORT_PDEVICE dev) -{ - stg_card_unload(dev); - stg_release_resource(dev); -} - -static device_method_t stg_pccard_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, pccard_compat_probe), - DEVMETHOD(device_attach, pccard_compat_attach), - DEVMETHOD(device_detach, stg_pccard_detach), - - /* Card interface */ - DEVMETHOD(card_compat_match, stg_pccard_match), - DEVMETHOD(card_compat_probe, stg_pccard_probe), - DEVMETHOD(card_compat_attach, stg_pccard_attach), - - DEVMETHOD_END -}; - -static driver_t stg_pccard_driver = { - "stg", - stg_pccard_methods, - sizeof(struct stg_softc), -}; - -static devclass_t stg_devclass; - -MODULE_DEPEND(stg, scsi_low, 1, 1, 1); -DRIVER_MODULE(stg, pccard, stg_pccard_driver, stg_devclass, NULL, NULL); - -static void -stg_card_unload(DEVPORT_PDEVICE devi) -{ - struct stg_softc *sc = DEVPORT_PDEVGET_SOFTC(devi); - - kprintf("%s: unload\n",sc->sc_sclow.sl_xname); - crit_enter(); - scsi_low_deactivate((struct scsi_low_softc *)sc); - scsi_low_dettach(&sc->sc_sclow); - crit_exit(); -} - -static int -stgprobe(DEVPORT_PDEVICE devi) -{ - int rv; - struct stg_softc *sc = device_get_softc(devi); - - rv = stgprobesubr(rman_get_bustag(sc->port_res), - rman_get_bushandle(sc->port_res), - DEVPORT_PDEVFLAGS(devi)); - - return rv; -} - -static int -stgattach(DEVPORT_PDEVICE devi) -{ - struct stg_softc *sc; - struct scsi_low_softc *slp; - u_int32_t flags = DEVPORT_PDEVFLAGS(devi); - u_int iobase = DEVPORT_PDEVIOBASE(devi); - char dvname[16]; - - strcpy(dvname,"stg"); - - if (iobase == 0) - { - kprintf("%s: no ioaddr is given\n", dvname); - return (0); - } - - sc = DEVPORT_PDEVALLOC_SOFTC(devi); - if (sc == NULL) { - return(0); - } - - slp = &sc->sc_sclow; - slp->sl_dev = devi; - sc->sc_iot = rman_get_bustag(sc->port_res); - sc->sc_ioh = rman_get_bushandle(sc->port_res); - - slp->sl_hostid = STG_HOSTID; - slp->sl_cfgflags = flags; - - crit_enter(); - stgattachsubr(sc); - crit_exit(); - - return(STGIOSZ); -} diff --git a/sys/dev/disk/stg/tmc18c30reg.h b/sys/dev/disk/stg/tmc18c30reg.h deleted file mode 100644 index bff77c2b67..0000000000 --- a/sys/dev/disk/stg/tmc18c30reg.h +++ /dev/null @@ -1,148 +0,0 @@ -/* $FreeBSD: src/sys/dev/stg/tmc18c30reg.h,v 1.1.2.2 2001/07/22 00:21:40 non Exp $ */ -/* $DragonFly: src/sys/dev/disk/stg/tmc18c30reg.h,v 1.2 2003/06/17 04:28:31 dillon Exp $ */ -/* $NecBSD: tmc18c30reg.h,v 1.4 1998/03/14 07:05:23 kmatsuda Exp $ */ -/* $NetBSD$ */ - -/* - * [NetBSD for NEC PC-98 series] - * Copyright (c) 1996, 1997, 1998 - * NetBSD/pc98 porting staff. All rights reserved. - * Copyright (c) 1996, 1997, 1998 - * Kouichi Matsuda. All rights reserved. - * - * 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. - */ - -#ifndef _TMC18C30REG_H_ -#define _TMC18C30REG_H_ - -#define tmc_wdata 0x00 -#define tmc_rdata 0x00 - -#define tmc_bctl 0x01 -#define BCTL_BUSFREE 0x00 -#define BCTL_RST 0x01 -#define BCTL_SEL 0x02 -#define BCTL_BSY 0x04 -#define BCTL_ATN 0x08 -#define BCTL_IO 0x10 -#define BCTL_CD 0x20 -#define BCTL_MSG 0x40 -#define BCTL_BUSEN 0x80 -#define tmc_bstat 0x01 -#define BSTAT_BSY 0x01 -#define BSTAT_MSG 0x02 -#define BSTAT_IO 0x04 -#define BSTAT_CMD 0x08 -#define BSTAT_REQ 0x10 -#define BSTAT_SEL 0x20 -#define BSTAT_ACK 0x40 - -#define tmc_ictl 0x02 -#define ICTL_FIFO 0x10 -#define ICTL_ARBIT 0x20 -#define ICTL_SEL 0x40 -#define ICTL_CD 0x80 -#define ICTL_ALLINT (ICTL_ARBIT | ICTL_CD | ICTL_SEL | ICTL_FIFO) -#define tmc_astat 0x02 -#define ASTAT_INT 0x01 -#define ASTAT_ARBIT 0x02 -#define ASTAT_PARERR 0x04 -#define ASTAT_SCSIRST 0x08 -#define ASTAT_STATMASK 0x0f -#define ASTAT_FIFODIR 0x10 -#define ASTAT_FIFOEN 0x20 -#define ASTAT_PARENB 0x40 -#define ASTAT_BUSEN 0x80 - -#define tmc_ssctl 0x03 -#define SSCTL_FSYNCHEN 0x40 -#define SSCTL_SYNCHEN 0x80 -#define tmc_fstat 0x03 - -#define tmc_fctl 0x04 -#define FCTL_CLRFIFO 0x01 -#define FCTL_ARBIT 0x04 -#define FCTL_PARENB 0x08 -#define FCTL_INTEN 0x10 -#define FCTL_CLRINT 0x20 -#define FCTL_FIFOW 0x40 -#define FCTL_FIFOEN 0x80 -#define tmc_icnd 0x04 - -#define tmc_mctl 0x05 -#define tmc_idlsb 0x05 - -#define tmc_idmsb 0x06 - -#define tmc_wlb 0x07 -#define tmc_rlb 0x07 - -#define tmc_scsiid 0x08 -#define tmc_sdna 0x08 - -#define tmc_istat 0x09 -#define ISTAT_INTEN 0x08 -#define ISTAT_FIFO 0x10 -#define ISTAT_ARBIT 0x20 -#define ISTAT_SEL 0x40 -#define ISTAT_CD 0x80 - -#define tmc_cfg1 0x0a - -#define tmc_ioctl 0x0b -#define IOCTL_IO32 0x80 -#define tmc_cfg2 0x0b - -#define tmc_wfifo 0x0c -#define tmc_rfifo 0x0c - -#define tmc_fdcnt 0x0e - -/* Information transfer phases */ -#define BUSFREE_PHASE 0x00 -#define DATA_OUT_PHASE (BSTAT_BSY) -#define DATA_IN_PHASE (BSTAT_BSY|BSTAT_IO) -#define COMMAND_PHASE (BSTAT_CMD|BSTAT_BSY) -#define STATUS_PHASE (BSTAT_CMD|BSTAT_BSY|BSTAT_IO) -#define MESSAGE_OUT_PHASE (BSTAT_CMD|BSTAT_MSG|BSTAT_BSY) -#define MESSAGE_IN_PHASE (BSTAT_CMD|BSTAT_MSG|BSTAT_BSY|BSTAT_IO) -#define PHASE_RESELECTED (BSTAT_SEL|BSTAT_IO) - -#define BSTAT_PHMASK (BSTAT_MSG | BSTAT_IO | BSTAT_CMD) -#define PHASE_MASK (BSTAT_SEL | BSTAT_BSY | BSTAT_PHMASK) -#define RESEL_PHASE_MASK (BSTAT_SEL | BSTAT_PHMASK) - -#define STG_IS_PHASE_DATA(st) \ - ((((st) & PHASE_MASK) & ~BSTAT_IO) == BSTAT_BSY) - -/* chip type */ -#define TMCCHIP_UNK 0x00 -#define TMCCHIP_1800 0x01 -#define TMCCHIP_18C50 0x02 -#define TMCCHIP_18C30 0x03 - -#define STGIOSZ 0x10 - -#endif /* !_TMC18C30REG_H_ */ diff --git a/sys/dev/disk/stg/tmc18c30var.h b/sys/dev/disk/stg/tmc18c30var.h deleted file mode 100644 index 7ec3a360ab..0000000000 --- a/sys/dev/disk/stg/tmc18c30var.h +++ /dev/null @@ -1,109 +0,0 @@ -/* $FreeBSD: src/sys/dev/stg/tmc18c30var.h,v 1.1.2.4 2001/12/17 13:30:19 non Exp $ */ -/* $DragonFly: src/sys/dev/disk/stg/tmc18c30var.h,v 1.4 2004/02/12 00:00:18 dillon Exp $ */ -/* $NecBSD: tmc18c30var.h,v 1.12.18.2 2001/06/13 05:51:23 honda Exp $ */ -/* $NetBSD$ */ - -/* - * [NetBSD for NEC PC-98 series] - * Copyright (c) 1996, 1997, 1998, 1999, 2000, 2001 - * NetBSD/pc98 porting staff. All rights reserved. - * Copyright (c) 1996, 1997, 1998, 1999, 2000, 2001 - * Naofumi HONDA. All rights reserved. - * Copyright (c) 1996, 1997, 1998 - * Kouichi Matsuda. All rights reserved. - * - * 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. - */ - -#ifndef _TMC18C30VAR_H_ -#define _TMC18C30VAR_H_ - -/***************************************************************** - * Host adapter structure - *****************************************************************/ -struct stg_softc { - struct scsi_low_softc sc_sclow; /* generic data */ - -#ifdef __NetBSD__ - bus_space_tag_t sc_iot; - bus_space_tag_t sc_memt; - bus_space_handle_t sc_ioh; - - void *sc_ih; -#endif /* __NetBSD__ */ - -#ifdef __DragonFly__ - bus_space_tag_t sc_iot; - bus_space_tag_t sc_memt; - bus_space_handle_t sc_ioh; - - int port_rid; - int irq_rid; - int mem_rid; - struct resource *port_res; - struct resource *irq_res; - struct resource *mem_res; - - void *stg_intrhand; -#endif /* __DragonFly__ */ - - int sc_tmaxcnt; - u_int sc_chip; /* chip type */ - u_int sc_fsz; /* fifo size */ - u_int sc_idbit; /* host id bit */ - u_int sc_wthold; /* write thread */ - u_int sc_rthold; /* read thread */ - u_int sc_maxwsize; /* max write size */ - int sc_dataout_timeout; /* data out timeout counter */ - int sc_ubf_timeout; /* unexpected bus free timeout */ - - u_int8_t sc_fcWinit; /* write flags */ - u_int8_t sc_fcRinit; /* read flags */ - - u_int8_t sc_icinit; /* interrupt masks */ - u_int8_t sc_busc; /* default bus control register */ - u_int8_t sc_imsg; /* identify msg required */ - u_int8_t sc_busimg; /* bus control register image */ -}; - -/***************************************************************** - * Lun information - *****************************************************************/ -struct stg_targ_info { - struct targ_info sti_ti; /* generic data */ - - u_int8_t sti_reg_synch; /* synch register per lun */ -}; - -/***************************************************************** - * Proto - *****************************************************************/ -int stgprobesubr (bus_space_tag_t, bus_space_handle_t, u_int); -void stgattachsubr (struct stg_softc *); -int stgprint (void *, const char *); -int stgintr (void *); - -#define SOFT_INTR_REQUIRED(slp) - -#endif /* !_TMC18C30VAR_H_ */ -- 2.11.4.GIT