179697Snon/* $NecBSD: tmc18c30.c,v 1.28.12.3 2001/06/19 04:35:48 honda Exp $ */ 267468Snon/* $NetBSD$ */ 367468Snon 467468Snon#define STG_DEBUG 567468Snon#define STG_STATICS 679697Snon#define STG_IO_CONTROL_FLAGS (STG_FIFO_INTERRUPTS | STG_WAIT_FOR_SELECT) 767468Snon 8139749Simp/*- 967468Snon * [NetBSD for NEC PC-98 series] 1079697Snon * Copyright (c) 1996, 1997, 1998, 1999, 2000, 2001 1167468Snon * NetBSD/pc98 porting staff. All rights reserved. 1279697Snon * Copyright (c) 1996, 1997, 1998, 1999, 2000, 2001 1367468Snon * Naofumi HONDA. All rights reserved. 1467468Snon * Copyright (c) 1996, 1997, 1998, 1999 1567468Snon * Kouichi Matsuda. All rights reserved. 1667468Snon * 1767468Snon * Redistribution and use in source and binary forms, with or without 1867468Snon * modification, are permitted provided that the following conditions 1967468Snon * are met: 2067468Snon * 1. Redistributions of source code must retain the above copyright 2167468Snon * notice, this list of conditions and the following disclaimer. 2267468Snon * 2. Redistributions in binary form must reproduce the above copyright 2367468Snon * notice, this list of conditions and the following disclaimer in the 2467468Snon * documentation and/or other materials provided with the distribution. 2567468Snon * 3. The name of the author may not be used to endorse or promote products 2667468Snon * derived from this software without specific prior written permission. 2767468Snon * 2867468Snon * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 2967468Snon * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 3067468Snon * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 3167468Snon * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 3267468Snon * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 3367468Snon * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 3467468Snon * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3567468Snon * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 3667468Snon * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 3767468Snon * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 3867468Snon * POSSIBILITY OF SUCH DAMAGE. 3967468Snon */ 40119420Sobrien 41119420Sobrien#include <sys/cdefs.h> 42119420Sobrien__FBSDID("$FreeBSD$"); 4367468Snon 4467468Snon#include <sys/param.h> 4567468Snon#include <sys/systm.h> 4667468Snon#include <sys/kernel.h> 4767468Snon#include <sys/bio.h> 4867468Snon#include <sys/buf.h> 4967468Snon#include <sys/queue.h> 5067468Snon#include <sys/malloc.h> 5167468Snon#include <sys/errno.h> 52274760Sjhb#include <sys/rman.h> 5367468Snon 5467468Snon#include <machine/cpu.h> 5567468Snon#include <machine/bus.h> 5667468Snon 5767468Snon#include <cam/scsi/scsi_low.h> 5867468Snon#include <dev/stg/tmc18c30reg.h> 5967468Snon#include <dev/stg/tmc18c30var.h> 6067468Snon 6167468Snon/*************************************************** 6267468Snon * USER SETTINGS 6367468Snon ***************************************************/ 6467468Snon/* DEVICE CONFIGURATION FLAGS (MINOR) 6567468Snon * 66250460Seadler * 0x01 DISCONNECT OFF 6767468Snon * 0x02 PARITY LINE OFF 6867468Snon * 0x04 IDENTIFY MSG OFF ( = single lun) 6967468Snon * 0x08 SYNC TRANSFER OFF 7067468Snon */ 7167468Snon/* #define STG_SYNC_SUPPORT */ /* NOT YET but easy */ 7267468Snon 7367468Snon/* For the 512 fifo type: change below */ 7467468Snon#define TMC18C30_FIFOSZ 0x800 7579697Snon#define TMC18C30_FCBSZ 0x200 7667468Snon#define TMC18C50_FIFOSZ 0x2000 7779697Snon#define TMC18C50_FCBSZ 0x400 7867468Snon 7979697Snon#define STG_MAX_DATA_SIZE (64 * 1024) 8079697Snon#define STG_DELAY_MAX (2 * 1000 * 1000) 8179697Snon#define STG_DELAY_INTERVAL (1) 8279697Snon#define STG_DELAY_SELECT_POLLING_MAX (5 * 1000 * 1000) 8379697Snon 8467468Snon/*************************************************** 8567468Snon * PARAMS 8667468Snon ***************************************************/ 8767468Snon#define STG_NTARGETS 8 8867468Snon#define STG_NLUNS 8 8967468Snon 9067468Snon/*************************************************** 9167468Snon * DEBUG 9267468Snon ***************************************************/ 9367468Snon#ifdef STG_DEBUG 9489093Smsmithstatic int stg_debug; 9567468Snon#endif /* STG_DEBUG */ 9667468Snon 9767468Snon#ifdef STG_STATICS 9889093Smsmithstatic struct stg_statics { 9979697Snon int arbit_fail_0; 10079697Snon int arbit_fail_1; 10167468Snon int disconnect; 10267468Snon int reselect; 10379697Snon} stg_statics; 10467468Snon#endif /* STG_STATICS */ 10567468Snon 10667468Snon/*************************************************** 10779697Snon * IO control flags 10867468Snon ***************************************************/ 10979697Snon#define STG_FIFO_INTERRUPTS 0x0001 11079697Snon#define STG_WAIT_FOR_SELECT 0x0100 11179697Snon 11279697Snonint stg_io_control = STG_IO_CONTROL_FLAGS; 11379697Snon 11479697Snon/*************************************************** 11579697Snon * DEVICE STRUCTURE 11679697Snon ***************************************************/ 11767468Snonextern struct cfdriver stg_cd; 11867468Snon 11967468Snon/************************************************************** 12067468Snon * DECLARE 12167468Snon **************************************************************/ 12267468Snon/* static */ 12392739Salfredstatic void stg_pio_read(struct stg_softc *, struct targ_info *, u_int); 12492739Salfredstatic void stg_pio_write(struct stg_softc *, struct targ_info *, u_int); 12592739Salfredstatic int stg_xfer(struct stg_softc *, u_int8_t *, int, int, int); 12692739Salfredstatic int stg_msg(struct stg_softc *, struct targ_info *, u_int); 12792739Salfredstatic int stg_reselected(struct stg_softc *); 12892739Salfredstatic int stg_disconnected(struct stg_softc *, struct targ_info *); 12992739Salfredstatic __inline void stg_pdma_end(struct stg_softc *, struct targ_info *); 13092739Salfredstatic int stghw_select_targ_wait(struct stg_softc *, int); 13192739Salfredstatic int stghw_check(struct stg_softc *); 13292739Salfredstatic void stghw_init(struct stg_softc *); 13392739Salfredstatic int stg_negate_signal(struct stg_softc *, u_int8_t, u_char *); 13492739Salfredstatic int stg_expect_signal(struct stg_softc *, u_int8_t, u_int8_t); 13592739Salfredstatic int stg_world_start(struct stg_softc *, int); 13692739Salfredstatic int stghw_start_selection(struct stg_softc *sc, struct slccb *); 13792739Salfredstatic void stghw_bus_reset(struct stg_softc *); 13892739Salfredstatic void stghw_attention(struct stg_softc *); 13992739Salfredstatic int stg_target_nexus_establish(struct stg_softc *); 14092739Salfredstatic int stg_lun_nexus_establish(struct stg_softc *); 14192739Salfredstatic int stg_ccb_nexus_establish(struct stg_softc *); 14292739Salfredstatic int stg_targ_init(struct stg_softc *, struct targ_info *, int); 14392739Salfredstatic __inline void stghw_bcr_write_1(struct stg_softc *, u_int8_t); 14492739Salfredstatic int stg_timeout(struct stg_softc *); 14592739Salfredstatic void stg_selection_done_and_expect_msgout(struct stg_softc *); 14667468Snon 14767468Snonstruct scsi_low_funcs stgfuncs = { 14867468Snon SC_LOW_INIT_T stg_world_start, 14967468Snon SC_LOW_BUSRST_T stghw_bus_reset, 15073025Snon SC_LOW_TARG_INIT_T stg_targ_init, 15179697Snon SC_LOW_LUN_INIT_T NULL, 15267468Snon 15367468Snon SC_LOW_SELECT_T stghw_start_selection, 15479697Snon SC_LOW_NEXUS_T stg_lun_nexus_establish, 15579697Snon SC_LOW_NEXUS_T stg_ccb_nexus_establish, 15667468Snon 15767468Snon SC_LOW_ATTEN_T stghw_attention, 15867468Snon SC_LOW_MSG_T stg_msg, 15967468Snon 16079697Snon SC_LOW_TIMEOUT_T stg_timeout, 16167468Snon SC_LOW_POLL_T stgintr, 16267468Snon 16367468Snon NULL, 16467468Snon}; 16567468Snon 16667468Snon/**************************************************** 16779697Snon * hwfuncs 16867468Snon ****************************************************/ 16967468Snonstatic __inline void 170189004Srdivackystghw_bcr_write_1(struct stg_softc *sc, u_int8_t bcv) 17167468Snon{ 17267468Snon 173274760Sjhb bus_write_1(sc->port_res, tmc_bctl, bcv); 17467468Snon sc->sc_busimg = bcv; 17567468Snon} 17667468Snon 17779697Snonstatic int 17879697Snonstghw_check(sc) 17979697Snon struct stg_softc *sc; 18079697Snon{ 18179697Snon struct scsi_low_softc *slp = &sc->sc_sclow; 18279697Snon u_int fcbsize, fcb; 18379697Snon u_int16_t lsb, msb; 18479697Snon 185274760Sjhb lsb = bus_read_1(sc->port_res, tmc_idlsb); 186274760Sjhb msb = bus_read_1(sc->port_res, tmc_idmsb); 18779697Snon switch (msb << 8 | lsb) 18879697Snon { 18979697Snon case 0x6127: 19079697Snon /* TMCCHIP_1800 not supported. (it's my policy) */ 19179697Snon sc->sc_chip = TMCCHIP_1800; 19279697Snon return EINVAL; 19379697Snon 19479697Snon case 0x60e9: 195274760Sjhb if (bus_read_1(sc->port_res, tmc_cfg2) & 0x02) 19679697Snon { 19779697Snon sc->sc_chip = TMCCHIP_18C30; 19879697Snon sc->sc_fsz = TMC18C30_FIFOSZ; 19979697Snon fcbsize = TMC18C30_FCBSZ; 20079697Snon } 20179697Snon else 20279697Snon { 20379697Snon sc->sc_chip = TMCCHIP_18C50; 20479697Snon sc->sc_fsz = TMC18C50_FIFOSZ; 20579697Snon fcbsize = TMC18C50_FCBSZ; 20679697Snon } 20779697Snon break; 20879697Snon 20979697Snon default: 21079697Snon sc->sc_chip = TMCCHIP_UNK; 21179697Snon return ENODEV; 21279697Snon } 21379697Snon 21479697Snon sc->sc_fcRinit = FCTL_INTEN; 21579697Snon sc->sc_fcWinit = FCTL_PARENB | FCTL_INTEN; 21679697Snon 21779697Snon if (slp->sl_cfgflags & CFG_NOATTEN) 21879697Snon sc->sc_imsg = 0; 21979697Snon else 22079697Snon sc->sc_imsg = BCTL_ATN; 22179697Snon sc->sc_busc = BCTL_BUSEN; 22279697Snon 22379697Snon sc->sc_wthold = fcbsize + 256; 22479697Snon sc->sc_rthold = fcbsize - 256; 22579697Snon sc->sc_maxwsize = sc->sc_fsz; 22679697Snon 22779697Snon fcb = fcbsize / (sc->sc_fsz / 16); 22879697Snon sc->sc_icinit = ICTL_CD | ICTL_SEL | ICTL_ARBIT | fcb; 22979697Snon return 0; 23079697Snon} 23179697Snon 23267468Snonstatic void 23379697Snonstghw_init(sc) 23479697Snon struct stg_softc *sc; 23579697Snon{ 23679697Snon 237274760Sjhb bus_write_1(sc->port_res, tmc_ictl, 0); 23879697Snon stghw_bcr_write_1(sc, BCTL_BUSFREE); 239274760Sjhb bus_write_1(sc->port_res, tmc_fctl, 24079697Snon sc->sc_fcRinit | FCTL_CLRFIFO | FCTL_CLRINT); 241274760Sjhb bus_write_1(sc->port_res, tmc_fctl, sc->sc_fcRinit); 242274760Sjhb bus_write_1(sc->port_res, tmc_ictl, sc->sc_icinit); 24379697Snon 244274760Sjhb bus_write_1(sc->port_res, tmc_ssctl, 0); 24579697Snon} 24679697Snon 24779697Snonstatic int 24879697Snonstg_targ_init(sc, ti, action) 24979697Snon struct stg_softc *sc; 25079697Snon struct targ_info *ti; 25179697Snon int action; 25279697Snon{ 25379697Snon struct stg_targ_info *sti = (void *) ti; 25479697Snon 25579697Snon if (action == SCSI_LOW_INFO_ALLOC || action == SCSI_LOW_INFO_REVOKE) 25679697Snon { 25779697Snon ti->ti_width = SCSI_LOW_BUS_WIDTH_8; 25879697Snon ti->ti_maxsynch.period = 0; 25979697Snon ti->ti_maxsynch.offset = 0; 26079697Snon sti->sti_reg_synch = 0; 26179697Snon } 26279697Snon return 0; 26379697Snon} 26479697Snon 26579697Snon/**************************************************** 26679697Snon * scsi low interface 26779697Snon ****************************************************/ 26879697Snonstatic void 26967468Snonstghw_attention(sc) 27067468Snon struct stg_softc *sc; 27167468Snon{ 27267468Snon 27367468Snon sc->sc_busc |= BCTL_ATN; 27467468Snon sc->sc_busimg |= BCTL_ATN; 275274760Sjhb bus_write_1(sc->port_res, tmc_bctl, sc->sc_busimg); 276240172Sjhb DELAY(10); 27767468Snon} 27867468Snon 27967468Snonstatic void 28067468Snonstghw_bus_reset(sc) 28167468Snon struct stg_softc *sc; 28267468Snon{ 28367468Snon 284274760Sjhb bus_write_1(sc->port_res, tmc_ictl, 0); 285274760Sjhb bus_write_1(sc->port_res, tmc_fctl, 0); 28667468Snon stghw_bcr_write_1(sc, BCTL_RST); 287240172Sjhb DELAY(100000); 28867468Snon stghw_bcr_write_1(sc, BCTL_BUSFREE); 28967468Snon} 29067468Snon 29167468Snonstatic int 29267468Snonstghw_start_selection(sc, cb) 29367468Snon struct stg_softc *sc; 29467468Snon struct slccb *cb; 29567468Snon{ 29667468Snon struct targ_info *ti = cb->ti; 29767468Snon register u_int8_t stat; 29867468Snon 29979697Snon sc->sc_tmaxcnt = cb->ccb_tcmax * 1000 * 1000; 30079697Snon sc->sc_dataout_timeout = 0; 30179697Snon sc->sc_ubf_timeout = 0; 30267468Snon stghw_bcr_write_1(sc, BCTL_BUSFREE); 303274760Sjhb bus_write_1(sc->port_res, tmc_ictl, sc->sc_icinit); 30467468Snon 305274760Sjhb stat = bus_read_1(sc->port_res, tmc_astat); 30679697Snon if ((stat & ASTAT_INT) != 0) 30767468Snon { 30879697Snon return SCSI_LOW_START_FAIL; 30967468Snon } 31067468Snon 311274760Sjhb bus_write_1(sc->port_res, tmc_scsiid, sc->sc_idbit); 312274760Sjhb bus_write_1(sc->port_res, tmc_fctl, sc->sc_fcRinit | FCTL_ARBIT); 31367468Snon 31467468Snon SCSI_LOW_SETUP_PHASE(ti, PH_ARBSTART); 31567468Snon return SCSI_LOW_START_OK; 31667468Snon} 31767468Snon 31867468Snonstatic int 31967468Snonstg_world_start(sc, fdone) 32067468Snon struct stg_softc *sc; 32167468Snon int fdone; 32267468Snon{ 32367468Snon struct scsi_low_softc *slp = &sc->sc_sclow; 32467468Snon int error; 32567468Snon 32679697Snon if ((slp->sl_cfgflags & CFG_NOPARITY) == 0) 32779697Snon sc->sc_fcRinit |= FCTL_PARENB; 32879697Snon else 32979697Snon sc->sc_fcRinit &= ~FCTL_PARENB; 33079697Snon 33167468Snon if ((error = stghw_check(sc)) != 0) 33267468Snon return error; 33367468Snon 33467468Snon stghw_init(sc); 33567468Snon scsi_low_bus_reset(slp); 33667468Snon stghw_init(sc); 33767468Snon 33867468Snon return 0; 33967468Snon} 34067468Snon 34167468Snonstatic int 34267468Snonstg_msg(sc, ti, msg) 34367468Snon struct stg_softc *sc; 34467468Snon struct targ_info *ti; 34567468Snon u_int msg; 34667468Snon{ 34773025Snon struct stg_targ_info *sti = (void *) ti; 34867468Snon u_int period, offset; 34967468Snon 35079697Snon if ((msg & SCSI_LOW_MSG_WIDE) != 0) 35179697Snon { 35279697Snon if (ti->ti_width != SCSI_LOW_BUS_WIDTH_8) 35379697Snon { 35479697Snon ti->ti_width = SCSI_LOW_BUS_WIDTH_8; 35579697Snon return EINVAL; 35679697Snon } 35779697Snon return 0; 35879697Snon } 35967468Snon 36079697Snon if ((msg & SCSI_LOW_MSG_SYNCH) == 0) 36179697Snon return 0; 36279697Snon 36373025Snon period = ti->ti_maxsynch.period; 36473025Snon offset = ti->ti_maxsynch.offset; 36567468Snon period = period << 2; 36667468Snon if (period >= 200) 36767468Snon { 36873025Snon sti->sti_reg_synch = (period - 200) / 50; 36967468Snon if (period % 50) 37073025Snon sti->sti_reg_synch ++; 37173025Snon sti->sti_reg_synch |= SSCTL_SYNCHEN; 37267468Snon } 37367468Snon else if (period >= 100) 37467468Snon { 37573025Snon sti->sti_reg_synch = (period - 100) / 50; 37667468Snon if (period % 50) 37773025Snon sti->sti_reg_synch ++; 37873025Snon sti->sti_reg_synch |= SSCTL_SYNCHEN | SSCTL_FSYNCHEN; 37967468Snon } 380274760Sjhb bus_write_1(sc->port_res, tmc_ssctl, sti->sti_reg_synch); 38167468Snon return 0; 38267468Snon} 38367468Snon 38467468Snon/************************************************************** 38567468Snon * General probe attach 38667468Snon **************************************************************/ 38767468Snonint 388274760Sjhbstgprobesubr(struct resource *res, u_int dvcfg) 38967468Snon{ 39067468Snon u_int16_t lsb, msb; 39167468Snon 392274760Sjhb lsb = bus_read_1(res, tmc_idlsb); 393274760Sjhb msb = bus_read_1(res, tmc_idmsb); 39467468Snon switch (msb << 8 | lsb) 39567468Snon { 39667468Snon default: 39767468Snon return 0; 39867468Snon case 0x6127: 39967468Snon /* not support! */ 40067468Snon return 0; 40167468Snon case 0x60e9: 40267468Snon return 1; 40367468Snon } 40467468Snon return 0; 40567468Snon} 40667468Snon 40767468Snonvoid 40867468Snonstgattachsubr(sc) 40967468Snon struct stg_softc *sc; 41067468Snon{ 41167468Snon struct scsi_low_softc *slp = &sc->sc_sclow; 41267468Snon 41367468Snon printf("\n"); 41467468Snon 41567468Snon sc->sc_idbit = (1 << slp->sl_hostid); 41667468Snon slp->sl_funcs = &stgfuncs; 41779697Snon sc->sc_tmaxcnt = SCSI_LOW_MIN_TOUT * 1000 * 1000; /* default */ 41867468Snon 41979697Snon slp->sl_flags |= HW_READ_PADDING; 42067468Snon slp->sl_cfgflags |= CFG_ASYNC; /* XXX */ 42167468Snon 42279697Snon (void) scsi_low_attach(slp, 0, STG_NTARGETS, STG_NLUNS, 42379697Snon sizeof(struct stg_targ_info), 0); 42467468Snon} 42567468Snon 42667468Snon/************************************************************** 42767468Snon * PDMA functions 42867468Snon **************************************************************/ 42967468Snonstatic __inline void 43067468Snonstg_pdma_end(sc, ti) 43167468Snon struct stg_softc *sc; 43267468Snon struct targ_info *ti; 43367468Snon{ 43467468Snon struct scsi_low_softc *slp = &sc->sc_sclow; 43579697Snon struct slccb *cb = slp->sl_Qnexus; 43667468Snon u_int len, tres; 43767468Snon 43867468Snon slp->sl_flags &= ~HW_PDMASTART; 43979697Snon sc->sc_icinit &= ~ICTL_FIFO; 44079697Snon sc->sc_dataout_timeout = 0; 44167468Snon 44279697Snon if (cb == NULL) 44379697Snon { 44479697Snon slp->sl_error |= PDMAERR; 44579697Snon goto out; 44679697Snon } 44779697Snon 44867468Snon if (ti->ti_phase == PH_DATA) 44967468Snon { 450274760Sjhb len = bus_read_2(sc->port_res, tmc_fdcnt); 45167468Snon if (slp->sl_scp.scp_direction == SCSI_LOW_WRITE) 45267468Snon { 45367468Snon if (len != 0) 45467468Snon { 45567468Snon tres = len + slp->sl_scp.scp_datalen; 45667468Snon if (tres <= (u_int) cb->ccb_scp.scp_datalen) 45767468Snon { 45867468Snon slp->sl_scp.scp_data -= len; 45967468Snon slp->sl_scp.scp_datalen = tres; 46067468Snon } 46167468Snon else 46267468Snon { 46367468Snon slp->sl_error |= PDMAERR; 464240325Sjhb device_printf(slp->sl_dev, 465240325Sjhb "len %x >= datalen %x\n", 46667468Snon len, slp->sl_scp.scp_datalen); 46767468Snon } 46867468Snon } 46967468Snon } 47067468Snon else if (slp->sl_scp.scp_direction == SCSI_LOW_READ) 47167468Snon { 47267468Snon if (len != 0) 47367468Snon { 47467468Snon slp->sl_error |= PDMAERR; 475240325Sjhb device_printf(slp->sl_dev, 476240325Sjhb "len %x left in fifo\n", len); 47767468Snon } 47867468Snon } 47979697Snon scsi_low_data_finish(slp); 48067468Snon } 48167468Snon else 48267468Snon { 48367468Snon 484240325Sjhb device_printf(slp->sl_dev, "data phase miss\n"); 48567468Snon slp->sl_error |= PDMAERR; 48667468Snon } 48767468Snon 48879697Snonout: 489274760Sjhb bus_write_1(sc->port_res, tmc_fctl, sc->sc_fcRinit); 49067468Snon} 49167468Snon 49267468Snonstatic void 49379697Snonstg_pio_read(sc, ti, thold) 49467468Snon struct stg_softc *sc; 49567468Snon struct targ_info *ti; 49679697Snon u_int thold; 49767468Snon{ 49867468Snon struct scsi_low_softc *slp = &sc->sc_sclow; 49967468Snon struct sc_p *sp = &slp->sl_scp; 500274760Sjhb int tout; 50167468Snon u_int res; 50267468Snon u_int8_t stat; 50367468Snon 50479697Snon if ((slp->sl_flags & HW_PDMASTART) == 0) 50579697Snon { 506274760Sjhb bus_write_1(sc->port_res, tmc_fctl, 50779697Snon sc->sc_fcRinit | FCTL_FIFOEN); 50879697Snon slp->sl_flags |= HW_PDMASTART; 50979697Snon } 51067468Snon 51179697Snon tout = sc->sc_tmaxcnt; 51279697Snon while (tout -- > 0) 51367468Snon { 51479697Snon if (thold > 0) 51567468Snon { 516274760Sjhb res = bus_read_2(sc->port_res, tmc_fdcnt); 51779697Snon if (res < thold) 51879697Snon { 519274760Sjhb bus_write_1(sc->port_res, tmc_ictl, 52079697Snon sc->sc_icinit); 52179697Snon break; 52279697Snon } 52379697Snon } 52479697Snon else 52579697Snon { 526274760Sjhb stat = bus_read_1(sc->port_res, tmc_bstat); 527274760Sjhb res = bus_read_2(sc->port_res, tmc_fdcnt); 52879697Snon if (res == 0) 52979697Snon { 53079697Snon if ((stat & PHASE_MASK) != DATA_IN_PHASE) 53179697Snon break; 53279697Snon if (sp->scp_datalen <= 0) 53379697Snon break; 534240172Sjhb DELAY(1); 53567468Snon continue; 53679697Snon } 53767468Snon } 53867468Snon 53979697Snon /* The assumtion res != 0 is valid here */ 54067468Snon if (res > sp->scp_datalen) 54167468Snon { 54279697Snon if (res == (u_int) -1) 54379697Snon break; 54479697Snon 54567468Snon slp->sl_error |= PDMAERR; 54679697Snon if ((slp->sl_flags & HW_READ_PADDING) == 0) 54779697Snon { 548240325Sjhb device_printf(slp->sl_dev, 549240325Sjhb "read padding required\n"); 55079697Snon break; 55179697Snon } 55279697Snon 55379697Snon sp->scp_datalen = 0; 55479697Snon if (res > STG_MAX_DATA_SIZE) 55579697Snon res = STG_MAX_DATA_SIZE; 55679697Snon while (res -- > 0) 55779697Snon { 558274760Sjhb (void) bus_read_1(sc->port_res, tmc_rfifo); 55979697Snon } 56079697Snon continue; 56167468Snon } 56267468Snon 56367468Snon sp->scp_datalen -= res; 56467468Snon if (res & 1) 56567468Snon { 566274760Sjhb *sp->scp_data = bus_read_1(sc->port_res, tmc_rfifo); 56767468Snon sp->scp_data ++; 56867468Snon res --; 56967468Snon } 57067468Snon 571274760Sjhb bus_read_multi_2(sc->port_res, tmc_rfifo, 57267468Snon (u_int16_t *) sp->scp_data, res >> 1); 57367468Snon sp->scp_data += res; 57467468Snon } 57567468Snon 57673025Snon if (tout <= 0) 577240325Sjhb device_printf(slp->sl_dev, "pio read timeout\n"); 57867468Snon} 57967468Snon 58067468Snonstatic void 58179697Snonstg_pio_write(sc, ti, thold) 58267468Snon struct stg_softc *sc; 58367468Snon struct targ_info *ti; 58479697Snon u_int thold; 58567468Snon{ 58667468Snon struct scsi_low_softc *slp = &sc->sc_sclow; 58767468Snon struct sc_p *sp = &slp->sl_scp; 58867468Snon u_int res; 589274760Sjhb int tout; 59067468Snon register u_int8_t stat; 59167468Snon 59279697Snon if ((slp->sl_flags & HW_PDMASTART) == 0) 59379697Snon { 59479697Snon stat = sc->sc_fcWinit | FCTL_FIFOEN | FCTL_FIFOW; 595274760Sjhb bus_write_1(sc->port_res, tmc_fctl, stat | FCTL_CLRFIFO); 596274760Sjhb bus_write_1(sc->port_res, tmc_fctl, stat); 59779697Snon slp->sl_flags |= HW_PDMASTART; 59879697Snon } 59967468Snon 60079697Snon tout = sc->sc_tmaxcnt; 60179697Snon while (tout -- > 0) 60267468Snon { 603274760Sjhb stat = bus_read_1(sc->port_res, tmc_bstat); 60479697Snon if ((stat & PHASE_MASK) != DATA_OUT_PHASE) 60567468Snon break; 60667468Snon 60779697Snon if (sp->scp_datalen <= 0) 60879697Snon { 60979697Snon if (sc->sc_dataout_timeout == 0) 61079697Snon sc->sc_dataout_timeout = SCSI_LOW_TIMEOUT_HZ; 61179697Snon break; 61279697Snon } 61367468Snon 61479697Snon if (thold > 0) 61579697Snon { 616274760Sjhb res = bus_read_2(sc->port_res, tmc_fdcnt); 61779697Snon if (res > thold) 61879697Snon { 619274760Sjhb bus_write_1(sc->port_res, tmc_ictl, 62079697Snon sc->sc_icinit); 62179697Snon break; 62279697Snon } 62379697Snon } 62479697Snon else 62579697Snon { 626274760Sjhb res = bus_read_2(sc->port_res, tmc_fdcnt); 62779697Snon if (res > sc->sc_maxwsize / 2) 62879697Snon { 629240172Sjhb DELAY(1); 63079697Snon continue; 63179697Snon } 63279697Snon } 63379697Snon 63479697Snon if (res == (u_int) -1) 63579697Snon break; 63679697Snon res = sc->sc_maxwsize - res; 63779697Snon if (res > sp->scp_datalen) 63879697Snon res = sp->scp_datalen; 63979697Snon 64067468Snon sp->scp_datalen -= res; 64167468Snon if ((res & 0x1) != 0) 64267468Snon { 643274760Sjhb bus_write_1(sc->port_res, tmc_wfifo, *sp->scp_data); 64467468Snon sp->scp_data ++; 64567468Snon res --; 64667468Snon } 64767468Snon 648274760Sjhb bus_write_multi_2(sc->port_res, tmc_wfifo, 64967468Snon (u_int16_t *) sp->scp_data, res >> 1); 65067468Snon sp->scp_data += res; 65167468Snon } 65267468Snon 65373025Snon if (tout <= 0) 654240325Sjhb device_printf(slp->sl_dev, "pio write timeout\n"); 65567468Snon} 65667468Snon 65767468Snonstatic int 658189004Srdivackystg_negate_signal(struct stg_softc *sc, u_int8_t mask, u_char *s) 65967468Snon{ 66067468Snon struct scsi_low_softc *slp = &sc->sc_sclow; 66179697Snon int wc; 66267468Snon u_int8_t regv; 66367468Snon 66479697Snon for (wc = 0; wc < STG_DELAY_MAX / STG_DELAY_INTERVAL; wc ++) 66567468Snon { 666274760Sjhb regv = bus_read_1(sc->port_res, tmc_bstat); 66779697Snon if (regv == (u_int8_t) -1) 66879697Snon return -1; 66979697Snon if ((regv & mask) == 0) 67079697Snon return 1; 67179697Snon 672240172Sjhb DELAY(STG_DELAY_INTERVAL); 67367468Snon } 67467468Snon 675240325Sjhb device_printf(slp->sl_dev, "%s stg_negate_signal timeout\n", s); 67679697Snon return -1; 67767468Snon} 67867468Snon 67967468Snonstatic int 680189004Srdivackystg_expect_signal(struct stg_softc *sc, u_int8_t phase, u_int8_t mask) 68167468Snon{ 68267468Snon struct scsi_low_softc *slp = &sc->sc_sclow; 68379697Snon int wc; 68467468Snon u_int8_t ph; 68567468Snon 68679697Snon phase &= PHASE_MASK; 68779697Snon for (wc = 0; wc < STG_DELAY_MAX / STG_DELAY_INTERVAL; wc ++) 68867468Snon { 689274760Sjhb ph = bus_read_1(sc->port_res, tmc_bstat); 69079697Snon if (ph == (u_int8_t) -1) 69179697Snon return -1; 69279697Snon if ((ph & PHASE_MASK) != phase) 69379697Snon return 0; 69479697Snon if ((ph & mask) != 0) 69579697Snon return 1; 69679697Snon 697240172Sjhb DELAY(STG_DELAY_INTERVAL); 69867468Snon } 69967468Snon 700240325Sjhb device_printf(slp->sl_dev, "stg_expect_signal timeout\n"); 70179697Snon return -1; 70267468Snon} 70367468Snon 70467468Snonstatic int 70579697Snonstg_xfer(sc, buf, len, phase, clear_atn) 70667468Snon struct stg_softc *sc; 70767468Snon u_int8_t *buf; 70867468Snon int len; 70967468Snon int phase; 71079697Snon int clear_atn; 71167468Snon{ 71279697Snon int rv, ptr; 71367468Snon 71467468Snon if (phase & BSTAT_IO) 715274760Sjhb bus_write_1(sc->port_res, tmc_fctl, sc->sc_fcRinit); 71667468Snon else 717274760Sjhb bus_write_1(sc->port_res, tmc_fctl, sc->sc_fcWinit); 71867468Snon 71967468Snon for (ptr = 0; len > 0; len --) 72067468Snon { 72167468Snon rv = stg_expect_signal(sc, phase, BSTAT_REQ); 72267468Snon if (rv <= 0) 72367468Snon goto bad; 72467468Snon 72579697Snon if (len == 1 && clear_atn != 0) 72667468Snon { 72767468Snon sc->sc_busc &= ~BCTL_ATN; 72867468Snon stghw_bcr_write_1(sc, sc->sc_busc); 72979697Snon SCSI_LOW_DEASSERT_ATN(&sc->sc_sclow); 73067468Snon } 73167468Snon 73267468Snon if (phase & BSTAT_IO) 73367468Snon { 734274760Sjhb buf[ptr ++] = bus_read_1(sc->port_res, tmc_rdata); 73567468Snon } 73667468Snon else 73767468Snon { 738274760Sjhb bus_write_1(sc->port_res, tmc_wdata, buf[ptr ++]); 73967468Snon } 74079697Snon 74167468Snon stg_negate_signal(sc, BSTAT_ACK, "xfer<ACK>"); 74267468Snon } 74367468Snon 74467468Snonbad: 745274760Sjhb bus_write_1(sc->port_res, tmc_fctl, sc->sc_fcRinit); 74667468Snon return len; 74767468Snon} 74867468Snon 74967468Snon/************************************************************** 75067468Snon * disconnect & reselect (HW low) 75167468Snon **************************************************************/ 75267468Snonstatic int 75367468Snonstg_reselected(sc) 75467468Snon struct stg_softc *sc; 75567468Snon{ 75667468Snon struct scsi_low_softc *slp = &sc->sc_sclow; 75779697Snon int tout; 75867468Snon u_int sid; 75979697Snon u_int8_t regv; 76067468Snon 76167468Snon if (slp->sl_selid != NULL) 76267468Snon { 76367468Snon /* XXX: 76467468Snon * Selection vs Reselection conflicts. 76567468Snon */ 766274760Sjhb bus_write_1(sc->port_res, tmc_fctl, sc->sc_fcRinit); 76767468Snon stghw_bcr_write_1(sc, BCTL_BUSFREE); 76867468Snon } 76979697Snon else if (slp->sl_Tnexus != NULL) 77079697Snon { 771240325Sjhb device_printf(slp->sl_dev, "unexpected termination\n"); 77279697Snon stg_disconnected(sc, slp->sl_Tnexus); 77379697Snon } 77467468Snon 77567468Snon /* XXX: 77667468Snon * We should ack the reselection as soon as possible, 777123608Sjhb * because the target would abort the current reselection seq 77867468Snon * due to reselection timeout. 77967468Snon */ 78079697Snon tout = STG_DELAY_SELECT_POLLING_MAX; 78179697Snon while (tout -- > 0) 78279697Snon { 783274760Sjhb regv = bus_read_1(sc->port_res, tmc_bstat); 78479697Snon if ((regv & (BSTAT_IO | BSTAT_SEL | BSTAT_BSY)) == 78579697Snon (BSTAT_IO | BSTAT_SEL)) 78679697Snon { 787240172Sjhb DELAY(1); 788274760Sjhb regv = bus_read_1(sc->port_res, tmc_bstat); 78979697Snon if ((regv & (BSTAT_IO | BSTAT_SEL | BSTAT_BSY)) == 79079697Snon (BSTAT_IO | BSTAT_SEL)) 79179697Snon goto reselect_start; 79279697Snon } 793240172Sjhb DELAY(1); 79479697Snon } 795240325Sjhb device_printf(slp->sl_dev, "reselction timeout I\n"); 79679697Snon return EJUSTRETURN; 79779697Snon 79879697Snonreselect_start: 799274760Sjhb sid = (u_int) bus_read_1(sc->port_res, tmc_scsiid); 80079697Snon if ((sid & sc->sc_idbit) == 0) 80179697Snon { 80279697Snon /* not us */ 80379697Snon return EJUSTRETURN; 80479697Snon } 80579697Snon 806274760Sjhb bus_write_1(sc->port_res, tmc_fctl, 80779697Snon sc->sc_fcRinit | FCTL_CLRFIFO | FCTL_CLRINT); 808274760Sjhb bus_write_1(sc->port_res, tmc_fctl, sc->sc_fcRinit); 80967468Snon stghw_bcr_write_1(sc, sc->sc_busc | BCTL_BSY); 81067468Snon 81179697Snon while (tout -- > 0) 81279697Snon { 813274760Sjhb regv = bus_read_1(sc->port_res, tmc_bstat); 81479697Snon if ((regv & (BSTAT_SEL | BSTAT_BSY)) == BSTAT_BSY) 81579697Snon goto reselected; 816240172Sjhb DELAY(1); 81779697Snon } 818240325Sjhb device_printf(slp->sl_dev, "reselction timeout II\n"); 81979697Snon return EJUSTRETURN; 82079697Snon 82179697Snonreselected: 82267468Snon sid &= ~sc->sc_idbit; 82367468Snon sid = ffs(sid) - 1; 82479697Snon if (scsi_low_reselected(slp, sid) == NULL) 82567468Snon return EJUSTRETURN; 82667468Snon 82767468Snon#ifdef STG_STATICS 82879697Snon stg_statics.reselect ++; 82967468Snon#endif /* STG_STATICS */ 83067468Snon return EJUSTRETURN; 83167468Snon} 83267468Snon 83379697Snonstatic int 83467468Snonstg_disconnected(sc, ti) 83567468Snon struct stg_softc *sc; 83667468Snon struct targ_info *ti; 83767468Snon{ 83867468Snon struct scsi_low_softc *slp = &sc->sc_sclow; 83967468Snon 84067468Snon /* clear bus status & fifo */ 841274760Sjhb bus_write_1(sc->port_res, tmc_fctl, sc->sc_fcRinit | FCTL_CLRFIFO); 842274760Sjhb bus_write_1(sc->port_res, tmc_fctl, sc->sc_fcRinit); 84367468Snon stghw_bcr_write_1(sc, BCTL_BUSFREE); 84479697Snon sc->sc_icinit &= ~ICTL_FIFO; 84567468Snon sc->sc_busc &= ~BCTL_ATN; 84679697Snon sc->sc_dataout_timeout = 0; 84779697Snon sc->sc_ubf_timeout = 0; 84867468Snon 84967468Snon#ifdef STG_STATICS 85079697Snon stg_statics.disconnect ++; 85167468Snon#endif /* STG_STATICS */ 85267468Snon scsi_low_disconnected(slp, ti); 85367468Snon return 1; 85467468Snon} 85567468Snon 85667468Snon/************************************************************** 85767468Snon * SEQUENCER 85867468Snon **************************************************************/ 85967468Snonstatic int 86079697Snonstg_target_nexus_establish(sc) 86167468Snon struct stg_softc *sc; 86267468Snon{ 86379697Snon struct scsi_low_softc *slp = &sc->sc_sclow; 86479697Snon struct targ_info *ti = slp->sl_Tnexus; 86573025Snon struct stg_targ_info *sti = (void *) ti; 86667468Snon 867274760Sjhb bus_write_1(sc->port_res, tmc_ssctl, sti->sti_reg_synch); 86879697Snon if ((stg_io_control & STG_FIFO_INTERRUPTS) != 0) 86979697Snon { 87079697Snon sc->sc_icinit |= ICTL_FIFO; 87179697Snon } 87267468Snon return 0; 87367468Snon} 87467468Snon 87567468Snonstatic int 87679697Snonstg_lun_nexus_establish(sc) 87767468Snon struct stg_softc *sc; 87867468Snon{ 87979697Snon 88079697Snon return 0; 88179697Snon} 88279697Snon 88379697Snonstatic int 88479697Snonstg_ccb_nexus_establish(sc) 88579697Snon struct stg_softc *sc; 88679697Snon{ 88779697Snon struct scsi_low_softc *slp = &sc->sc_sclow; 88879697Snon struct slccb *cb = slp->sl_Qnexus; 88979697Snon 89079697Snon sc->sc_tmaxcnt = cb->ccb_tcmax * 1000 * 1000; 89179697Snon return 0; 89279697Snon} 89379697Snon 89479697Snon#define STGHW_SELECT_INTERVAL 10 89579697Snon 89679697Snonstatic int 89779697Snonstghw_select_targ_wait(sc, mu) 89879697Snon struct stg_softc *sc; 89979697Snon int mu; 90079697Snon{ 90167468Snon 90279697Snon mu = mu / STGHW_SELECT_INTERVAL; 90379697Snon while (mu -- > 0) 90467468Snon { 905274760Sjhb if ((bus_read_1(sc->port_res, tmc_bstat) & BSTAT_BSY) == 0) 90667468Snon { 907240172Sjhb DELAY(STGHW_SELECT_INTERVAL); 90879697Snon continue; 90967468Snon } 910240172Sjhb DELAY(1); 911274760Sjhb if ((bus_read_1(sc->port_res, tmc_bstat) & BSTAT_BSY) != 0) 91279697Snon { 91379697Snon return 0; 91479697Snon } 91567468Snon } 91679697Snon return ENXIO; 91779697Snon} 91867468Snon 91979697Snonstatic void 92079697Snonstg_selection_done_and_expect_msgout(sc) 92179697Snon struct stg_softc *sc; 92279697Snon{ 92379697Snon struct scsi_low_softc *slp = &sc->sc_sclow; 92479697Snon 925274760Sjhb bus_write_1(sc->port_res, tmc_fctl, sc->sc_fcRinit | FCTL_CLRFIFO); 926274760Sjhb bus_write_1(sc->port_res, tmc_fctl, sc->sc_fcRinit); 92779697Snon stghw_bcr_write_1(sc, sc->sc_imsg | sc->sc_busc); 92879697Snon SCSI_LOW_ASSERT_ATN(slp); 92967468Snon} 93067468Snon 93167468Snonint 93267468Snonstgintr(arg) 93367468Snon void *arg; 93467468Snon{ 93567468Snon struct stg_softc *sc = arg; 93667468Snon struct scsi_low_softc *slp = &sc->sc_sclow; 93767468Snon struct targ_info *ti; 93867468Snon struct buf *bp; 93979697Snon u_int derror, flags; 940274760Sjhb int len; 94167468Snon u_int8_t status, astatus, regv; 94267468Snon 94367468Snon /******************************************* 94467468Snon * interrupt check 94567468Snon *******************************************/ 94667468Snon if (slp->sl_flags & HW_INACTIVE) 94767468Snon return 0; 94867468Snon 949274760Sjhb astatus = bus_read_1(sc->port_res, tmc_astat); 950274760Sjhb status = bus_read_1(sc->port_res, tmc_bstat); 95167468Snon 95279697Snon if ((astatus & ASTAT_STATMASK) == 0 || astatus == (u_int8_t) -1) 95367468Snon return 0; 95467468Snon 955274760Sjhb bus_write_1(sc->port_res, tmc_ictl, 0); 95667468Snon if (astatus & ASTAT_SCSIRST) 95767468Snon { 958274760Sjhb bus_write_1(sc->port_res, tmc_fctl, 95967468Snon sc->sc_fcRinit | FCTL_CLRFIFO); 960274760Sjhb bus_write_1(sc->port_res, tmc_fctl, sc->sc_fcRinit); 961274760Sjhb bus_write_1(sc->port_res, tmc_ictl, 0); 96267468Snon 96367468Snon scsi_low_restart(slp, SCSI_LOW_RESTART_SOFT, 96467468Snon "bus reset (power off?)"); 96567468Snon return 1; 96667468Snon } 96767468Snon 96867468Snon /******************************************* 96967468Snon * debug section 97067468Snon *******************************************/ 97167468Snon#ifdef STG_DEBUG 97267468Snon if (stg_debug) 97367468Snon { 97467468Snon scsi_low_print(slp, NULL); 975240325Sjhb device_printf(slp->sl_dev, "st %x ist %x\n\n", 97667468Snon status, astatus); 977131920Smarcel#ifdef KDB 97867468Snon if (stg_debug > 1) 979240172Sjhb kdb_enter(KDB_WHY_CAM, "stg"); 980131920Smarcel#endif /* KDB */ 98167468Snon } 98267468Snon#endif /* STG_DEBUG */ 98367468Snon 98467468Snon /******************************************* 98567468Snon * reselection & nexus 98667468Snon *******************************************/ 98767468Snon if ((status & RESEL_PHASE_MASK)== PHASE_RESELECTED) 98867468Snon { 98967468Snon if (stg_reselected(sc) == EJUSTRETURN) 99079697Snon goto out; 99167468Snon } 99267468Snon 99379697Snon if ((ti = slp->sl_Tnexus) == NULL) 99479697Snon return 0; 99567468Snon 99679697Snon derror = 0; 99767468Snon if ((astatus & ASTAT_PARERR) != 0 && ti->ti_phase != PH_ARBSTART && 99867468Snon (sc->sc_fcRinit & FCTL_PARENB) != 0) 99967468Snon { 100067468Snon slp->sl_error |= PARITYERR; 100179697Snon derror = SCSI_LOW_DATA_PE; 100279697Snon if ((status & PHASE_MASK) == MESSAGE_IN_PHASE) 100379697Snon scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_PARITY, 0); 100467468Snon else 100567468Snon scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ERROR, 1); 100667468Snon } 100767468Snon 100867468Snon /******************************************* 100967468Snon * aribitration & selection 101067468Snon *******************************************/ 101167468Snon switch (ti->ti_phase) 101267468Snon { 101367468Snon case PH_ARBSTART: 101467468Snon if ((astatus & ASTAT_ARBIT) == 0) 101579697Snon { 101679697Snon#ifdef STG_STATICS 101779697Snon stg_statics.arbit_fail_0 ++; 101879697Snon#endif /* STG_STATICS */ 101967468Snon goto arb_fail; 102079697Snon } 102167468Snon 1022274760Sjhb status = bus_read_1(sc->port_res, tmc_bstat); 102367468Snon if ((status & BSTAT_IO) != 0) 102467468Snon { 102567468Snon /* XXX: 102667468Snon * Selection vs Reselection conflicts. 102767468Snon */ 102867468Snon#ifdef STG_STATICS 102979697Snon stg_statics.arbit_fail_1 ++; 103067468Snon#endif /* STG_STATICS */ 103167468Snonarb_fail: 1032274760Sjhb bus_write_1(sc->port_res, tmc_fctl, sc->sc_fcRinit); 103367468Snon stghw_bcr_write_1(sc, BCTL_BUSFREE); 103479697Snon scsi_low_arbit_fail(slp, slp->sl_Qnexus); 103579697Snon goto out; 103667468Snon } 103767468Snon 103867468Snon /* 103967468Snon * selection assert start. 104067468Snon */ 104167468Snon SCSI_LOW_SETUP_PHASE(ti, PH_SELSTART); 104279697Snon scsi_low_arbit_win(slp); 104379697Snon 1044274760Sjhb bus_write_1(sc->port_res, tmc_scsiid, 104567468Snon sc->sc_idbit | (1 << ti->ti_id)); 104667468Snon stghw_bcr_write_1(sc, sc->sc_imsg | sc->sc_busc | BCTL_SEL); 1047274760Sjhb bus_write_1(sc->port_res, tmc_fctl, sc->sc_fcWinit); 104879697Snon if ((stg_io_control & STG_WAIT_FOR_SELECT) != 0) 104979697Snon { 105079697Snon /* selection abort delay 200 + 100 micro sec */ 105179697Snon if (stghw_select_targ_wait(sc, 300) == 0) 105279697Snon { 105379697Snon SCSI_LOW_SETUP_PHASE(ti, PH_SELECTED); 105479697Snon stg_selection_done_and_expect_msgout(sc); 105579697Snon } 105679697Snon } 105779697Snon goto out; 105867468Snon 105967468Snon case PH_SELSTART: 106067468Snon if ((status & BSTAT_BSY) == 0) 106167468Snon { 106279697Snon /* selection timeout delay 250 ms */ 106379697Snon if (stghw_select_targ_wait(sc, 250 * 1000) != 0) 106467468Snon { 106579697Snon stg_disconnected(sc, ti); 106679697Snon goto out; 106767468Snon } 106867468Snon } 106967468Snon 107067468Snon SCSI_LOW_SETUP_PHASE(ti, PH_SELECTED); 107179697Snon stg_selection_done_and_expect_msgout(sc); 107279697Snon goto out; 107367468Snon 107479697Snon case PH_SELECTED: 107579697Snon if ((status & BSTAT_REQ) == 0) 107679697Snon goto out; 107779697Snon stg_target_nexus_establish(sc); 107879697Snon break; 107979697Snon 108067468Snon case PH_RESEL: 108179697Snon if ((status & BSTAT_REQ) == 0) 108279697Snon goto out; 108379697Snon 108467468Snon /* clear a busy line */ 1085274760Sjhb bus_write_1(sc->port_res, tmc_fctl, sc->sc_fcRinit); 108667468Snon stghw_bcr_write_1(sc, sc->sc_busc); 108779697Snon stg_target_nexus_establish(sc); 108867468Snon if ((status & PHASE_MASK) != MESSAGE_IN_PHASE) 108967468Snon { 1090240325Sjhb device_printf(slp->sl_dev, 1091240325Sjhb "unexpected phase after reselect\n"); 109279697Snon slp->sl_error |= FATALIO; 109367468Snon scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 1); 109479697Snon goto out; 109567468Snon } 109667468Snon break; 109767468Snon } 109867468Snon 109967468Snon /******************************************* 110079697Snon * data phase 110167468Snon *******************************************/ 110279697Snon if ((slp->sl_flags & HW_PDMASTART) && STG_IS_PHASE_DATA(status) == 0) 110379697Snon { 110479697Snon if (slp->sl_scp.scp_direction == SCSI_LOW_READ) 110579697Snon stg_pio_read(sc, ti, 0); 110679697Snon 110767468Snon stg_pdma_end(sc, ti); 110879697Snon } 110967468Snon 111079697Snon /******************************************* 111179697Snon * scsi seq 111279697Snon *******************************************/ 111367468Snon switch (status & PHASE_MASK) 111467468Snon { 111567468Snon case COMMAND_PHASE: 111679697Snon if (stg_expect_signal(sc, COMMAND_PHASE, BSTAT_REQ) <= 0) 111779697Snon break; 111879697Snon 111967468Snon SCSI_LOW_SETUP_PHASE(ti, PH_CMD); 112067468Snon if (scsi_low_cmd(slp, ti) != 0) 112179697Snon { 112279697Snon scsi_low_attention(slp); 112379697Snon } 112467468Snon 112579697Snon if (stg_xfer(sc, slp->sl_scp.scp_cmd, slp->sl_scp.scp_cmdlen, 112679697Snon COMMAND_PHASE, 0) != 0) 112767468Snon { 1128240325Sjhb device_printf(slp->sl_dev, "CMDOUT short\n"); 112967468Snon } 113067468Snon break; 113167468Snon 113267468Snon case DATA_OUT_PHASE: 113367468Snon SCSI_LOW_SETUP_PHASE(ti, PH_DATA); 113467468Snon if (scsi_low_data(slp, ti, &bp, SCSI_LOW_WRITE) != 0) 113579697Snon { 113679697Snon scsi_low_attention(slp); 113779697Snon } 113867468Snon 113979697Snon if ((sc->sc_icinit & ICTL_FIFO) != 0) 114079697Snon stg_pio_write(sc, ti, sc->sc_wthold); 114179697Snon else 114279697Snon stg_pio_write(sc, ti, 0); 114367468Snon break; 114467468Snon 114567468Snon case DATA_IN_PHASE: 114667468Snon SCSI_LOW_SETUP_PHASE(ti, PH_DATA); 114767468Snon if (scsi_low_data(slp, ti, &bp, SCSI_LOW_READ) != 0) 114879697Snon { 114979697Snon scsi_low_attention(slp); 115079697Snon } 115167468Snon 115279697Snon if ((sc->sc_icinit & ICTL_FIFO) != 0) 115379697Snon stg_pio_read(sc, ti, sc->sc_rthold); 115479697Snon else 115579697Snon stg_pio_read(sc, ti, 0); 115667468Snon break; 115767468Snon 115867468Snon case STATUS_PHASE: 115979697Snon regv = stg_expect_signal(sc, STATUS_PHASE, BSTAT_REQ); 116079697Snon if (regv <= 0) 116179697Snon break; 116279697Snon 116367468Snon SCSI_LOW_SETUP_PHASE(ti, PH_STAT); 1164274760Sjhb regv = bus_read_1(sc->port_res, tmc_sdna); 116579697Snon if (scsi_low_statusin(slp, ti, regv | derror) != 0) 116679697Snon { 116779697Snon scsi_low_attention(slp); 116879697Snon } 1169274760Sjhb if (regv != bus_read_1(sc->port_res, tmc_rdata)) 117079697Snon { 1171240325Sjhb device_printf(slp->sl_dev, "STATIN: data mismatch\n"); 117279697Snon } 117379697Snon stg_negate_signal(sc, BSTAT_ACK, "statin<ACK>"); 117467468Snon break; 117567468Snon 117667468Snon case MESSAGE_OUT_PHASE: 117779697Snon if (stg_expect_signal(sc, MESSAGE_OUT_PHASE, BSTAT_REQ) <= 0) 117879697Snon break; 117979697Snon 118067468Snon SCSI_LOW_SETUP_PHASE(ti, PH_MSGOUT); 118179697Snon flags = (ti->ti_ophase != ti->ti_phase) ? 118279697Snon SCSI_LOW_MSGOUT_INIT : 0; 118379697Snon len = scsi_low_msgout(slp, ti, flags); 118479697Snon 118579697Snon if (len > 1 && slp->sl_atten == 0) 118667468Snon { 118779697Snon scsi_low_attention(slp); 118879697Snon } 118979697Snon 119079697Snon if (stg_xfer(sc, ti->ti_msgoutstr, len, MESSAGE_OUT_PHASE, 119179697Snon slp->sl_clear_atten) != 0) 119279697Snon { 1193240325Sjhb device_printf(slp->sl_dev, "MSGOUT short\n"); 119467468Snon } 119579697Snon else 119679697Snon { 119779697Snon if (slp->sl_msgphase >= MSGPH_ABORT) 119879697Snon { 119979697Snon stg_disconnected(sc, ti); 120079697Snon } 120179697Snon } 120267468Snon break; 120367468Snon 120467468Snon case MESSAGE_IN_PHASE: 120579697Snon /* confirm phase and req signal */ 120679697Snon if (stg_expect_signal(sc, MESSAGE_IN_PHASE, BSTAT_REQ) <= 0) 120779697Snon break; 120879697Snon 120967468Snon SCSI_LOW_SETUP_PHASE(ti, PH_MSGIN); 121067468Snon 121179697Snon /* read data with NOACK */ 1212274760Sjhb regv = bus_read_1(sc->port_res, tmc_sdna); 121379697Snon 121479697Snon if (scsi_low_msgin(slp, ti, derror | regv) == 0) 121567468Snon { 121679697Snon if (scsi_low_is_msgout_continue(ti, 0) != 0) 121779697Snon { 121879697Snon scsi_low_attention(slp); 121979697Snon } 122067468Snon } 122167468Snon 122267468Snon /* read data with ACK */ 1223274760Sjhb if (regv != bus_read_1(sc->port_res, tmc_rdata)) 122467468Snon { 1225240325Sjhb device_printf(slp->sl_dev, "MSGIN: data mismatch\n"); 122667468Snon } 122767468Snon 122879697Snon /* wait for the ack negated */ 122979697Snon stg_negate_signal(sc, BSTAT_ACK, "msgin<ACK>"); 123079697Snon 123179697Snon if (slp->sl_msgphase != 0 && slp->sl_msgphase < MSGPH_ABORT) 123267468Snon { 123379697Snon stg_disconnected(sc, ti); 123467468Snon } 123567468Snon break; 123667468Snon 123767468Snon case BUSFREE_PHASE: 1238240325Sjhb device_printf(slp->sl_dev, "unexpected disconnect\n"); 123979697Snon stg_disconnected(sc, ti); 124079697Snon break; 124167468Snon 124267468Snon default: 124379697Snon slp->sl_error |= FATALIO; 1244240325Sjhb device_printf(slp->sl_dev, "unknown phase bus %x intr %x\n", 1245240325Sjhb status, astatus); 124667468Snon break; 124767468Snon } 124867468Snon 124979697Snonout: 1250274760Sjhb bus_write_1(sc->port_res, tmc_ictl, sc->sc_icinit); 125167468Snon return 1; 125267468Snon} 125379697Snon 125479697Snonstatic int 125579697Snonstg_timeout(sc) 125679697Snon struct stg_softc *sc; 125779697Snon{ 125879697Snon struct scsi_low_softc *slp = &sc->sc_sclow; 125979697Snon int tout, count; 126079697Snon u_int8_t status; 126179697Snon 126279697Snon if (slp->sl_Tnexus == NULL) 126379697Snon return 0; 126479697Snon 1265274760Sjhb status = bus_read_1(sc->port_res, tmc_bstat); 126679697Snon if ((status & PHASE_MASK) == 0) 126779697Snon { 126879697Snon if (sc->sc_ubf_timeout ++ == 0) 126979697Snon return 0; 127079697Snon 1271240325Sjhb device_printf(slp->sl_dev, "unexpected bus free detected\n"); 127279697Snon slp->sl_error |= FATALIO; 127379697Snon scsi_low_print(slp, slp->sl_Tnexus); 127479697Snon stg_disconnected(sc, slp->sl_Tnexus); 127579697Snon return 0; 127679697Snon } 127779697Snon 127879697Snon switch (status & PHASE_MASK) 127979697Snon { 128079697Snon case DATA_OUT_PHASE: 128179697Snon if (sc->sc_dataout_timeout == 0) 128279697Snon break; 128379697Snon if ((status & BSTAT_REQ) == 0) 128479697Snon break; 1285274760Sjhb if (bus_read_2(sc->port_res, tmc_fdcnt) != 0) 128679697Snon break; 128779697Snon if ((-- sc->sc_dataout_timeout) > 0) 128879697Snon break; 128979697Snon 129079697Snon slp->sl_error |= PDMAERR; 129179697Snon if ((slp->sl_flags & HW_WRITE_PADDING) == 0) 129279697Snon { 1293240325Sjhb device_printf(slp->sl_dev, "write padding required\n"); 129479697Snon break; 129579697Snon } 129679697Snon 1297274760Sjhb bus_write_1(sc->port_res, tmc_ictl, 0); 129879697Snon 129979697Snon tout = STG_DELAY_MAX; 130079697Snon while (tout --) 130179697Snon { 1302274760Sjhb status = bus_read_1(sc->port_res, tmc_bstat); 130379697Snon if ((status & PHASE_MASK) != DATA_OUT_PHASE) 130479697Snon break; 130579697Snon 1306274760Sjhb if (bus_read_2(sc->port_res, tmc_fdcnt) != 0) 130779697Snon { 1308240172Sjhb DELAY(1); 130979697Snon continue; 131079697Snon } 131179697Snon 131279697Snon for (count = sc->sc_maxwsize; count > 0; count --) 1313274760Sjhb bus_write_1(sc->port_res, tmc_wfifo, 0); 131479697Snon } 131579697Snon 1316274760Sjhb status = bus_read_1(sc->port_res, tmc_bstat); 131779697Snon if ((status & PHASE_MASK) == DATA_OUT_PHASE) 131879697Snon sc->sc_dataout_timeout = SCSI_LOW_TIMEOUT_HZ; 131979697Snon 1320274760Sjhb bus_write_1(sc->port_res, tmc_ictl, sc->sc_icinit); 132179697Snon break; 132279697Snon 132379697Snon default: 132479697Snon break; 132579697Snon } 132679697Snon return 0; 132779697Snon} 1328