1 1.44 andvar /* $NetBSD: trm.c,v 1.44 2024/02/09 22:08:36 andvar Exp $ */ 2 1.30 tsutsui /*- 3 1.30 tsutsui * Copyright (c) 2002 Izumi Tsutsui. All rights reserved. 4 1.30 tsutsui * 5 1.30 tsutsui * Redistribution and use in source and binary forms, with or without 6 1.30 tsutsui * modification, are permitted provided that the following conditions 7 1.30 tsutsui * are met: 8 1.30 tsutsui * 1. Redistributions of source code must retain the above copyright 9 1.30 tsutsui * notice, this list of conditions and the following disclaimer. 10 1.30 tsutsui * 2. Redistributions in binary form must reproduce the above copyright 11 1.30 tsutsui * notice, this list of conditions and the following disclaimer in the 12 1.30 tsutsui * documentation and/or other materials provided with the distribution. 13 1.30 tsutsui * 14 1.30 tsutsui * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 15 1.30 tsutsui * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16 1.30 tsutsui * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17 1.30 tsutsui * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 18 1.30 tsutsui * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19 1.30 tsutsui * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20 1.30 tsutsui * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21 1.30 tsutsui * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 1.30 tsutsui * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23 1.30 tsutsui * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 1.30 tsutsui */ 25 1.30 tsutsui 26 1.1 tsutsui /* 27 1.1 tsutsui * Device Driver for Tekram DC395U/UW/F, DC315/U 28 1.1 tsutsui * PCI SCSI Bus Master Host Adapter 29 1.1 tsutsui * (SCSI chip set used Tekram ASIC TRM-S1040) 30 1.1 tsutsui * 31 1.1 tsutsui * Copyright (c) 2001 Rui-Xiang Guo 32 1.1 tsutsui * All rights reserved. 33 1.1 tsutsui * 34 1.1 tsutsui * Redistribution and use in source and binary forms, with or without 35 1.1 tsutsui * modification, are permitted provided that the following conditions 36 1.1 tsutsui * are met: 37 1.1 tsutsui * 1. Redistributions of source code must retain the above copyright 38 1.1 tsutsui * notice, this list of conditions and the following disclaimer. 39 1.1 tsutsui * 2. Redistributions in binary form must reproduce the above copyright 40 1.1 tsutsui * notice, this list of conditions and the following disclaimer in the 41 1.1 tsutsui * documentation and/or other materials provided with the distribution. 42 1.1 tsutsui * 3. The name of the author may not be used to endorse or promote products 43 1.1 tsutsui * derived from this software without specific prior written permission. 44 1.1 tsutsui * 45 1.1 tsutsui * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 46 1.1 tsutsui * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 47 1.1 tsutsui * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 48 1.1 tsutsui * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 49 1.1 tsutsui * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 50 1.1 tsutsui * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 51 1.1 tsutsui * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 52 1.1 tsutsui * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 53 1.1 tsutsui * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 54 1.1 tsutsui * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 55 1.1 tsutsui */ 56 1.1 tsutsui /* 57 1.1 tsutsui * Ported from 58 1.1 tsutsui * dc395x_trm.c 59 1.1 tsutsui * 60 1.1 tsutsui * Written for NetBSD 1.4.x by 61 1.1 tsutsui * Erich Chen (erich (at) tekram.com.tw) 62 1.1 tsutsui * 63 1.1 tsutsui * Provided by 64 1.1 tsutsui * (C)Copyright 1995-1999 Tekram Technology Co., Ltd. All rights reserved. 65 1.1 tsutsui */ 66 1.4 lukem 67 1.4 lukem #include <sys/cdefs.h> 68 1.44 andvar __KERNEL_RCSID(0, "$NetBSD: trm.c,v 1.44 2024/02/09 22:08:36 andvar Exp $"); 69 1.1 tsutsui 70 1.2 tsutsui /* #define TRM_DEBUG */ 71 1.7 tsutsui #ifdef TRM_DEBUG 72 1.7 tsutsui int trm_debug = 1; 73 1.7 tsutsui #define DPRINTF(arg) if (trm_debug > 0) printf arg; 74 1.7 tsutsui #else 75 1.7 tsutsui #define DPRINTF(arg) 76 1.7 tsutsui #endif 77 1.1 tsutsui 78 1.1 tsutsui #include <sys/param.h> 79 1.1 tsutsui #include <sys/systm.h> 80 1.1 tsutsui #include <sys/malloc.h> 81 1.1 tsutsui #include <sys/buf.h> 82 1.1 tsutsui #include <sys/kernel.h> 83 1.1 tsutsui #include <sys/device.h> 84 1.7 tsutsui #include <sys/queue.h> 85 1.1 tsutsui 86 1.27 ad #include <sys/bus.h> 87 1.27 ad #include <sys/intr.h> 88 1.1 tsutsui 89 1.17 thorpej #include <dev/scsipi/scsi_spc.h> 90 1.1 tsutsui #include <dev/scsipi/scsi_all.h> 91 1.1 tsutsui #include <dev/scsipi/scsi_message.h> 92 1.1 tsutsui #include <dev/scsipi/scsipi_all.h> 93 1.1 tsutsui #include <dev/scsipi/scsiconf.h> 94 1.1 tsutsui 95 1.1 tsutsui #include <dev/pci/pcidevs.h> 96 1.1 tsutsui #include <dev/pci/pcireg.h> 97 1.1 tsutsui #include <dev/pci/pcivar.h> 98 1.1 tsutsui #include <dev/pci/trmreg.h> 99 1.1 tsutsui 100 1.1 tsutsui /* 101 1.1 tsutsui * feature of chip set MAX value 102 1.1 tsutsui */ 103 1.1 tsutsui #define TRM_MAX_TARGETS 16 104 1.7 tsutsui #define TRM_MAX_LUNS 8 105 1.1 tsutsui #define TRM_MAX_SG_ENTRIES (MAXPHYS / PAGE_SIZE + 1) 106 1.7 tsutsui #define TRM_MAX_SRB 32 /* XXX */ 107 1.7 tsutsui #define TRM_MAX_TAG TRM_MAX_SRB /* XXX */ 108 1.7 tsutsui #define TRM_MAX_OFFSET 15 109 1.7 tsutsui #define TRM_MAX_PERIOD 125 110 1.1 tsutsui 111 1.1 tsutsui /* 112 1.1 tsutsui * Segment Entry 113 1.1 tsutsui */ 114 1.1 tsutsui struct trm_sg_entry { 115 1.16 tsutsui uint32_t address; 116 1.16 tsutsui uint32_t length; 117 1.1 tsutsui }; 118 1.1 tsutsui 119 1.1 tsutsui #define TRM_SG_SIZE (sizeof(struct trm_sg_entry) * TRM_MAX_SG_ENTRIES) 120 1.1 tsutsui 121 1.1 tsutsui /* 122 1.1 tsutsui ********************************************************************** 123 1.1 tsutsui * The SEEPROM structure for TRM_S1040 124 1.1 tsutsui ********************************************************************** 125 1.1 tsutsui */ 126 1.1 tsutsui struct nvram_target { 127 1.16 tsutsui uint8_t config0; /* Target configuration byte 0 */ 128 1.1 tsutsui #define NTC_DO_WIDE_NEGO 0x20 /* Wide negotiate */ 129 1.8 wiz #define NTC_DO_TAG_QUEUING 0x10 /* Enable SCSI tagged queuing */ 130 1.1 tsutsui #define NTC_DO_SEND_START 0x08 /* Send start command SPINUP */ 131 1.1 tsutsui #define NTC_DO_DISCONNECT 0x04 /* Enable SCSI disconnect */ 132 1.1 tsutsui #define NTC_DO_SYNC_NEGO 0x02 /* Sync negotiation */ 133 1.5 tsutsui #define NTC_DO_PARITY_CHK 0x01 /* Parity check enable */ 134 1.16 tsutsui uint8_t period; /* Target period */ 135 1.16 tsutsui uint8_t config2; /* Target configuration byte 2 */ 136 1.16 tsutsui uint8_t config3; /* Target configuration byte 3 */ 137 1.1 tsutsui }; 138 1.1 tsutsui 139 1.1 tsutsui struct trm_nvram { 140 1.16 tsutsui uint8_t subvendor_id[2]; /* 0,1 Sub Vendor ID */ 141 1.16 tsutsui uint8_t subsys_id[2]; /* 2,3 Sub System ID */ 142 1.16 tsutsui uint8_t subclass; /* 4 Sub Class */ 143 1.16 tsutsui uint8_t vendor_id[2]; /* 5,6 Vendor ID */ 144 1.16 tsutsui uint8_t device_id[2]; /* 7,8 Device ID */ 145 1.16 tsutsui uint8_t reserved0; /* 9 Reserved */ 146 1.1 tsutsui struct nvram_target target[TRM_MAX_TARGETS]; 147 1.1 tsutsui /* 10,11,12,13 148 1.1 tsutsui * 14,15,16,17 149 1.1 tsutsui * .... 150 1.1 tsutsui * 70,71,72,73 */ 151 1.16 tsutsui uint8_t scsi_id; /* 74 Host Adapter SCSI ID */ 152 1.16 tsutsui uint8_t channel_cfg; /* 75 Channel configuration */ 153 1.1 tsutsui #define NAC_SCANLUN 0x20 /* Include LUN as BIOS device */ 154 1.3 tsutsui #define NAC_DO_PARITY_CHK 0x08 /* Parity check enable */ 155 1.1 tsutsui #define NAC_POWERON_SCSI_RESET 0x04 /* Power on reset enable */ 156 1.1 tsutsui #define NAC_GREATER_1G 0x02 /* > 1G support enable */ 157 1.1 tsutsui #define NAC_GT2DRIVES 0x01 /* Support more than 2 drives */ 158 1.16 tsutsui uint8_t delay_time; /* 76 Power on delay time */ 159 1.16 tsutsui uint8_t max_tag; /* 77 Maximum tags */ 160 1.16 tsutsui uint8_t reserved1; /* 78 */ 161 1.16 tsutsui uint8_t boot_target; /* 79 */ 162 1.16 tsutsui uint8_t boot_lun; /* 80 */ 163 1.16 tsutsui uint8_t reserved2; /* 81 */ 164 1.16 tsutsui uint8_t reserved3[44]; /* 82,..125 */ 165 1.16 tsutsui uint8_t checksum0; /* 126 */ 166 1.16 tsutsui uint8_t checksum1; /* 127 */ 167 1.1 tsutsui #define TRM_NVRAM_CKSUM 0x1234 168 1.1 tsutsui }; 169 1.1 tsutsui 170 1.1 tsutsui /* Nvram Initiater bits definition */ 171 1.1 tsutsui #define MORE2_DRV 0x00000001 172 1.1 tsutsui #define GREATER_1G 0x00000002 173 1.1 tsutsui #define RST_SCSI_BUS 0x00000004 174 1.1 tsutsui #define ACTIVE_NEGATION 0x00000008 175 1.1 tsutsui #define NO_SEEK 0x00000010 176 1.1 tsutsui #define LUN_CHECK 0x00000020 177 1.1 tsutsui 178 1.7 tsutsui #define trm_eeprom_wait() DELAY(30) 179 1.1 tsutsui 180 1.1 tsutsui /* 181 1.1 tsutsui *----------------------------------------------------------------------- 182 1.1 tsutsui * SCSI Request Block 183 1.1 tsutsui *----------------------------------------------------------------------- 184 1.1 tsutsui */ 185 1.1 tsutsui struct trm_srb { 186 1.7 tsutsui TAILQ_ENTRY(trm_srb) next; 187 1.1 tsutsui 188 1.1 tsutsui struct trm_sg_entry *sgentry; 189 1.5 tsutsui struct scsipi_xfer *xs; /* scsipi_xfer for this cmd */ 190 1.1 tsutsui bus_dmamap_t dmap; 191 1.1 tsutsui bus_size_t sgoffset; /* Xfer buf offset */ 192 1.1 tsutsui 193 1.16 tsutsui uint32_t buflen; /* Total xfer length */ 194 1.16 tsutsui uint32_t sgaddr; /* SGList physical starting address */ 195 1.1 tsutsui 196 1.1 tsutsui int sgcnt; 197 1.1 tsutsui int sgindex; 198 1.1 tsutsui 199 1.1 tsutsui int hastat; /* Host Adapter Status */ 200 1.1 tsutsui #define H_STATUS_GOOD 0x00 201 1.1 tsutsui #define H_SEL_TIMEOUT 0x11 202 1.1 tsutsui #define H_OVER_UNDER_RUN 0x12 203 1.1 tsutsui #define H_UNEXP_BUS_FREE 0x13 204 1.1 tsutsui #define H_TARGET_PHASE_F 0x14 205 1.1 tsutsui #define H_INVALID_CCB_OP 0x16 206 1.1 tsutsui #define H_LINK_CCB_BAD 0x17 207 1.1 tsutsui #define H_BAD_TARGET_DIR 0x18 208 1.1 tsutsui #define H_DUPLICATE_CCB 0x19 209 1.1 tsutsui #define H_BAD_CCB_OR_SG 0x1A 210 1.1 tsutsui #define H_ABORT 0xFF 211 1.1 tsutsui int tastat; /* Target SCSI Status Byte */ 212 1.1 tsutsui int flag; /* SRBFlag */ 213 1.1 tsutsui #define AUTO_REQSENSE 0x0001 214 1.7 tsutsui #define PARITY_ERROR 0x0002 215 1.7 tsutsui #define SRB_TIMEOUT 0x0004 216 1.1 tsutsui 217 1.1 tsutsui int cmdlen; /* SCSI command length */ 218 1.16 tsutsui uint8_t cmd[12]; /* SCSI command */ 219 1.1 tsutsui 220 1.16 tsutsui uint8_t tag[2]; 221 1.1 tsutsui }; 222 1.1 tsutsui 223 1.1 tsutsui /* 224 1.7 tsutsui * some info about each target and lun on the SCSI bus 225 1.1 tsutsui */ 226 1.7 tsutsui struct trm_linfo { 227 1.7 tsutsui int used; /* number of slots in use */ 228 1.7 tsutsui int avail; /* where to start scanning */ 229 1.7 tsutsui int busy; /* lun in use */ 230 1.7 tsutsui struct trm_srb *untagged; 231 1.7 tsutsui struct trm_srb *queued[TRM_MAX_TAG]; 232 1.7 tsutsui }; 233 1.1 tsutsui 234 1.7 tsutsui struct trm_tinfo { 235 1.7 tsutsui u_int flag; /* Sync mode ? (1 sync):(0 async) */ 236 1.7 tsutsui #define SYNC_NEGO_ENABLE 0x0001 237 1.7 tsutsui #define SYNC_NEGO_DOING 0x0002 238 1.7 tsutsui #define SYNC_NEGO_DONE 0x0004 239 1.7 tsutsui #define WIDE_NEGO_ENABLE 0x0008 240 1.7 tsutsui #define WIDE_NEGO_DOING 0x0010 241 1.7 tsutsui #define WIDE_NEGO_DONE 0x0020 242 1.7 tsutsui #define USE_TAG_QUEUING 0x0040 243 1.7 tsutsui #define NO_RESELECT 0x0080 244 1.7 tsutsui struct trm_linfo *linfo[TRM_MAX_LUNS]; 245 1.1 tsutsui 246 1.16 tsutsui uint8_t config0; /* Target Config */ 247 1.16 tsutsui uint8_t period; /* Max Period for nego. */ 248 1.16 tsutsui uint8_t synctl; /* Sync control for reg. */ 249 1.16 tsutsui uint8_t offset; /* Sync offset for reg. and nego.(low nibble) */ 250 1.1 tsutsui }; 251 1.1 tsutsui 252 1.1 tsutsui /* 253 1.1 tsutsui *----------------------------------------------------------------------- 254 1.1 tsutsui * Adapter Control Block 255 1.1 tsutsui *----------------------------------------------------------------------- 256 1.1 tsutsui */ 257 1.1 tsutsui struct trm_softc { 258 1.29 tsutsui device_t sc_dev; 259 1.1 tsutsui 260 1.1 tsutsui bus_space_tag_t sc_iot; 261 1.1 tsutsui bus_space_handle_t sc_ioh; 262 1.1 tsutsui bus_dma_tag_t sc_dmat; 263 1.1 tsutsui bus_dmamap_t sc_dmamap; /* Map the control structures */ 264 1.1 tsutsui 265 1.7 tsutsui struct trm_srb *sc_actsrb; 266 1.7 tsutsui struct trm_tinfo sc_tinfo[TRM_MAX_TARGETS]; 267 1.1 tsutsui 268 1.7 tsutsui TAILQ_HEAD(, trm_srb) sc_freesrb, 269 1.7 tsutsui sc_readysrb; 270 1.1 tsutsui struct trm_srb *sc_srb; /* SRB array */ 271 1.1 tsutsui 272 1.1 tsutsui struct trm_sg_entry *sc_sglist; 273 1.1 tsutsui 274 1.7 tsutsui int sc_maxid; 275 1.1 tsutsui /* 276 1.1 tsutsui * Link to the generic SCSI driver 277 1.1 tsutsui */ 278 1.1 tsutsui struct scsipi_channel sc_channel; 279 1.1 tsutsui struct scsipi_adapter sc_adapter; 280 1.1 tsutsui 281 1.1 tsutsui int sc_id; /* Adapter SCSI Target ID */ 282 1.1 tsutsui 283 1.7 tsutsui int sc_state; /* SRB State */ 284 1.7 tsutsui #define TRM_IDLE 0 285 1.7 tsutsui #define TRM_WAIT 1 286 1.7 tsutsui #define TRM_READY 2 287 1.7 tsutsui #define TRM_MSGOUT 3 /* arbitration+msg_out 1st byte */ 288 1.7 tsutsui #define TRM_MSGIN 4 289 1.7 tsutsui #define TRM_EXTEND_MSGIN 5 290 1.7 tsutsui #define TRM_COMMAND 6 291 1.7 tsutsui #define TRM_START 7 /* arbitration+msg_out+command_out */ 292 1.7 tsutsui #define TRM_DISCONNECTED 8 293 1.7 tsutsui #define TRM_DATA_XFER 9 294 1.7 tsutsui #define TRM_XFERPAD 10 295 1.7 tsutsui #define TRM_STATUS 11 296 1.7 tsutsui #define TRM_COMPLETED 12 297 1.7 tsutsui #define TRM_ABORT_SENT 13 298 1.7 tsutsui #define TRM_UNEXPECT_RESEL 14 299 1.1 tsutsui 300 1.7 tsutsui int sc_phase; /* SCSI phase */ 301 1.7 tsutsui int sc_config; 302 1.7 tsutsui #define HCC_WIDE_CARD 0x01 303 1.7 tsutsui #define HCC_SCSI_RESET 0x02 304 1.7 tsutsui #define HCC_PARITY 0x04 305 1.7 tsutsui #define HCC_AUTOTERM 0x08 306 1.7 tsutsui #define HCC_LOW8TERM 0x10 307 1.7 tsutsui #define HCC_UP8TERM 0x20 308 1.1 tsutsui 309 1.1 tsutsui int sc_flag; 310 1.1 tsutsui #define RESET_DEV 0x01 311 1.1 tsutsui #define RESET_DETECT 0x02 312 1.1 tsutsui #define RESET_DONE 0x04 313 1.7 tsutsui #define WAIT_TAGMSG 0x08 /* XXX */ 314 1.7 tsutsui 315 1.7 tsutsui int sc_msgcnt; 316 1.7 tsutsui 317 1.7 tsutsui int resel_target; /* XXX */ 318 1.7 tsutsui int resel_lun; /* XXX */ 319 1.7 tsutsui 320 1.16 tsutsui uint8_t *sc_msg; 321 1.16 tsutsui uint8_t sc_msgbuf[6]; 322 1.1 tsutsui }; 323 1.1 tsutsui 324 1.1 tsutsui /* 325 1.1 tsutsui * SCSI Status codes not defined in scsi_all.h 326 1.1 tsutsui */ 327 1.1 tsutsui #define SCSI_COND_MET 0x04 /* Condition Met */ 328 1.1 tsutsui #define SCSI_INTERM_COND_MET 0x14 /* Intermediate condition met */ 329 1.8 wiz #define SCSI_UNEXP_BUS_FREE 0xFD /* Unexpected Bus Free */ 330 1.8 wiz #define SCSI_BUS_RST_DETECT 0xFE /* SCSI Bus Reset detected */ 331 1.8 wiz #define SCSI_SEL_TIMEOUT 0xFF /* Selection Timeout */ 332 1.1 tsutsui 333 1.29 tsutsui static int trm_match(device_t, cfdata_t, void *); 334 1.29 tsutsui static void trm_attach(device_t, device_t, void *); 335 1.7 tsutsui 336 1.7 tsutsui static int trm_init(struct trm_softc *); 337 1.7 tsutsui 338 1.7 tsutsui static void trm_scsipi_request(struct scsipi_channel *, scsipi_adapter_req_t, 339 1.7 tsutsui void *); 340 1.7 tsutsui static void trm_update_xfer_mode(struct trm_softc *, int); 341 1.7 tsutsui static void trm_sched(struct trm_softc *); 342 1.7 tsutsui static int trm_select(struct trm_softc *, struct trm_srb *); 343 1.7 tsutsui static void trm_reset(struct trm_softc *); 344 1.7 tsutsui static void trm_timeout(void *); 345 1.1 tsutsui static int trm_intr(void *); 346 1.1 tsutsui 347 1.7 tsutsui static void trm_dataout_phase0(struct trm_softc *, int); 348 1.7 tsutsui static void trm_datain_phase0(struct trm_softc *, int); 349 1.7 tsutsui static void trm_status_phase0(struct trm_softc *); 350 1.7 tsutsui static void trm_msgin_phase0(struct trm_softc *); 351 1.7 tsutsui static void trm_command_phase1(struct trm_softc *); 352 1.7 tsutsui static void trm_status_phase1(struct trm_softc *); 353 1.7 tsutsui static void trm_msgout_phase1(struct trm_softc *); 354 1.7 tsutsui static void trm_msgin_phase1(struct trm_softc *); 355 1.7 tsutsui 356 1.7 tsutsui static void trm_dataio_xfer(struct trm_softc *, int); 357 1.1 tsutsui static void trm_disconnect(struct trm_softc *); 358 1.1 tsutsui static void trm_reselect(struct trm_softc *); 359 1.7 tsutsui static void trm_done(struct trm_softc *, struct trm_srb *); 360 1.7 tsutsui static int trm_request_sense(struct trm_softc *, struct trm_srb *); 361 1.7 tsutsui static void trm_dequeue(struct trm_softc *, struct trm_srb *); 362 1.7 tsutsui 363 1.1 tsutsui static void trm_scsi_reset_detect(struct trm_softc *); 364 1.1 tsutsui static void trm_reset_scsi_bus(struct trm_softc *); 365 1.7 tsutsui 366 1.1 tsutsui static void trm_check_eeprom(struct trm_softc *, struct trm_nvram *); 367 1.1 tsutsui static void trm_eeprom_read_all(struct trm_softc *, struct trm_nvram *); 368 1.1 tsutsui static void trm_eeprom_write_all(struct trm_softc *, struct trm_nvram *); 369 1.16 tsutsui static void trm_eeprom_set_data(struct trm_softc *, uint8_t, uint8_t); 370 1.16 tsutsui static void trm_eeprom_write_cmd(struct trm_softc *, uint8_t, uint8_t); 371 1.16 tsutsui static uint8_t trm_eeprom_get_data(struct trm_softc *, uint8_t); 372 1.1 tsutsui 373 1.29 tsutsui CFATTACH_DECL_NEW(trm, sizeof(struct trm_softc), 374 1.29 tsutsui trm_match, trm_attach, NULL, NULL); 375 1.1 tsutsui 376 1.7 tsutsui /* real period: */ 377 1.16 tsutsui static const uint8_t trm_clock_period[] = { 378 1.7 tsutsui 12, /* 48 ns 20.0 MB/sec */ 379 1.7 tsutsui 18, /* 72 ns 13.3 MB/sec */ 380 1.7 tsutsui 25, /* 100 ns 10.0 MB/sec */ 381 1.7 tsutsui 31, /* 124 ns 8.0 MB/sec */ 382 1.7 tsutsui 37, /* 148 ns 6.6 MB/sec */ 383 1.7 tsutsui 43, /* 172 ns 5.7 MB/sec */ 384 1.7 tsutsui 50, /* 200 ns 5.0 MB/sec */ 385 1.7 tsutsui 62 /* 248 ns 4.0 MB/sec */ 386 1.1 tsutsui }; 387 1.29 tsutsui #define NPERIOD __arraycount(trm_clock_period) 388 1.1 tsutsui 389 1.7 tsutsui static int 390 1.29 tsutsui trm_match(device_t parent, cfdata_t cf, void *aux) 391 1.7 tsutsui { 392 1.7 tsutsui struct pci_attach_args *pa = aux; 393 1.1 tsutsui 394 1.7 tsutsui if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_TEKRAM2) 395 1.7 tsutsui switch (PCI_PRODUCT(pa->pa_id)) { 396 1.7 tsutsui case PCI_PRODUCT_TEKRAM2_DC315: 397 1.29 tsutsui return 1; 398 1.7 tsutsui } 399 1.29 tsutsui return 0; 400 1.7 tsutsui } 401 1.1 tsutsui 402 1.1 tsutsui /* 403 1.7 tsutsui * attach and init a host adapter 404 1.1 tsutsui */ 405 1.1 tsutsui static void 406 1.29 tsutsui trm_attach(device_t parent, device_t self, void *aux) 407 1.1 tsutsui { 408 1.29 tsutsui struct trm_softc *sc = device_private(self); 409 1.7 tsutsui struct pci_attach_args *const pa = aux; 410 1.7 tsutsui bus_space_tag_t iot; 411 1.7 tsutsui bus_space_handle_t ioh; 412 1.7 tsutsui pci_intr_handle_t ih; 413 1.7 tsutsui pcireg_t command; 414 1.7 tsutsui const char *intrstr; 415 1.38 macallan int fl = -1; 416 1.36 christos char intrbuf[PCI_INTRSTR_LEN]; 417 1.7 tsutsui 418 1.29 tsutsui sc->sc_dev = self; 419 1.29 tsutsui 420 1.7 tsutsui /* 421 1.33 macallan * Some cards do not allow memory mapped accesses 422 1.7 tsutsui * pa_pc: chipset tag 423 1.7 tsutsui * pa_tag: pci tag 424 1.7 tsutsui */ 425 1.7 tsutsui command = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG); 426 1.7 tsutsui if ((command & (PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MASTER_ENABLE)) != 427 1.7 tsutsui (PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MASTER_ENABLE)) { 428 1.7 tsutsui command |= PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MASTER_ENABLE; 429 1.7 tsutsui pci_conf_write(pa->pa_pc, pa->pa_tag, 430 1.7 tsutsui PCI_COMMAND_STATUS_REG, command); 431 1.7 tsutsui } 432 1.7 tsutsui /* 433 1.7 tsutsui * mask for get correct base address of pci IO port 434 1.7 tsutsui */ 435 1.33 macallan if (command & PCI_COMMAND_MEM_ENABLE) { 436 1.33 macallan fl = pci_mapreg_map(pa, TRM_BAR_MMIO, PCI_MAPREG_TYPE_MEM, 0, &iot, 437 1.33 macallan &ioh, NULL, NULL); 438 1.33 macallan } 439 1.33 macallan if (fl != 0) { 440 1.39 macallan aprint_verbose_dev(self, "couldn't map MMIO registers, trying PIO\n"); 441 1.37 msaitoh if ((fl = pci_mapreg_map(pa, TRM_BAR_PIO, PCI_MAPREG_TYPE_IO, 442 1.37 msaitoh 0, &iot, &ioh, NULL, NULL)) != 0) { 443 1.33 macallan aprint_error(": unable to map registers (%d)\n", fl); 444 1.33 macallan return; 445 1.33 macallan } 446 1.7 tsutsui } 447 1.7 tsutsui /* 448 1.7 tsutsui * test checksum of eeprom.. & initialize softc... 449 1.7 tsutsui */ 450 1.7 tsutsui sc->sc_iot = iot; 451 1.7 tsutsui sc->sc_ioh = ioh; 452 1.7 tsutsui sc->sc_dmat = pa->pa_dmat; 453 1.1 tsutsui 454 1.7 tsutsui if (trm_init(sc) != 0) { 455 1.7 tsutsui /* 456 1.7 tsutsui * Error during initialization! 457 1.7 tsutsui */ 458 1.7 tsutsui return; 459 1.7 tsutsui } 460 1.7 tsutsui /* 461 1.7 tsutsui * Now try to attach all the sub-devices 462 1.7 tsutsui */ 463 1.7 tsutsui if ((sc->sc_config & HCC_WIDE_CARD) != 0) 464 1.29 tsutsui aprint_normal(": Tekram DC395UW/F (TRM-S1040) Fast40 " 465 1.7 tsutsui "Ultra Wide SCSI Adapter\n"); 466 1.7 tsutsui else 467 1.29 tsutsui aprint_normal(": Tekram DC395U, DC315/U (TRM-S1040) Fast20 " 468 1.7 tsutsui "Ultra SCSI Adapter\n"); 469 1.1 tsutsui 470 1.7 tsutsui /* 471 1.7 tsutsui * Now tell the generic SCSI layer about our bus. 472 1.7 tsutsui * map and establish interrupt 473 1.7 tsutsui */ 474 1.7 tsutsui if (pci_intr_map(pa, &ih)) { 475 1.29 tsutsui aprint_error_dev(self, "couldn't map interrupt\n"); 476 1.7 tsutsui return; 477 1.7 tsutsui } 478 1.36 christos intrstr = pci_intr_string(pa->pa_pc, ih, intrbuf, sizeof(intrbuf)); 479 1.1 tsutsui 480 1.40 jdolecek if (pci_intr_establish_xname(pa->pa_pc, ih, IPL_BIO, trm_intr, sc, 481 1.40 jdolecek device_xname(self)) == NULL) { 482 1.29 tsutsui aprint_error_dev(self, "couldn't establish interrupt"); 483 1.7 tsutsui if (intrstr != NULL) 484 1.29 tsutsui aprint_error(" at %s", intrstr); 485 1.29 tsutsui aprint_error("\n"); 486 1.7 tsutsui return; 487 1.1 tsutsui } 488 1.7 tsutsui if (intrstr != NULL) 489 1.29 tsutsui aprint_normal_dev(self, "interrupting at %s\n", intrstr); 490 1.7 tsutsui 491 1.29 tsutsui sc->sc_adapter.adapt_dev = self; 492 1.7 tsutsui sc->sc_adapter.adapt_nchannels = 1; 493 1.7 tsutsui sc->sc_adapter.adapt_openings = TRM_MAX_SRB; 494 1.7 tsutsui sc->sc_adapter.adapt_max_periph = TRM_MAX_SRB; 495 1.7 tsutsui sc->sc_adapter.adapt_request = trm_scsipi_request; 496 1.7 tsutsui sc->sc_adapter.adapt_minphys = minphys; 497 1.7 tsutsui 498 1.7 tsutsui sc->sc_channel.chan_adapter = &sc->sc_adapter; 499 1.7 tsutsui sc->sc_channel.chan_bustype = &scsi_bustype; 500 1.7 tsutsui sc->sc_channel.chan_channel = 0; 501 1.7 tsutsui sc->sc_channel.chan_ntargets = sc->sc_maxid + 1; 502 1.7 tsutsui sc->sc_channel.chan_nluns = 8; 503 1.7 tsutsui sc->sc_channel.chan_id = sc->sc_id; 504 1.1 tsutsui 505 1.43 thorpej config_found(self, &sc->sc_channel, scsiprint, CFARGS_NONE); 506 1.1 tsutsui } 507 1.1 tsutsui 508 1.7 tsutsui /* 509 1.7 tsutsui * initialize the internal structures for a given SCSI host 510 1.7 tsutsui */ 511 1.7 tsutsui static int 512 1.15 tsutsui trm_init(struct trm_softc *sc) 513 1.1 tsutsui { 514 1.7 tsutsui bus_space_tag_t iot = sc->sc_iot; 515 1.7 tsutsui bus_space_handle_t ioh = sc->sc_ioh; 516 1.7 tsutsui bus_dma_segment_t seg; 517 1.7 tsutsui struct trm_nvram eeprom; 518 1.1 tsutsui struct trm_srb *srb; 519 1.7 tsutsui struct trm_tinfo *ti; 520 1.7 tsutsui struct nvram_target *tconf; 521 1.7 tsutsui int error, rseg, all_sgsize; 522 1.7 tsutsui int i, target; 523 1.16 tsutsui uint8_t bval; 524 1.7 tsutsui 525 1.7 tsutsui DPRINTF(("\n")); 526 1.1 tsutsui 527 1.7 tsutsui /* 528 1.7 tsutsui * allocate the space for all SCSI control blocks (SRB) for DMA memory 529 1.7 tsutsui */ 530 1.7 tsutsui all_sgsize = TRM_MAX_SRB * TRM_SG_SIZE; 531 1.7 tsutsui if ((error = bus_dmamem_alloc(sc->sc_dmat, all_sgsize, PAGE_SIZE, 532 1.7 tsutsui 0, &seg, 1, &rseg, BUS_DMA_NOWAIT)) != 0) { 533 1.29 tsutsui aprint_error(": unable to allocate SCSI REQUEST BLOCKS, " 534 1.7 tsutsui "error = %d\n", error); 535 1.29 tsutsui return 1; 536 1.7 tsutsui } 537 1.7 tsutsui if ((error = bus_dmamem_map(sc->sc_dmat, &seg, rseg, 538 1.26 christos all_sgsize, (void **) &sc->sc_sglist, 539 1.7 tsutsui BUS_DMA_NOWAIT | BUS_DMA_COHERENT)) != 0) { 540 1.29 tsutsui aprint_error(": unable to map SCSI REQUEST BLOCKS, " 541 1.7 tsutsui "error = %d\n", error); 542 1.29 tsutsui return 1; 543 1.7 tsutsui } 544 1.7 tsutsui if ((error = bus_dmamap_create(sc->sc_dmat, all_sgsize, 1, 545 1.7 tsutsui all_sgsize, 0, BUS_DMA_NOWAIT, &sc->sc_dmamap)) != 0) { 546 1.29 tsutsui aprint_error(": unable to create SRB DMA maps, " 547 1.7 tsutsui "error = %d\n", error); 548 1.29 tsutsui return 1; 549 1.7 tsutsui } 550 1.7 tsutsui if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_dmamap, 551 1.7 tsutsui sc->sc_sglist, all_sgsize, NULL, BUS_DMA_NOWAIT)) != 0) { 552 1.29 tsutsui aprint_error(": unable to load SRB DMA maps, " 553 1.7 tsutsui "error = %d\n", error); 554 1.29 tsutsui return 1; 555 1.7 tsutsui } 556 1.7 tsutsui DPRINTF(("all_sgsize=%x\n", all_sgsize)); 557 1.7 tsutsui memset(sc->sc_sglist, 0, all_sgsize); 558 1.1 tsutsui 559 1.7 tsutsui /* 560 1.7 tsutsui * EEPROM CHECKSUM 561 1.7 tsutsui */ 562 1.7 tsutsui trm_check_eeprom(sc, &eeprom); 563 1.1 tsutsui 564 1.7 tsutsui sc->sc_maxid = 7; 565 1.7 tsutsui sc->sc_config = HCC_AUTOTERM | HCC_PARITY; 566 1.7 tsutsui if (bus_space_read_1(iot, ioh, TRM_GEN_STATUS) & WIDESCSI) { 567 1.7 tsutsui sc->sc_config |= HCC_WIDE_CARD; 568 1.7 tsutsui sc->sc_maxid = 15; 569 1.1 tsutsui } 570 1.7 tsutsui if (eeprom.channel_cfg & NAC_POWERON_SCSI_RESET) 571 1.7 tsutsui sc->sc_config |= HCC_SCSI_RESET; 572 1.1 tsutsui 573 1.7 tsutsui sc->sc_actsrb = NULL; 574 1.7 tsutsui sc->sc_id = eeprom.scsi_id; 575 1.7 tsutsui sc->sc_flag = 0; 576 1.1 tsutsui 577 1.1 tsutsui /* 578 1.8 wiz * initialize and link all device's SRB queues of this adapter 579 1.1 tsutsui */ 580 1.7 tsutsui TAILQ_INIT(&sc->sc_freesrb); 581 1.7 tsutsui TAILQ_INIT(&sc->sc_readysrb); 582 1.1 tsutsui 583 1.7 tsutsui sc->sc_srb = malloc(sizeof(struct trm_srb) * TRM_MAX_SRB, 584 1.41 chs M_DEVBUF, M_WAITOK | M_ZERO); 585 1.31 jakllsch DPRINTF(("all SRB size=%zx\n", sizeof(struct trm_srb) * TRM_MAX_SRB)); 586 1.7 tsutsui 587 1.7 tsutsui for (i = 0, srb = sc->sc_srb; i < TRM_MAX_SRB; i++) { 588 1.7 tsutsui srb->sgentry = sc->sc_sglist + TRM_MAX_SG_ENTRIES * i; 589 1.7 tsutsui srb->sgoffset = TRM_SG_SIZE * i; 590 1.7 tsutsui srb->sgaddr = sc->sc_dmamap->dm_segs[0].ds_addr + srb->sgoffset; 591 1.1 tsutsui /* 592 1.7 tsutsui * map all SRB space to SRB_array 593 1.1 tsutsui */ 594 1.7 tsutsui if (bus_dmamap_create(sc->sc_dmat, 595 1.7 tsutsui MAXPHYS, TRM_MAX_SG_ENTRIES, MAXPHYS, 0, 596 1.7 tsutsui BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &srb->dmap)) { 597 1.29 tsutsui aprint_error(": unable to create DMA transfer map.\n"); 598 1.7 tsutsui free(sc->sc_srb, M_DEVBUF); 599 1.29 tsutsui return 1; 600 1.1 tsutsui } 601 1.7 tsutsui TAILQ_INSERT_TAIL(&sc->sc_freesrb, srb, next); 602 1.7 tsutsui srb++; 603 1.7 tsutsui } 604 1.7 tsutsui 605 1.7 tsutsui /* 606 1.8 wiz * initialize all target info structures 607 1.7 tsutsui */ 608 1.7 tsutsui for (target = 0; target < TRM_MAX_TARGETS; target++) { 609 1.7 tsutsui ti = &sc->sc_tinfo[target]; 610 1.7 tsutsui ti->synctl = 0; 611 1.7 tsutsui ti->offset = 0; 612 1.7 tsutsui tconf = &eeprom.target[target]; 613 1.7 tsutsui ti->config0 = tconf->config0; 614 1.7 tsutsui ti->period = trm_clock_period[tconf->period & 0x07]; 615 1.7 tsutsui ti->flag = 0; 616 1.7 tsutsui if ((ti->config0 & NTC_DO_DISCONNECT) != 0) { 617 1.7 tsutsui #ifdef notyet 618 1.7 tsutsui if ((ti->config0 & NTC_DO_TAG_QUEUING) != 0) 619 1.7 tsutsui ti->flag |= USE_TAG_QUEUING; 620 1.7 tsutsui #endif 621 1.7 tsutsui } else 622 1.7 tsutsui ti->flag |= NO_RESELECT; 623 1.7 tsutsui 624 1.7 tsutsui DPRINTF(("target %d: config0 = 0x%02x, period = 0x%02x", 625 1.7 tsutsui target, ti->config0, ti->period)); 626 1.7 tsutsui DPRINTF((", flag = 0x%02x\n", ti->flag)); 627 1.1 tsutsui } 628 1.1 tsutsui 629 1.7 tsutsui /* program configuration 0 */ 630 1.7 tsutsui bval = PHASELATCH | INITIATOR | BLOCKRST; 631 1.7 tsutsui if ((sc->sc_config & HCC_PARITY) != 0) 632 1.7 tsutsui bval |= PARITYCHECK; 633 1.7 tsutsui bus_space_write_1(iot, ioh, TRM_SCSI_CONFIG0, bval); 634 1.7 tsutsui 635 1.7 tsutsui /* program configuration 1 */ 636 1.7 tsutsui bus_space_write_1(iot, ioh, TRM_SCSI_CONFIG1, 637 1.7 tsutsui ACTIVE_NEG | ACTIVE_NEGPLUS); 638 1.7 tsutsui 639 1.7 tsutsui /* 250ms selection timeout */ 640 1.7 tsutsui bus_space_write_1(iot, ioh, TRM_SCSI_TIMEOUT, SEL_TIMEOUT); 641 1.7 tsutsui 642 1.8 wiz /* Mask all interrupts */ 643 1.7 tsutsui bus_space_write_1(iot, ioh, TRM_DMA_INTEN, 0); 644 1.7 tsutsui bus_space_write_1(iot, ioh, TRM_SCSI_INTEN, 0); 645 1.7 tsutsui 646 1.7 tsutsui /* Reset SCSI module */ 647 1.7 tsutsui bus_space_write_2(iot, ioh, TRM_SCSI_CONTROL, DO_RSTMODULE); 648 1.7 tsutsui 649 1.7 tsutsui /* program Host ID */ 650 1.7 tsutsui bus_space_write_1(iot, ioh, TRM_SCSI_HOSTID, sc->sc_id); 651 1.7 tsutsui 652 1.8 wiz /* set asynchronous transfer */ 653 1.7 tsutsui bus_space_write_1(iot, ioh, TRM_SCSI_OFFSET, 0); 654 1.7 tsutsui 655 1.8 wiz /* Turn LED control off */ 656 1.7 tsutsui bus_space_write_2(iot, ioh, TRM_GEN_CONTROL, 657 1.7 tsutsui bus_space_read_2(iot, ioh, TRM_GEN_CONTROL) & ~EN_LED); 658 1.7 tsutsui 659 1.7 tsutsui /* DMA config */ 660 1.7 tsutsui bus_space_write_2(iot, ioh, TRM_DMA_CONFIG, 661 1.7 tsutsui bus_space_read_2(iot, ioh, TRM_DMA_CONFIG) | DMA_ENHANCE); 662 1.7 tsutsui 663 1.7 tsutsui /* Clear pending interrupt status */ 664 1.23 christos (void)bus_space_read_1(iot, ioh, TRM_SCSI_INTSTATUS); 665 1.7 tsutsui 666 1.7 tsutsui /* Enable SCSI interrupt */ 667 1.7 tsutsui bus_space_write_1(iot, ioh, TRM_SCSI_INTEN, 668 1.7 tsutsui EN_SELECT | EN_SELTIMEOUT | EN_DISCONNECT | EN_RESELECTED | 669 1.7 tsutsui EN_SCSIRESET | EN_BUSSERVICE | EN_CMDDONE); 670 1.7 tsutsui bus_space_write_1(iot, ioh, TRM_DMA_INTEN, EN_SCSIINTR); 671 1.7 tsutsui 672 1.7 tsutsui trm_reset(sc); 673 1.7 tsutsui 674 1.29 tsutsui return 0; 675 1.7 tsutsui } 676 1.1 tsutsui 677 1.1 tsutsui /* 678 1.1 tsutsui * enqueues a SCSI command 679 1.7 tsutsui * called by the higher level SCSI driver 680 1.1 tsutsui */ 681 1.7 tsutsui static void 682 1.15 tsutsui trm_scsipi_request(struct scsipi_channel *chan, scsipi_adapter_req_t req, 683 1.15 tsutsui void *arg) 684 1.1 tsutsui { 685 1.1 tsutsui bus_space_tag_t iot; 686 1.1 tsutsui bus_space_handle_t ioh; 687 1.1 tsutsui struct trm_softc *sc; 688 1.1 tsutsui struct trm_srb *srb; 689 1.1 tsutsui struct scsipi_xfer *xs; 690 1.34 martin int error, i, s; 691 1.1 tsutsui 692 1.29 tsutsui sc = device_private(chan->chan_adapter->adapt_dev); 693 1.1 tsutsui iot = sc->sc_iot; 694 1.1 tsutsui ioh = sc->sc_ioh; 695 1.1 tsutsui 696 1.1 tsutsui switch (req) { 697 1.1 tsutsui case ADAPTER_REQ_RUN_XFER: 698 1.1 tsutsui xs = arg; 699 1.7 tsutsui DPRINTF(("trm_scsipi_request.....\n")); 700 1.34 martin DPRINTF(("target= %d lun= %d\n", xs->xs_periph->periph_target, 701 1.34 martin xs->xs_periph->periph_lun)); 702 1.1 tsutsui if (xs->xs_control & XS_CTL_RESET) { 703 1.1 tsutsui trm_reset(sc); 704 1.35 bouyer xs->error = XS_RESET; 705 1.1 tsutsui return; 706 1.1 tsutsui } 707 1.1 tsutsui if (xs->xs_status & XS_STS_DONE) { 708 1.29 tsutsui printf("%s: Is it done?\n", device_xname(sc->sc_dev)); 709 1.1 tsutsui xs->xs_status &= ~XS_STS_DONE; 710 1.1 tsutsui } 711 1.1 tsutsui 712 1.1 tsutsui s = splbio(); 713 1.1 tsutsui 714 1.1 tsutsui /* Get SRB */ 715 1.7 tsutsui srb = TAILQ_FIRST(&sc->sc_freesrb); 716 1.1 tsutsui if (srb != NULL) { 717 1.7 tsutsui TAILQ_REMOVE(&sc->sc_freesrb, srb, next); 718 1.1 tsutsui } else { 719 1.1 tsutsui xs->error = XS_RESOURCE_SHORTAGE; 720 1.1 tsutsui scsipi_done(xs); 721 1.1 tsutsui splx(s); 722 1.1 tsutsui return; 723 1.1 tsutsui } 724 1.7 tsutsui 725 1.1 tsutsui srb->xs = xs; 726 1.1 tsutsui srb->cmdlen = xs->cmdlen; 727 1.1 tsutsui memcpy(srb->cmd, xs->cmd, xs->cmdlen); 728 1.7 tsutsui 729 1.5 tsutsui if (xs->xs_control & (XS_CTL_DATA_IN | XS_CTL_DATA_OUT)) { 730 1.1 tsutsui if ((error = bus_dmamap_load(sc->sc_dmat, srb->dmap, 731 1.1 tsutsui xs->data, xs->datalen, NULL, 732 1.5 tsutsui ((xs->xs_control & XS_CTL_NOSLEEP) ? 733 1.5 tsutsui BUS_DMA_NOWAIT : BUS_DMA_WAITOK) | 734 1.5 tsutsui BUS_DMA_STREAMING | 735 1.5 tsutsui ((xs->xs_control & XS_CTL_DATA_IN) ? 736 1.5 tsutsui BUS_DMA_READ : BUS_DMA_WRITE))) != 0) { 737 1.29 tsutsui printf("%s: DMA transfer map unable to load, " 738 1.29 tsutsui "error = %d\n", device_xname(sc->sc_dev), 739 1.29 tsutsui error); 740 1.1 tsutsui xs->error = XS_DRIVER_STUFFUP; 741 1.1 tsutsui /* 742 1.1 tsutsui * free SRB 743 1.1 tsutsui */ 744 1.7 tsutsui TAILQ_INSERT_TAIL(&sc->sc_freesrb, srb, next); 745 1.3 tsutsui splx(s); 746 1.1 tsutsui return; 747 1.1 tsutsui } 748 1.1 tsutsui bus_dmamap_sync(sc->sc_dmat, srb->dmap, 0, 749 1.1 tsutsui srb->dmap->dm_mapsize, 750 1.1 tsutsui (xs->xs_control & XS_CTL_DATA_IN) ? 751 1.1 tsutsui BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE); 752 1.1 tsutsui 753 1.1 tsutsui /* Set up the scatter gather list */ 754 1.1 tsutsui for (i = 0; i < srb->dmap->dm_nsegs; i++) { 755 1.1 tsutsui srb->sgentry[i].address = 756 1.1 tsutsui htole32(srb->dmap->dm_segs[i].ds_addr); 757 1.1 tsutsui srb->sgentry[i].length = 758 1.1 tsutsui htole32(srb->dmap->dm_segs[i].ds_len); 759 1.1 tsutsui } 760 1.1 tsutsui srb->buflen = xs->datalen; 761 1.1 tsutsui srb->sgcnt = srb->dmap->dm_nsegs; 762 1.1 tsutsui } else { 763 1.1 tsutsui srb->sgentry[0].address = 0; 764 1.1 tsutsui srb->sgentry[0].length = 0; 765 1.1 tsutsui srb->buflen = 0; 766 1.1 tsutsui srb->sgcnt = 0; 767 1.1 tsutsui } 768 1.1 tsutsui bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap, 769 1.1 tsutsui srb->sgoffset, TRM_SG_SIZE, BUS_DMASYNC_PREWRITE); 770 1.1 tsutsui 771 1.7 tsutsui sc->sc_phase = PH_BUS_FREE; /* SCSI bus free Phase */ 772 1.7 tsutsui 773 1.1 tsutsui srb->sgindex = 0; 774 1.1 tsutsui srb->hastat = 0; 775 1.1 tsutsui srb->tastat = 0; 776 1.1 tsutsui srb->flag = 0; 777 1.1 tsutsui 778 1.7 tsutsui TAILQ_INSERT_TAIL(&sc->sc_readysrb, srb, next); 779 1.7 tsutsui if (sc->sc_actsrb == NULL) 780 1.7 tsutsui trm_sched(sc); 781 1.1 tsutsui splx(s); 782 1.1 tsutsui 783 1.7 tsutsui if ((xs->xs_control & XS_CTL_POLL) != 0) { 784 1.1 tsutsui int timeout = xs->timeout; 785 1.7 tsutsui 786 1.1 tsutsui s = splbio(); 787 1.1 tsutsui do { 788 1.7 tsutsui while (--timeout) { 789 1.1 tsutsui DELAY(1000); 790 1.1 tsutsui if (bus_space_read_2(iot, ioh, 791 1.1 tsutsui TRM_SCSI_STATUS) & SCSIINTERRUPT) 792 1.1 tsutsui break; 793 1.1 tsutsui } 794 1.7 tsutsui if (timeout == 0) { 795 1.1 tsutsui trm_timeout(srb); 796 1.1 tsutsui break; 797 1.1 tsutsui } else 798 1.1 tsutsui trm_intr(sc); 799 1.1 tsutsui } while ((xs->xs_status & XS_STS_DONE) == 0); 800 1.1 tsutsui splx(s); 801 1.1 tsutsui } 802 1.1 tsutsui return; 803 1.1 tsutsui 804 1.1 tsutsui case ADAPTER_REQ_GROW_RESOURCES: 805 1.1 tsutsui /* XXX Not supported. */ 806 1.1 tsutsui return; 807 1.1 tsutsui 808 1.1 tsutsui case ADAPTER_REQ_SET_XFER_MODE: 809 1.7 tsutsui { 810 1.7 tsutsui struct trm_tinfo *ti; 811 1.7 tsutsui struct scsipi_xfer_mode *xm; 812 1.7 tsutsui 813 1.7 tsutsui xm = arg; 814 1.7 tsutsui ti = &sc->sc_tinfo[xm->xm_target]; 815 1.7 tsutsui ti->flag &= ~(SYNC_NEGO_ENABLE|WIDE_NEGO_ENABLE); 816 1.7 tsutsui 817 1.7 tsutsui #ifdef notyet 818 1.7 tsutsui if ((xm->xm_mode & PERIPH_CAP_TQING) != 0) 819 1.7 tsutsui ti->flag |= USE_TAG_QUEUING; 820 1.7 tsutsui else 821 1.7 tsutsui #endif 822 1.7 tsutsui ti->flag &= ~USE_TAG_QUEUING; 823 1.7 tsutsui 824 1.19 bouyer if ((xm->xm_mode & PERIPH_CAP_WIDE16) != 0 && 825 1.19 bouyer (sc->sc_config & HCC_WIDE_CARD) != 0 && 826 1.19 bouyer (ti->config0 & NTC_DO_WIDE_NEGO) != 0) { 827 1.7 tsutsui ti->flag |= WIDE_NEGO_ENABLE; 828 1.7 tsutsui ti->flag &= ~WIDE_NEGO_DONE; 829 1.7 tsutsui } 830 1.7 tsutsui 831 1.19 bouyer if ((xm->xm_mode & PERIPH_CAP_SYNC) != 0 && 832 1.19 bouyer (ti->config0 & NTC_DO_SYNC_NEGO) != 0) { 833 1.7 tsutsui ti->flag |= SYNC_NEGO_ENABLE; 834 1.7 tsutsui ti->flag &= ~SYNC_NEGO_DONE; 835 1.7 tsutsui ti->period = trm_clock_period[0]; 836 1.7 tsutsui } 837 1.7 tsutsui 838 1.7 tsutsui /* 839 1.7 tsutsui * If we're not going to negotiate, send the 840 1.7 tsutsui * notification now, since it won't happen later. 841 1.7 tsutsui */ 842 1.7 tsutsui if ((ti->flag & (WIDE_NEGO_DONE|SYNC_NEGO_DONE)) == 843 1.7 tsutsui (WIDE_NEGO_DONE|SYNC_NEGO_DONE)) 844 1.7 tsutsui trm_update_xfer_mode(sc, xm->xm_target); 845 1.7 tsutsui 846 1.7 tsutsui return; 847 1.7 tsutsui } 848 1.1 tsutsui } 849 1.1 tsutsui } 850 1.1 tsutsui 851 1.1 tsutsui static void 852 1.15 tsutsui trm_update_xfer_mode(struct trm_softc *sc, int target) 853 1.1 tsutsui { 854 1.7 tsutsui struct scsipi_xfer_mode xm; 855 1.7 tsutsui struct trm_tinfo *ti; 856 1.1 tsutsui 857 1.7 tsutsui ti = &sc->sc_tinfo[target]; 858 1.7 tsutsui xm.xm_target = target; 859 1.7 tsutsui xm.xm_mode = 0; 860 1.7 tsutsui xm.xm_period = 0; 861 1.7 tsutsui xm.xm_offset = 0; 862 1.1 tsutsui 863 1.7 tsutsui if ((ti->synctl & WIDE_SYNC) != 0) 864 1.7 tsutsui xm.xm_mode |= PERIPH_CAP_WIDE16; 865 1.1 tsutsui 866 1.7 tsutsui if (ti->period > 0) { 867 1.7 tsutsui xm.xm_mode |= PERIPH_CAP_SYNC; 868 1.7 tsutsui xm.xm_period = ti->period; 869 1.7 tsutsui xm.xm_offset = ti->offset; 870 1.1 tsutsui } 871 1.7 tsutsui 872 1.7 tsutsui #ifdef notyet 873 1.7 tsutsui if ((ti->flag & USE_TAG_QUEUING) != 0) 874 1.7 tsutsui xm.xm_mode |= PERIPH_CAP_TQING; 875 1.7 tsutsui #endif 876 1.7 tsutsui 877 1.7 tsutsui scsipi_async_event(&sc->sc_channel, ASYNC_EVENT_XFER_MODE, &xm); 878 1.1 tsutsui } 879 1.1 tsutsui 880 1.1 tsutsui static void 881 1.15 tsutsui trm_sched(struct trm_softc *sc) 882 1.1 tsutsui { 883 1.7 tsutsui struct trm_srb *srb; 884 1.7 tsutsui struct scsipi_periph *periph; 885 1.7 tsutsui struct trm_tinfo *ti; 886 1.7 tsutsui struct trm_linfo *li; 887 1.7 tsutsui int s, lun, tag; 888 1.7 tsutsui 889 1.7 tsutsui DPRINTF(("trm_sched...\n")); 890 1.7 tsutsui 891 1.7 tsutsui TAILQ_FOREACH(srb, &sc->sc_readysrb, next) { 892 1.7 tsutsui periph = srb->xs->xs_periph; 893 1.7 tsutsui ti = &sc->sc_tinfo[periph->periph_target]; 894 1.7 tsutsui lun = periph->periph_lun; 895 1.7 tsutsui 896 1.7 tsutsui /* select type of tag for this command */ 897 1.7 tsutsui if ((ti->flag & NO_RESELECT) != 0 || 898 1.7 tsutsui (ti->flag & USE_TAG_QUEUING) == 0 || 899 1.7 tsutsui (srb->flag & AUTO_REQSENSE) != 0 || 900 1.7 tsutsui (srb->xs->xs_control & XS_CTL_REQSENSE) != 0) 901 1.7 tsutsui tag = 0; 902 1.7 tsutsui else 903 1.7 tsutsui tag = srb->xs->xs_tag_type; 904 1.7 tsutsui #if 0 905 1.7 tsutsui /* XXX use tags for polled commands? */ 906 1.7 tsutsui if (srb->xs->xs_control & XS_CTL_POLL) 907 1.7 tsutsui tag = 0; 908 1.7 tsutsui #endif 909 1.1 tsutsui 910 1.7 tsutsui s = splbio(); 911 1.7 tsutsui li = ti->linfo[lun]; 912 1.7 tsutsui if (li == NULL) { 913 1.7 tsutsui /* initialize lun info */ 914 1.7 tsutsui if ((li = malloc(sizeof(*li), M_DEVBUF, 915 1.7 tsutsui M_NOWAIT|M_ZERO)) == NULL) { 916 1.7 tsutsui splx(s); 917 1.7 tsutsui continue; 918 1.7 tsutsui } 919 1.7 tsutsui ti->linfo[lun] = li; 920 1.7 tsutsui } 921 1.1 tsutsui 922 1.7 tsutsui if (tag == 0) { 923 1.7 tsutsui /* try to issue this srb as an un-tagged command */ 924 1.7 tsutsui if (li->untagged == NULL) 925 1.7 tsutsui li->untagged = srb; 926 1.7 tsutsui } 927 1.7 tsutsui if (li->untagged != NULL) { 928 1.7 tsutsui tag = 0; 929 1.7 tsutsui if (li->busy != 1 && li->used == 0) { 930 1.7 tsutsui /* we need to issue the untagged command now */ 931 1.7 tsutsui srb = li->untagged; 932 1.7 tsutsui periph = srb->xs->xs_periph; 933 1.1 tsutsui } else { 934 1.7 tsutsui /* not ready yet */ 935 1.7 tsutsui splx(s); 936 1.7 tsutsui continue; 937 1.1 tsutsui } 938 1.1 tsutsui } 939 1.7 tsutsui srb->tag[0] = tag; 940 1.7 tsutsui if (tag != 0) { 941 1.7 tsutsui li->queued[srb->xs->xs_tag_id] = srb; 942 1.7 tsutsui srb->tag[1] = srb->xs->xs_tag_id; 943 1.7 tsutsui li->used++; 944 1.7 tsutsui } 945 1.7 tsutsui 946 1.7 tsutsui if (li->untagged != NULL && li->busy != 1) { 947 1.7 tsutsui li->busy = 1; 948 1.7 tsutsui TAILQ_REMOVE(&sc->sc_readysrb, srb, next); 949 1.7 tsutsui sc->sc_actsrb = srb; 950 1.7 tsutsui trm_select(sc, srb); 951 1.7 tsutsui splx(s); 952 1.7 tsutsui break; 953 1.7 tsutsui } 954 1.7 tsutsui if (li->untagged == NULL && tag != 0) { 955 1.7 tsutsui TAILQ_REMOVE(&sc->sc_readysrb, srb, next); 956 1.7 tsutsui sc->sc_actsrb = srb; 957 1.7 tsutsui trm_select(sc, srb); 958 1.7 tsutsui splx(s); 959 1.7 tsutsui break; 960 1.7 tsutsui } else 961 1.7 tsutsui splx(s); 962 1.7 tsutsui } 963 1.7 tsutsui } 964 1.7 tsutsui 965 1.7 tsutsui static int 966 1.15 tsutsui trm_select(struct trm_softc *sc, struct trm_srb *srb) 967 1.7 tsutsui { 968 1.7 tsutsui bus_space_tag_t iot = sc->sc_iot; 969 1.7 tsutsui bus_space_handle_t ioh = sc->sc_ioh; 970 1.7 tsutsui struct scsipi_periph *periph = srb->xs->xs_periph; 971 1.7 tsutsui int target = periph->periph_target; 972 1.7 tsutsui int lun = periph->periph_lun; 973 1.7 tsutsui struct trm_tinfo *ti = &sc->sc_tinfo[target]; 974 1.16 tsutsui uint8_t scsicmd; 975 1.7 tsutsui 976 1.7 tsutsui DPRINTF(("trm_select.....\n")); 977 1.7 tsutsui 978 1.7 tsutsui if ((srb->xs->xs_control & XS_CTL_POLL) == 0) { 979 1.10 bouyer callout_reset(&srb->xs->xs_callout, mstohz(srb->xs->timeout), 980 1.10 bouyer trm_timeout, srb); 981 1.7 tsutsui } 982 1.7 tsutsui 983 1.7 tsutsui bus_space_write_1(iot, ioh, TRM_SCSI_HOSTID, sc->sc_id); 984 1.7 tsutsui bus_space_write_1(iot, ioh, TRM_SCSI_TARGETID, target); 985 1.7 tsutsui bus_space_write_1(iot, ioh, TRM_SCSI_SYNC, ti->synctl); 986 1.7 tsutsui bus_space_write_1(iot, ioh, TRM_SCSI_OFFSET, ti->offset); 987 1.7 tsutsui /* Flush FIFO */ 988 1.7 tsutsui bus_space_write_2(iot, ioh, TRM_SCSI_CONTROL, DO_CLRFIFO); 989 1.7 tsutsui DELAY(10); 990 1.7 tsutsui 991 1.7 tsutsui sc->sc_phase = PH_BUS_FREE; /* initial phase */ 992 1.7 tsutsui 993 1.7 tsutsui DPRINTF(("cmd = 0x%02x\n", srb->cmd[0])); 994 1.7 tsutsui 995 1.7 tsutsui if (((ti->flag & WIDE_NEGO_ENABLE) && 996 1.7 tsutsui (ti->flag & WIDE_NEGO_DONE) == 0) || 997 1.7 tsutsui ((ti->flag & SYNC_NEGO_ENABLE) && 998 1.7 tsutsui (ti->flag & SYNC_NEGO_DONE) == 0)) { 999 1.7 tsutsui sc->sc_state = TRM_MSGOUT; 1000 1.7 tsutsui bus_space_write_1(iot, ioh, TRM_SCSI_FIFO, 1001 1.7 tsutsui MSG_IDENTIFY(lun, 0)); 1002 1.7 tsutsui bus_space_write_multi_1(iot, ioh, 1003 1.7 tsutsui TRM_SCSI_FIFO, srb->cmd, srb->cmdlen); 1004 1.7 tsutsui /* it's important for atn stop */ 1005 1.7 tsutsui bus_space_write_2(iot, ioh, TRM_SCSI_CONTROL, 1006 1.7 tsutsui DO_DATALATCH | DO_HWRESELECT); 1007 1.7 tsutsui /* SCSI command */ 1008 1.7 tsutsui bus_space_write_1(iot, ioh, TRM_SCSI_COMMAND, SCMD_SEL_ATNSTOP); 1009 1.7 tsutsui DPRINTF(("select with SEL_ATNSTOP\n")); 1010 1.29 tsutsui return 0; 1011 1.1 tsutsui } 1012 1.7 tsutsui 1013 1.7 tsutsui if (srb->tag[0] != 0) { 1014 1.7 tsutsui /* Send identify message */ 1015 1.7 tsutsui bus_space_write_1(iot, ioh, TRM_SCSI_FIFO, 1016 1.7 tsutsui MSG_IDENTIFY(lun, 1)); 1017 1.7 tsutsui /* Send Tag id */ 1018 1.7 tsutsui bus_space_write_1(iot, ioh, TRM_SCSI_FIFO, srb->tag[0]); 1019 1.7 tsutsui bus_space_write_1(iot, ioh, TRM_SCSI_FIFO, srb->tag[1]); 1020 1.7 tsutsui scsicmd = SCMD_SEL_ATN3; 1021 1.7 tsutsui DPRINTF(("select with SEL_ATN3\n")); 1022 1.7 tsutsui } else { 1023 1.7 tsutsui /* Send identify message */ 1024 1.7 tsutsui bus_space_write_1(iot, ioh, TRM_SCSI_FIFO, 1025 1.7 tsutsui MSG_IDENTIFY(lun, 1026 1.7 tsutsui (ti->flag & NO_RESELECT) == 0 && 1027 1.7 tsutsui (srb->flag & AUTO_REQSENSE) == 0 && 1028 1.7 tsutsui (srb->xs->xs_control & XS_CTL_REQSENSE) == 0)); 1029 1.7 tsutsui scsicmd = SCMD_SEL_ATN; 1030 1.7 tsutsui DPRINTF(("select with SEL_ATN\n")); 1031 1.7 tsutsui } 1032 1.7 tsutsui sc->sc_state = TRM_START; 1033 1.7 tsutsui 1034 1.7 tsutsui /* 1035 1.7 tsutsui * Send CDB ..command block... 1036 1.7 tsutsui */ 1037 1.7 tsutsui bus_space_write_multi_1(iot, ioh, TRM_SCSI_FIFO, srb->cmd, srb->cmdlen); 1038 1.7 tsutsui 1039 1.7 tsutsui /* 1040 1.8 wiz * If trm_select returns 0: current interrupt status 1041 1.7 tsutsui * is interrupt enable. It's said that SCSI processor is 1042 1.7 tsutsui * unoccupied. 1043 1.7 tsutsui */ 1044 1.7 tsutsui sc->sc_phase = PH_BUS_FREE; /* SCSI bus free Phase */ 1045 1.7 tsutsui /* SCSI command */ 1046 1.7 tsutsui bus_space_write_1(iot, ioh, TRM_SCSI_COMMAND, scsicmd); 1047 1.29 tsutsui return 0; 1048 1.1 tsutsui } 1049 1.1 tsutsui 1050 1.1 tsutsui /* 1051 1.1 tsutsui * perform a hard reset on the SCSI bus (and TRM_S1040 chip). 1052 1.1 tsutsui */ 1053 1.1 tsutsui static void 1054 1.15 tsutsui trm_reset(struct trm_softc *sc) 1055 1.1 tsutsui { 1056 1.1 tsutsui bus_space_tag_t iot = sc->sc_iot; 1057 1.1 tsutsui bus_space_handle_t ioh = sc->sc_ioh; 1058 1.1 tsutsui int s; 1059 1.1 tsutsui 1060 1.7 tsutsui DPRINTF(("trm_reset.........\n")); 1061 1.7 tsutsui 1062 1.1 tsutsui s = splbio(); 1063 1.1 tsutsui 1064 1.1 tsutsui /* disable SCSI and DMA interrupt */ 1065 1.1 tsutsui bus_space_write_1(iot, ioh, TRM_DMA_INTEN, 0); 1066 1.1 tsutsui bus_space_write_1(iot, ioh, TRM_SCSI_INTEN, 0); 1067 1.1 tsutsui 1068 1.1 tsutsui trm_reset_scsi_bus(sc); 1069 1.7 tsutsui DELAY(100000); 1070 1.1 tsutsui 1071 1.1 tsutsui /* Enable SCSI interrupt */ 1072 1.1 tsutsui bus_space_write_1(iot, ioh, TRM_SCSI_INTEN, 1073 1.1 tsutsui EN_SELECT | EN_SELTIMEOUT | EN_DISCONNECT | EN_RESELECTED | 1074 1.1 tsutsui EN_SCSIRESET | EN_BUSSERVICE | EN_CMDDONE); 1075 1.1 tsutsui 1076 1.1 tsutsui /* Enable DMA interrupt */ 1077 1.1 tsutsui bus_space_write_1(iot, ioh, TRM_DMA_INTEN, EN_SCSIINTR); 1078 1.1 tsutsui 1079 1.1 tsutsui /* Clear DMA FIFO */ 1080 1.1 tsutsui bus_space_write_1(iot, ioh, TRM_DMA_CONTROL, CLRXFIFO); 1081 1.1 tsutsui 1082 1.1 tsutsui /* Clear SCSI FIFO */ 1083 1.1 tsutsui bus_space_write_2(iot, ioh, TRM_SCSI_CONTROL, DO_CLRFIFO); 1084 1.1 tsutsui 1085 1.7 tsutsui sc->sc_actsrb = NULL; 1086 1.1 tsutsui sc->sc_flag = 0; /* RESET_DETECT, RESET_DONE, RESET_DEV */ 1087 1.1 tsutsui 1088 1.1 tsutsui splx(s); 1089 1.1 tsutsui } 1090 1.1 tsutsui 1091 1.1 tsutsui static void 1092 1.15 tsutsui trm_timeout(void *arg) 1093 1.1 tsutsui { 1094 1.1 tsutsui struct trm_srb *srb = (struct trm_srb *)arg; 1095 1.22 rpaulo struct scsipi_xfer *xs; 1096 1.22 rpaulo struct scsipi_periph *periph; 1097 1.1 tsutsui struct trm_softc *sc; 1098 1.1 tsutsui int s; 1099 1.1 tsutsui 1100 1.22 rpaulo if (srb == NULL) { 1101 1.22 rpaulo printf("trm_timeout called with srb == NULL\n"); 1102 1.22 rpaulo return; 1103 1.22 rpaulo } 1104 1.22 rpaulo 1105 1.22 rpaulo xs = srb->xs; 1106 1.22 rpaulo if (xs == NULL) { 1107 1.1 tsutsui printf("trm_timeout called with xs == NULL\n"); 1108 1.22 rpaulo return; 1109 1.22 rpaulo } 1110 1.1 tsutsui 1111 1.22 rpaulo periph = xs->xs_periph; 1112 1.22 rpaulo scsipi_printaddr(xs->xs_periph); 1113 1.22 rpaulo printf("SCSI OpCode 0x%02x timed out\n", xs->cmd->opcode); 1114 1.1 tsutsui 1115 1.29 tsutsui sc = device_private(periph->periph_channel->chan_adapter->adapt_dev); 1116 1.1 tsutsui 1117 1.7 tsutsui trm_reset_scsi_bus(sc); 1118 1.1 tsutsui s = splbio(); 1119 1.7 tsutsui srb->flag |= SRB_TIMEOUT; 1120 1.7 tsutsui trm_done(sc, srb); 1121 1.7 tsutsui /* XXX needs more.. */ 1122 1.1 tsutsui splx(s); 1123 1.1 tsutsui } 1124 1.1 tsutsui 1125 1.1 tsutsui /* 1126 1.1 tsutsui * Catch an interrupt from the adapter 1127 1.1 tsutsui * Process pending device interrupts. 1128 1.1 tsutsui */ 1129 1.1 tsutsui static int 1130 1.15 tsutsui trm_intr(void *arg) 1131 1.1 tsutsui { 1132 1.1 tsutsui bus_space_tag_t iot; 1133 1.1 tsutsui bus_space_handle_t ioh; 1134 1.1 tsutsui struct trm_softc *sc; 1135 1.7 tsutsui int intstat, stat; 1136 1.7 tsutsui 1137 1.7 tsutsui DPRINTF(("trm_intr......\n")); 1138 1.29 tsutsui sc = arg; 1139 1.7 tsutsui if (sc == NULL) 1140 1.29 tsutsui return 0; 1141 1.1 tsutsui 1142 1.1 tsutsui iot = sc->sc_iot; 1143 1.1 tsutsui ioh = sc->sc_ioh; 1144 1.1 tsutsui 1145 1.1 tsutsui stat = bus_space_read_2(iot, ioh, TRM_SCSI_STATUS); 1146 1.1 tsutsui if ((stat & SCSIINTERRUPT) == 0) 1147 1.29 tsutsui return 0; 1148 1.1 tsutsui 1149 1.7 tsutsui DPRINTF(("stat = %04x, ", stat)); 1150 1.1 tsutsui intstat = bus_space_read_1(iot, ioh, TRM_SCSI_INTSTATUS); 1151 1.1 tsutsui 1152 1.7 tsutsui DPRINTF(("intstat=%02x, ", intstat)); 1153 1.1 tsutsui if (intstat & (INT_SELTIMEOUT | INT_DISCONNECT)) { 1154 1.7 tsutsui DPRINTF(("\n")); 1155 1.1 tsutsui trm_disconnect(sc); 1156 1.29 tsutsui return 1; 1157 1.1 tsutsui } 1158 1.1 tsutsui if (intstat & INT_RESELECTED) { 1159 1.7 tsutsui DPRINTF(("\n")); 1160 1.1 tsutsui trm_reselect(sc); 1161 1.29 tsutsui return 1; 1162 1.1 tsutsui } 1163 1.1 tsutsui if (intstat & INT_SCSIRESET) { 1164 1.7 tsutsui DPRINTF(("\n")); 1165 1.1 tsutsui trm_scsi_reset_detect(sc); 1166 1.29 tsutsui return 1; 1167 1.1 tsutsui } 1168 1.1 tsutsui if (intstat & (INT_BUSSERVICE | INT_CMDDONE)) { 1169 1.7 tsutsui DPRINTF(("sc->sc_phase = %2d, sc->sc_state = %2d\n", 1170 1.7 tsutsui sc->sc_phase, sc->sc_state)); 1171 1.1 tsutsui /* 1172 1.1 tsutsui * software sequential machine 1173 1.1 tsutsui */ 1174 1.1 tsutsui 1175 1.1 tsutsui /* 1176 1.7 tsutsui * call phase0 functions... "phase entry" handle 1177 1.7 tsutsui * every phase before start transfer 1178 1.1 tsutsui */ 1179 1.7 tsutsui switch (sc->sc_phase) { 1180 1.7 tsutsui case PH_DATA_OUT: 1181 1.7 tsutsui trm_dataout_phase0(sc, stat); 1182 1.7 tsutsui break; 1183 1.7 tsutsui case PH_DATA_IN: 1184 1.7 tsutsui trm_datain_phase0(sc, stat); 1185 1.7 tsutsui break; 1186 1.7 tsutsui case PH_COMMAND: 1187 1.7 tsutsui break; 1188 1.7 tsutsui case PH_STATUS: 1189 1.7 tsutsui trm_status_phase0(sc); 1190 1.7 tsutsui stat = PH_BUS_FREE; 1191 1.7 tsutsui break; 1192 1.7 tsutsui case PH_MSG_OUT: 1193 1.7 tsutsui if (sc->sc_state == TRM_UNEXPECT_RESEL || 1194 1.7 tsutsui sc->sc_state == TRM_ABORT_SENT) 1195 1.7 tsutsui stat = PH_BUS_FREE; 1196 1.7 tsutsui break; 1197 1.7 tsutsui case PH_MSG_IN: 1198 1.7 tsutsui trm_msgin_phase0(sc); 1199 1.7 tsutsui stat = PH_BUS_FREE; 1200 1.7 tsutsui break; 1201 1.7 tsutsui case PH_BUS_FREE: 1202 1.7 tsutsui break; 1203 1.7 tsutsui default: 1204 1.29 tsutsui printf("%s: unexpected phase in trm_intr() phase0\n", 1205 1.29 tsutsui device_xname(sc->sc_dev)); 1206 1.7 tsutsui break; 1207 1.7 tsutsui } 1208 1.1 tsutsui 1209 1.7 tsutsui sc->sc_phase = stat & PHASEMASK; 1210 1.7 tsutsui 1211 1.7 tsutsui switch (sc->sc_phase) { 1212 1.7 tsutsui case PH_DATA_OUT: 1213 1.7 tsutsui trm_dataio_xfer(sc, XFERDATAOUT); 1214 1.7 tsutsui break; 1215 1.7 tsutsui case PH_DATA_IN: 1216 1.7 tsutsui trm_dataio_xfer(sc, XFERDATAIN); 1217 1.7 tsutsui break; 1218 1.7 tsutsui case PH_COMMAND: 1219 1.7 tsutsui trm_command_phase1(sc); 1220 1.7 tsutsui break; 1221 1.7 tsutsui case PH_STATUS: 1222 1.7 tsutsui trm_status_phase1(sc); 1223 1.7 tsutsui break; 1224 1.7 tsutsui case PH_MSG_OUT: 1225 1.7 tsutsui trm_msgout_phase1(sc); 1226 1.7 tsutsui break; 1227 1.7 tsutsui case PH_MSG_IN: 1228 1.7 tsutsui trm_msgin_phase1(sc); 1229 1.7 tsutsui break; 1230 1.7 tsutsui case PH_BUS_FREE: 1231 1.7 tsutsui break; 1232 1.7 tsutsui default: 1233 1.29 tsutsui printf("%s: unexpected phase in trm_intr() phase1\n", 1234 1.29 tsutsui device_xname(sc->sc_dev)); 1235 1.7 tsutsui break; 1236 1.7 tsutsui } 1237 1.1 tsutsui 1238 1.29 tsutsui return 1; 1239 1.1 tsutsui } 1240 1.29 tsutsui return 0; 1241 1.1 tsutsui } 1242 1.1 tsutsui 1243 1.1 tsutsui static void 1244 1.15 tsutsui trm_msgout_phase1(struct trm_softc *sc) 1245 1.1 tsutsui { 1246 1.1 tsutsui bus_space_tag_t iot = sc->sc_iot; 1247 1.1 tsutsui bus_space_handle_t ioh = sc->sc_ioh; 1248 1.7 tsutsui struct trm_srb *srb; 1249 1.7 tsutsui struct scsipi_periph *periph; 1250 1.7 tsutsui struct trm_tinfo *ti; 1251 1.1 tsutsui 1252 1.1 tsutsui bus_space_write_2(iot, ioh, TRM_SCSI_CONTROL, DO_CLRFIFO); 1253 1.1 tsutsui 1254 1.7 tsutsui srb = sc->sc_actsrb; 1255 1.7 tsutsui 1256 1.7 tsutsui /* message out phase */ 1257 1.7 tsutsui if (srb != NULL) { 1258 1.7 tsutsui periph = srb->xs->xs_periph; 1259 1.7 tsutsui ti = &sc->sc_tinfo[periph->periph_target]; 1260 1.7 tsutsui 1261 1.7 tsutsui if ((ti->flag & WIDE_NEGO_DOING) == 0 && 1262 1.7 tsutsui (ti->flag & WIDE_NEGO_ENABLE)) { 1263 1.7 tsutsui /* send WDTR */ 1264 1.7 tsutsui ti->flag &= ~SYNC_NEGO_DONE; 1265 1.7 tsutsui 1266 1.7 tsutsui sc->sc_msgbuf[0] = MSG_IDENTIFY(periph->periph_lun, 0); 1267 1.7 tsutsui sc->sc_msgbuf[1] = MSG_EXTENDED; 1268 1.7 tsutsui sc->sc_msgbuf[2] = MSG_EXT_WDTR_LEN; 1269 1.7 tsutsui sc->sc_msgbuf[3] = MSG_EXT_WDTR; 1270 1.7 tsutsui sc->sc_msgbuf[4] = MSG_EXT_WDTR_BUS_16_BIT; 1271 1.7 tsutsui sc->sc_msgcnt = 5; 1272 1.7 tsutsui 1273 1.7 tsutsui ti->flag |= WIDE_NEGO_DOING; 1274 1.7 tsutsui } else if ((ti->flag & SYNC_NEGO_DOING) == 0 && 1275 1.7 tsutsui (ti->flag & SYNC_NEGO_ENABLE)) { 1276 1.7 tsutsui /* send SDTR */ 1277 1.7 tsutsui int cnt = 0; 1278 1.7 tsutsui 1279 1.7 tsutsui if ((ti->flag & WIDE_NEGO_DONE) == 0) 1280 1.7 tsutsui sc->sc_msgbuf[cnt++] = 1281 1.7 tsutsui MSG_IDENTIFY(periph->periph_lun, 0); 1282 1.7 tsutsui 1283 1.7 tsutsui sc->sc_msgbuf[cnt++] = MSG_EXTENDED; 1284 1.7 tsutsui sc->sc_msgbuf[cnt++] = MSG_EXT_SDTR_LEN; 1285 1.7 tsutsui sc->sc_msgbuf[cnt++] = MSG_EXT_SDTR; 1286 1.7 tsutsui sc->sc_msgbuf[cnt++] = ti->period; 1287 1.7 tsutsui sc->sc_msgbuf[cnt++] = TRM_MAX_OFFSET; 1288 1.7 tsutsui sc->sc_msgcnt = cnt; 1289 1.7 tsutsui ti->flag |= SYNC_NEGO_DOING; 1290 1.7 tsutsui } 1291 1.7 tsutsui } 1292 1.7 tsutsui if (sc->sc_msgcnt == 0) { 1293 1.7 tsutsui sc->sc_msgbuf[0] = MSG_ABORT; 1294 1.7 tsutsui sc->sc_msgcnt = 1; 1295 1.7 tsutsui sc->sc_state = TRM_ABORT_SENT; 1296 1.7 tsutsui } 1297 1.7 tsutsui 1298 1.7 tsutsui DPRINTF(("msgout: cnt = %d, ", sc->sc_msgcnt)); 1299 1.7 tsutsui DPRINTF(("msgbuf = %02x %02x %02x %02x %02x %02x\n", 1300 1.7 tsutsui sc->sc_msgbuf[0], sc->sc_msgbuf[1], sc->sc_msgbuf[2], 1301 1.7 tsutsui sc->sc_msgbuf[3], sc->sc_msgbuf[4], sc->sc_msgbuf[5])); 1302 1.7 tsutsui 1303 1.7 tsutsui bus_space_write_multi_1(iot, ioh, TRM_SCSI_FIFO, 1304 1.7 tsutsui sc->sc_msgbuf, sc->sc_msgcnt); 1305 1.7 tsutsui sc->sc_msgcnt = 0; 1306 1.7 tsutsui memset(sc->sc_msgbuf, 0, sizeof(sc->sc_msgbuf)); 1307 1.7 tsutsui 1308 1.1 tsutsui /* it's important for atn stop */ 1309 1.18 perry bus_space_write_2(iot, ioh, TRM_SCSI_CONTROL, DO_DATALATCH); 1310 1.1 tsutsui 1311 1.1 tsutsui /* 1312 1.8 wiz * SCSI command 1313 1.1 tsutsui */ 1314 1.1 tsutsui bus_space_write_1(iot, ioh, TRM_SCSI_COMMAND, SCMD_FIFO_OUT); 1315 1.1 tsutsui } 1316 1.1 tsutsui 1317 1.1 tsutsui static void 1318 1.15 tsutsui trm_command_phase1(struct trm_softc *sc) 1319 1.7 tsutsui { 1320 1.7 tsutsui bus_space_tag_t iot = sc->sc_iot; 1321 1.7 tsutsui bus_space_handle_t ioh = sc->sc_ioh; 1322 1.1 tsutsui struct trm_srb *srb; 1323 1.1 tsutsui 1324 1.7 tsutsui srb = sc->sc_actsrb; 1325 1.7 tsutsui if (srb == NULL) { 1326 1.7 tsutsui DPRINTF(("trm_command_phase1: no active srb\n")); 1327 1.7 tsutsui return; 1328 1.7 tsutsui } 1329 1.1 tsutsui 1330 1.1 tsutsui bus_space_write_2(iot, ioh, TRM_SCSI_CONTROL, DO_CLRATN | DO_CLRFIFO); 1331 1.5 tsutsui bus_space_write_multi_1(iot, ioh, TRM_SCSI_FIFO, srb->cmd, srb->cmdlen); 1332 1.1 tsutsui 1333 1.7 tsutsui sc->sc_state = TRM_COMMAND; 1334 1.1 tsutsui /* it's important for atn stop */ 1335 1.18 perry bus_space_write_2(iot, ioh, TRM_SCSI_CONTROL, DO_DATALATCH); 1336 1.1 tsutsui 1337 1.1 tsutsui /* 1338 1.8 wiz * SCSI command 1339 1.1 tsutsui */ 1340 1.1 tsutsui bus_space_write_1(iot, ioh, TRM_SCSI_COMMAND, SCMD_FIFO_OUT); 1341 1.1 tsutsui } 1342 1.1 tsutsui 1343 1.1 tsutsui static void 1344 1.15 tsutsui trm_dataout_phase0(struct trm_softc *sc, int stat) 1345 1.1 tsutsui { 1346 1.1 tsutsui bus_space_tag_t iot = sc->sc_iot; 1347 1.1 tsutsui bus_space_handle_t ioh = sc->sc_ioh; 1348 1.7 tsutsui struct trm_srb *srb; 1349 1.7 tsutsui struct scsipi_periph *periph; 1350 1.7 tsutsui struct trm_tinfo *ti; 1351 1.1 tsutsui struct trm_sg_entry *sg; 1352 1.1 tsutsui int sgindex; 1353 1.16 tsutsui uint32_t xferlen, leftcnt = 0; 1354 1.1 tsutsui 1355 1.7 tsutsui if (sc->sc_state == TRM_XFERPAD) 1356 1.7 tsutsui return; 1357 1.7 tsutsui 1358 1.7 tsutsui srb = sc->sc_actsrb; 1359 1.7 tsutsui if (srb == NULL) { 1360 1.7 tsutsui DPRINTF(("trm_dataout_phase0: no active srb\n")); 1361 1.7 tsutsui return; 1362 1.7 tsutsui } 1363 1.7 tsutsui periph = srb->xs->xs_periph; 1364 1.7 tsutsui ti = &sc->sc_tinfo[periph->periph_target]; 1365 1.1 tsutsui 1366 1.7 tsutsui if ((stat & PARITYERROR) != 0) 1367 1.7 tsutsui srb->flag |= PARITY_ERROR; 1368 1.1 tsutsui 1369 1.7 tsutsui if ((stat & SCSIXFERDONE) == 0) { 1370 1.7 tsutsui /* 1371 1.7 tsutsui * when data transfer from DMA FIFO to SCSI FIFO 1372 1.7 tsutsui * if there was some data left in SCSI FIFO 1373 1.7 tsutsui */ 1374 1.7 tsutsui leftcnt = bus_space_read_1(iot, ioh, TRM_SCSI_FIFOCNT) & 1375 1.7 tsutsui SCSI_FIFOCNT_MASK; 1376 1.7 tsutsui if (ti->synctl & WIDE_SYNC) 1377 1.1 tsutsui /* 1378 1.7 tsutsui * if WIDE scsi SCSI FIFOCNT unit is word 1379 1.7 tsutsui * so need to * 2 1380 1.1 tsutsui */ 1381 1.7 tsutsui leftcnt <<= 1; 1382 1.7 tsutsui } 1383 1.7 tsutsui /* 1384 1.8 wiz * calculate all the residue data that was not yet transferred 1385 1.7 tsutsui * SCSI transfer counter + left in SCSI FIFO data 1386 1.7 tsutsui * 1387 1.7 tsutsui * .....TRM_SCSI_XCNT (24bits) 1388 1.8 wiz * The counter always decrements by one for every SCSI 1389 1.7 tsutsui * byte transfer. 1390 1.7 tsutsui * .....TRM_SCSI_FIFOCNT ( 5bits) 1391 1.7 tsutsui * The counter is SCSI FIFO offset counter 1392 1.7 tsutsui */ 1393 1.7 tsutsui leftcnt += bus_space_read_4(iot, ioh, TRM_SCSI_XCNT); 1394 1.7 tsutsui if (leftcnt == 1) { 1395 1.7 tsutsui leftcnt = 0; 1396 1.7 tsutsui bus_space_write_2(iot, ioh, TRM_SCSI_CONTROL, DO_CLRFIFO); 1397 1.7 tsutsui } 1398 1.7 tsutsui if ((leftcnt == 0) || (stat & SCSIXFERCNT_2_ZERO)) { 1399 1.7 tsutsui while ((bus_space_read_1(iot, ioh, TRM_DMA_STATUS) & 1400 1.7 tsutsui DMAXFERCOMP) == 0) 1401 1.7 tsutsui ; /* XXX needs timeout */ 1402 1.7 tsutsui 1403 1.7 tsutsui srb->buflen = 0; 1404 1.7 tsutsui } else { 1405 1.7 tsutsui /* Update SG list */ 1406 1.7 tsutsui 1407 1.1 tsutsui /* 1408 1.7 tsutsui * if transfer not yet complete 1409 1.7 tsutsui * there were some data residue in SCSI FIFO or 1410 1.7 tsutsui * SCSI transfer counter not empty 1411 1.1 tsutsui */ 1412 1.7 tsutsui if (srb->buflen != leftcnt) { 1413 1.7 tsutsui /* data that had transferred length */ 1414 1.7 tsutsui xferlen = srb->buflen - leftcnt; 1415 1.7 tsutsui 1416 1.7 tsutsui /* next time to be transferred length */ 1417 1.7 tsutsui srb->buflen = leftcnt; 1418 1.1 tsutsui 1419 1.1 tsutsui /* 1420 1.7 tsutsui * parsing from last time disconnect sgindex 1421 1.1 tsutsui */ 1422 1.7 tsutsui sg = srb->sgentry + srb->sgindex; 1423 1.7 tsutsui for (sgindex = srb->sgindex; 1424 1.7 tsutsui sgindex < srb->sgcnt; 1425 1.7 tsutsui sgindex++, sg++) { 1426 1.1 tsutsui /* 1427 1.7 tsutsui * find last time which SG transfer 1428 1.7 tsutsui * be disconnect 1429 1.1 tsutsui */ 1430 1.7 tsutsui if (xferlen >= le32toh(sg->length)) 1431 1.7 tsutsui xferlen -= le32toh(sg->length); 1432 1.7 tsutsui else { 1433 1.1 tsutsui /* 1434 1.7 tsutsui * update last time 1435 1.7 tsutsui * disconnected SG list 1436 1.1 tsutsui */ 1437 1.7 tsutsui /* residue data length */ 1438 1.7 tsutsui sg->length = 1439 1.7 tsutsui htole32(le32toh(sg->length) 1440 1.7 tsutsui - xferlen); 1441 1.7 tsutsui /* residue data pointer */ 1442 1.7 tsutsui sg->address = 1443 1.7 tsutsui htole32(le32toh(sg->address) 1444 1.7 tsutsui + xferlen); 1445 1.7 tsutsui srb->sgindex = sgindex; 1446 1.7 tsutsui break; 1447 1.1 tsutsui } 1448 1.1 tsutsui } 1449 1.7 tsutsui bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap, 1450 1.7 tsutsui srb->sgoffset, TRM_SG_SIZE, BUS_DMASYNC_PREWRITE); 1451 1.1 tsutsui } 1452 1.1 tsutsui } 1453 1.1 tsutsui bus_space_write_1(iot, ioh, TRM_DMA_CONTROL, STOPDMAXFER); 1454 1.1 tsutsui } 1455 1.1 tsutsui 1456 1.1 tsutsui static void 1457 1.15 tsutsui trm_datain_phase0(struct trm_softc *sc, int stat) 1458 1.1 tsutsui { 1459 1.1 tsutsui bus_space_tag_t iot = sc->sc_iot; 1460 1.1 tsutsui bus_space_handle_t ioh = sc->sc_ioh; 1461 1.7 tsutsui struct trm_srb *srb; 1462 1.1 tsutsui struct trm_sg_entry *sg; 1463 1.1 tsutsui int sgindex; 1464 1.16 tsutsui uint32_t xferlen, leftcnt = 0; 1465 1.1 tsutsui 1466 1.7 tsutsui if (sc->sc_state == TRM_XFERPAD) 1467 1.7 tsutsui return; 1468 1.7 tsutsui 1469 1.7 tsutsui srb = sc->sc_actsrb; 1470 1.7 tsutsui if (srb == NULL) { 1471 1.7 tsutsui DPRINTF(("trm_datain_phase0: no active srb\n")); 1472 1.7 tsutsui return; 1473 1.7 tsutsui } 1474 1.7 tsutsui 1475 1.7 tsutsui if (stat & PARITYERROR) 1476 1.7 tsutsui srb->flag |= PARITY_ERROR; 1477 1.7 tsutsui 1478 1.7 tsutsui leftcnt += bus_space_read_4(iot, ioh, TRM_SCSI_XCNT); 1479 1.7 tsutsui if ((leftcnt == 0) || (stat & SCSIXFERCNT_2_ZERO)) { 1480 1.7 tsutsui while ((bus_space_read_1(iot, ioh, TRM_DMA_STATUS) & 1481 1.7 tsutsui DMAXFERCOMP) == 0) 1482 1.7 tsutsui ; /* XXX needs timeout */ 1483 1.1 tsutsui 1484 1.7 tsutsui srb->buflen = 0; 1485 1.7 tsutsui } else { /* phase changed */ 1486 1.7 tsutsui /* 1487 1.7 tsutsui * parsing the case: 1488 1.7 tsutsui * when a transfer not yet complete 1489 1.8 wiz * but be disconnected by upper layer 1490 1.7 tsutsui * if transfer not yet complete 1491 1.7 tsutsui * there were some data residue in SCSI FIFO or 1492 1.7 tsutsui * SCSI transfer counter not empty 1493 1.7 tsutsui */ 1494 1.7 tsutsui if (srb->buflen != leftcnt) { 1495 1.1 tsutsui /* 1496 1.7 tsutsui * data that had transferred length 1497 1.1 tsutsui */ 1498 1.7 tsutsui xferlen = srb->buflen - leftcnt; 1499 1.1 tsutsui 1500 1.7 tsutsui /* 1501 1.7 tsutsui * next time to be transferred length 1502 1.7 tsutsui */ 1503 1.7 tsutsui srb->buflen = leftcnt; 1504 1.1 tsutsui 1505 1.7 tsutsui /* 1506 1.7 tsutsui * parsing from last time disconnect sgindex 1507 1.7 tsutsui */ 1508 1.7 tsutsui sg = srb->sgentry + srb->sgindex; 1509 1.7 tsutsui for (sgindex = srb->sgindex; 1510 1.7 tsutsui sgindex < srb->sgcnt; 1511 1.7 tsutsui sgindex++, sg++) { 1512 1.1 tsutsui /* 1513 1.7 tsutsui * find last time which SG transfer 1514 1.7 tsutsui * be disconnect 1515 1.1 tsutsui */ 1516 1.7 tsutsui if (xferlen >= le32toh(sg->length)) 1517 1.7 tsutsui xferlen -= le32toh(sg->length); 1518 1.7 tsutsui else { 1519 1.1 tsutsui /* 1520 1.7 tsutsui * update last time 1521 1.7 tsutsui * disconnected SG list 1522 1.1 tsutsui */ 1523 1.7 tsutsui /* residue data length */ 1524 1.7 tsutsui sg->length = 1525 1.7 tsutsui htole32(le32toh(sg->length) 1526 1.7 tsutsui - xferlen); 1527 1.7 tsutsui /* residue data pointer */ 1528 1.7 tsutsui sg->address = 1529 1.7 tsutsui htole32(le32toh(sg->address) 1530 1.7 tsutsui + xferlen); 1531 1.7 tsutsui srb->sgindex = sgindex; 1532 1.7 tsutsui break; 1533 1.1 tsutsui } 1534 1.1 tsutsui } 1535 1.7 tsutsui bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap, 1536 1.7 tsutsui srb->sgoffset, TRM_SG_SIZE, BUS_DMASYNC_PREWRITE); 1537 1.1 tsutsui } 1538 1.1 tsutsui } 1539 1.1 tsutsui } 1540 1.1 tsutsui 1541 1.1 tsutsui static void 1542 1.15 tsutsui trm_dataio_xfer(struct trm_softc *sc, int iodir) 1543 1.1 tsutsui { 1544 1.1 tsutsui bus_space_tag_t iot = sc->sc_iot; 1545 1.1 tsutsui bus_space_handle_t ioh = sc->sc_ioh; 1546 1.7 tsutsui struct trm_srb *srb; 1547 1.7 tsutsui struct scsipi_periph *periph; 1548 1.7 tsutsui struct trm_tinfo *ti; 1549 1.7 tsutsui 1550 1.7 tsutsui srb = sc->sc_actsrb; 1551 1.7 tsutsui if (srb == NULL) { 1552 1.7 tsutsui DPRINTF(("trm_dataio_xfer: no active srb\n")); 1553 1.7 tsutsui return; 1554 1.7 tsutsui } 1555 1.7 tsutsui periph = srb->xs->xs_periph; 1556 1.7 tsutsui ti = &sc->sc_tinfo[periph->periph_target]; 1557 1.1 tsutsui 1558 1.1 tsutsui if (srb->sgindex < srb->sgcnt) { 1559 1.1 tsutsui if (srb->buflen > 0) { 1560 1.1 tsutsui /* 1561 1.1 tsutsui * load what physical address of Scatter/Gather 1562 1.1 tsutsui * list table want to be transfer 1563 1.1 tsutsui */ 1564 1.7 tsutsui sc->sc_state = TRM_DATA_XFER; 1565 1.1 tsutsui bus_space_write_4(iot, ioh, TRM_DMA_XHIGHADDR, 0); 1566 1.1 tsutsui bus_space_write_4(iot, ioh, TRM_DMA_XLOWADDR, 1567 1.1 tsutsui srb->sgaddr + 1568 1.1 tsutsui srb->sgindex * sizeof(struct trm_sg_entry)); 1569 1.1 tsutsui /* 1570 1.1 tsutsui * load how many bytes in the Scatter/Gather list table 1571 1.1 tsutsui */ 1572 1.1 tsutsui bus_space_write_4(iot, ioh, TRM_DMA_XCNT, 1573 1.1 tsutsui (srb->sgcnt - srb->sgindex) 1574 1.1 tsutsui * sizeof(struct trm_sg_entry)); 1575 1.1 tsutsui /* 1576 1.1 tsutsui * load total xfer length (24bits) max value 16Mbyte 1577 1.1 tsutsui */ 1578 1.1 tsutsui bus_space_write_4(iot, ioh, TRM_SCSI_XCNT, srb->buflen); 1579 1.1 tsutsui /* Start DMA transfer */ 1580 1.1 tsutsui bus_space_write_1(iot, ioh, TRM_DMA_COMMAND, 1581 1.1 tsutsui iodir | SGXFER); 1582 1.1 tsutsui bus_space_write_1(iot, ioh, TRM_DMA_CONTROL, 1583 1.1 tsutsui STARTDMAXFER); 1584 1.1 tsutsui 1585 1.1 tsutsui /* Start SCSI transfer */ 1586 1.1 tsutsui /* it's important for atn stop */ 1587 1.1 tsutsui bus_space_write_2(iot, ioh, TRM_SCSI_CONTROL, 1588 1.1 tsutsui DO_DATALATCH); 1589 1.18 perry 1590 1.1 tsutsui /* 1591 1.8 wiz * SCSI command 1592 1.1 tsutsui */ 1593 1.1 tsutsui bus_space_write_1(iot, ioh, TRM_SCSI_COMMAND, 1594 1.1 tsutsui (iodir == XFERDATAOUT) ? 1595 1.1 tsutsui SCMD_DMA_OUT : SCMD_DMA_IN); 1596 1.1 tsutsui } else { /* xfer pad */ 1597 1.1 tsutsui if (srb->sgcnt) { 1598 1.1 tsutsui srb->hastat = H_OVER_UNDER_RUN; 1599 1.1 tsutsui } 1600 1.1 tsutsui bus_space_write_4(iot, ioh, TRM_SCSI_XCNT, 1601 1.7 tsutsui (ti->synctl & WIDE_SYNC) ? 2 : 1); 1602 1.1 tsutsui 1603 1.1 tsutsui if (iodir == XFERDATAOUT) 1604 1.1 tsutsui bus_space_write_2(iot, ioh, TRM_SCSI_FIFO, 0); 1605 1.1 tsutsui else 1606 1.23 christos (void)bus_space_read_2(iot, ioh, TRM_SCSI_FIFO); 1607 1.1 tsutsui 1608 1.7 tsutsui sc->sc_state = TRM_XFERPAD; 1609 1.1 tsutsui /* it's important for atn stop */ 1610 1.1 tsutsui bus_space_write_2(iot, ioh, TRM_SCSI_CONTROL, 1611 1.1 tsutsui DO_DATALATCH); 1612 1.18 perry 1613 1.1 tsutsui /* 1614 1.8 wiz * SCSI command 1615 1.1 tsutsui */ 1616 1.1 tsutsui bus_space_write_1(iot, ioh, TRM_SCSI_COMMAND, 1617 1.1 tsutsui (iodir == XFERDATAOUT) ? 1618 1.1 tsutsui SCMD_FIFO_OUT : SCMD_FIFO_IN); 1619 1.1 tsutsui } 1620 1.1 tsutsui } 1621 1.1 tsutsui } 1622 1.1 tsutsui 1623 1.1 tsutsui static void 1624 1.15 tsutsui trm_status_phase0(struct trm_softc *sc) 1625 1.1 tsutsui { 1626 1.1 tsutsui bus_space_tag_t iot = sc->sc_iot; 1627 1.1 tsutsui bus_space_handle_t ioh = sc->sc_ioh; 1628 1.7 tsutsui struct trm_srb *srb; 1629 1.1 tsutsui 1630 1.7 tsutsui srb = sc->sc_actsrb; 1631 1.7 tsutsui if (srb == NULL) { 1632 1.7 tsutsui DPRINTF(("trm_status_phase0: no active srb\n")); 1633 1.7 tsutsui return; 1634 1.7 tsutsui } 1635 1.1 tsutsui srb->tastat = bus_space_read_1(iot, ioh, TRM_SCSI_FIFO); 1636 1.7 tsutsui sc->sc_state = TRM_COMPLETED; 1637 1.1 tsutsui /* it's important for atn stop */ 1638 1.1 tsutsui bus_space_write_2(iot, ioh, TRM_SCSI_CONTROL, DO_DATALATCH); 1639 1.1 tsutsui 1640 1.1 tsutsui /* 1641 1.7 tsutsui * SCSI command 1642 1.1 tsutsui */ 1643 1.1 tsutsui bus_space_write_1(iot, ioh, TRM_SCSI_COMMAND, SCMD_MSGACCEPT); 1644 1.1 tsutsui } 1645 1.1 tsutsui 1646 1.1 tsutsui static void 1647 1.15 tsutsui trm_status_phase1(struct trm_softc *sc) 1648 1.1 tsutsui { 1649 1.1 tsutsui bus_space_tag_t iot = sc->sc_iot; 1650 1.1 tsutsui bus_space_handle_t ioh = sc->sc_ioh; 1651 1.1 tsutsui 1652 1.1 tsutsui if (bus_space_read_1(iot, ioh, TRM_DMA_COMMAND) & XFERDATAIN) { 1653 1.1 tsutsui if ((bus_space_read_1(iot, ioh, TRM_SCSI_FIFOCNT) 1654 1.1 tsutsui & SCSI_FIFO_EMPTY) == 0) 1655 1.1 tsutsui bus_space_write_2(iot, ioh, 1656 1.1 tsutsui TRM_SCSI_CONTROL, DO_CLRFIFO); 1657 1.1 tsutsui if ((bus_space_read_1(iot, ioh, TRM_DMA_FIFOSTATUS) 1658 1.1 tsutsui & DMA_FIFO_EMPTY) == 0) 1659 1.1 tsutsui bus_space_write_1(iot, ioh, TRM_DMA_CONTROL, CLRXFIFO); 1660 1.1 tsutsui } else { 1661 1.1 tsutsui if ((bus_space_read_1(iot, ioh, TRM_DMA_FIFOSTATUS) 1662 1.1 tsutsui & DMA_FIFO_EMPTY) == 0) 1663 1.1 tsutsui bus_space_write_1(iot, ioh, TRM_DMA_CONTROL, CLRXFIFO); 1664 1.1 tsutsui if ((bus_space_read_1(iot, ioh, TRM_SCSI_FIFOCNT) 1665 1.1 tsutsui & SCSI_FIFO_EMPTY) == 0) 1666 1.1 tsutsui bus_space_write_2(iot, ioh, 1667 1.1 tsutsui TRM_SCSI_CONTROL, DO_CLRFIFO); 1668 1.1 tsutsui } 1669 1.7 tsutsui sc->sc_state = TRM_STATUS; 1670 1.1 tsutsui /* it's important for atn stop */ 1671 1.1 tsutsui bus_space_write_2(iot, ioh, TRM_SCSI_CONTROL, DO_DATALATCH); 1672 1.1 tsutsui 1673 1.1 tsutsui /* 1674 1.8 wiz * SCSI command 1675 1.1 tsutsui */ 1676 1.1 tsutsui bus_space_write_1(iot, ioh, TRM_SCSI_COMMAND, SCMD_COMP); 1677 1.1 tsutsui } 1678 1.1 tsutsui 1679 1.1 tsutsui static void 1680 1.15 tsutsui trm_msgin_phase0(struct trm_softc *sc) 1681 1.1 tsutsui { 1682 1.1 tsutsui bus_space_tag_t iot = sc->sc_iot; 1683 1.1 tsutsui bus_space_handle_t ioh = sc->sc_ioh; 1684 1.7 tsutsui struct trm_srb *srb; 1685 1.7 tsutsui struct scsipi_periph *periph; 1686 1.7 tsutsui struct trm_tinfo *ti; 1687 1.7 tsutsui int index; 1688 1.16 tsutsui uint8_t msgin_code; 1689 1.1 tsutsui 1690 1.1 tsutsui msgin_code = bus_space_read_1(iot, ioh, TRM_SCSI_FIFO); 1691 1.7 tsutsui if (sc->sc_state != TRM_EXTEND_MSGIN) { 1692 1.7 tsutsui DPRINTF(("msgin: code = %02x\n", msgin_code)); 1693 1.7 tsutsui switch (msgin_code) { 1694 1.7 tsutsui case MSG_DISCONNECT: 1695 1.7 tsutsui sc->sc_state = TRM_DISCONNECTED; 1696 1.7 tsutsui break; 1697 1.7 tsutsui 1698 1.7 tsutsui case MSG_SAVEDATAPOINTER: 1699 1.7 tsutsui break; 1700 1.7 tsutsui 1701 1.7 tsutsui case MSG_EXTENDED: 1702 1.7 tsutsui case MSG_SIMPLE_Q_TAG: 1703 1.7 tsutsui case MSG_HEAD_OF_Q_TAG: 1704 1.7 tsutsui case MSG_ORDERED_Q_TAG: 1705 1.7 tsutsui sc->sc_state = TRM_EXTEND_MSGIN; 1706 1.1 tsutsui /* extended message (01h) */ 1707 1.7 tsutsui sc->sc_msgbuf[0] = msgin_code; 1708 1.1 tsutsui 1709 1.7 tsutsui sc->sc_msgcnt = 1; 1710 1.1 tsutsui /* extended message length (n) */ 1711 1.7 tsutsui sc->sc_msg = &sc->sc_msgbuf[1]; 1712 1.1 tsutsui 1713 1.7 tsutsui break; 1714 1.7 tsutsui case MSG_MESSAGE_REJECT: 1715 1.1 tsutsui /* Reject message */ 1716 1.7 tsutsui srb = sc->sc_actsrb; 1717 1.7 tsutsui if (srb == NULL) { 1718 1.7 tsutsui DPRINTF(("trm_msgin_phase0: " 1719 1.7 tsutsui " message reject without actsrb\n")); 1720 1.7 tsutsui break; 1721 1.7 tsutsui } 1722 1.7 tsutsui periph = srb->xs->xs_periph; 1723 1.7 tsutsui ti = &sc->sc_tinfo[periph->periph_target]; 1724 1.7 tsutsui 1725 1.7 tsutsui if (ti->flag & WIDE_NEGO_ENABLE) { 1726 1.7 tsutsui /* do wide nego reject */ 1727 1.7 tsutsui ti->flag |= WIDE_NEGO_DONE; 1728 1.7 tsutsui ti->flag &= 1729 1.7 tsutsui ~(SYNC_NEGO_DONE | WIDE_NEGO_ENABLE); 1730 1.7 tsutsui if ((ti->flag & SYNC_NEGO_ENABLE) && 1731 1.7 tsutsui (ti->flag & SYNC_NEGO_DONE) == 0) { 1732 1.1 tsutsui /* Set ATN, in case ATN was clear */ 1733 1.7 tsutsui sc->sc_state = TRM_MSGOUT; 1734 1.1 tsutsui bus_space_write_2(iot, ioh, 1735 1.1 tsutsui TRM_SCSI_CONTROL, DO_SETATN); 1736 1.1 tsutsui } else 1737 1.1 tsutsui /* Clear ATN */ 1738 1.1 tsutsui bus_space_write_2(iot, ioh, 1739 1.1 tsutsui TRM_SCSI_CONTROL, DO_CLRATN); 1740 1.7 tsutsui } else if (ti->flag & SYNC_NEGO_ENABLE) { 1741 1.1 tsutsui /* do sync nego reject */ 1742 1.1 tsutsui bus_space_write_2(iot, ioh, 1743 1.1 tsutsui TRM_SCSI_CONTROL, DO_CLRATN); 1744 1.7 tsutsui if (ti->flag & SYNC_NEGO_DOING) { 1745 1.7 tsutsui ti->flag &=~(SYNC_NEGO_ENABLE | 1746 1.1 tsutsui SYNC_NEGO_DONE); 1747 1.7 tsutsui ti->synctl = 0; 1748 1.7 tsutsui ti->offset = 0; 1749 1.7 tsutsui bus_space_write_1(iot, ioh, 1750 1.7 tsutsui TRM_SCSI_SYNC, ti->synctl); 1751 1.7 tsutsui bus_space_write_1(iot, ioh, 1752 1.7 tsutsui TRM_SCSI_OFFSET, ti->offset); 1753 1.1 tsutsui } 1754 1.1 tsutsui } 1755 1.7 tsutsui break; 1756 1.7 tsutsui 1757 1.7 tsutsui case MSG_IGN_WIDE_RESIDUE: 1758 1.1 tsutsui bus_space_write_4(iot, ioh, TRM_SCSI_XCNT, 1); 1759 1.23 christos (void)bus_space_read_1(iot, ioh, TRM_SCSI_FIFO); 1760 1.7 tsutsui break; 1761 1.7 tsutsui 1762 1.7 tsutsui default: 1763 1.1 tsutsui /* 1764 1.1 tsutsui * Restore data pointer message 1765 1.1 tsutsui * Save data pointer message 1766 1.1 tsutsui * Completion message 1767 1.1 tsutsui * NOP message 1768 1.1 tsutsui */ 1769 1.7 tsutsui break; 1770 1.1 tsutsui } 1771 1.1 tsutsui } else { 1772 1.1 tsutsui /* 1773 1.7 tsutsui * when extend message in: sc->sc_state = TRM_EXTEND_MSGIN 1774 1.44 andvar * Parsing incoming extended messages 1775 1.1 tsutsui */ 1776 1.7 tsutsui *sc->sc_msg++ = msgin_code; 1777 1.7 tsutsui sc->sc_msgcnt++; 1778 1.7 tsutsui 1779 1.7 tsutsui DPRINTF(("extended_msgin: cnt = %d, ", sc->sc_msgcnt)); 1780 1.7 tsutsui DPRINTF(("msgbuf = %02x %02x %02x %02x %02x %02x\n", 1781 1.7 tsutsui sc->sc_msgbuf[0], sc->sc_msgbuf[1], sc->sc_msgbuf[2], 1782 1.7 tsutsui sc->sc_msgbuf[3], sc->sc_msgbuf[4], sc->sc_msgbuf[5])); 1783 1.7 tsutsui 1784 1.7 tsutsui switch (sc->sc_msgbuf[0]) { 1785 1.7 tsutsui case MSG_SIMPLE_Q_TAG: 1786 1.7 tsutsui case MSG_HEAD_OF_Q_TAG: 1787 1.7 tsutsui case MSG_ORDERED_Q_TAG: 1788 1.1 tsutsui /* 1789 1.1 tsutsui * is QUEUE tag message : 1790 1.1 tsutsui * 1791 1.1 tsutsui * byte 0: 1792 1.1 tsutsui * HEAD QUEUE TAG (20h) 1793 1.1 tsutsui * ORDERED QUEUE TAG (21h) 1794 1.1 tsutsui * SIMPLE QUEUE TAG (22h) 1795 1.1 tsutsui * byte 1: 1796 1.1 tsutsui * Queue tag (00h - FFh) 1797 1.1 tsutsui */ 1798 1.7 tsutsui if (sc->sc_msgcnt == 2 && sc->sc_actsrb == NULL) { 1799 1.7 tsutsui /* XXX XXX XXX */ 1800 1.7 tsutsui struct trm_linfo *li; 1801 1.7 tsutsui int tagid; 1802 1.7 tsutsui 1803 1.7 tsutsui sc->sc_flag &= ~WAIT_TAGMSG; 1804 1.7 tsutsui tagid = sc->sc_msgbuf[1]; 1805 1.7 tsutsui ti = &sc->sc_tinfo[sc->resel_target]; 1806 1.7 tsutsui li = ti->linfo[sc->resel_lun]; 1807 1.7 tsutsui srb = li->queued[tagid]; 1808 1.7 tsutsui if (srb != NULL) { 1809 1.7 tsutsui sc->sc_actsrb = srb; 1810 1.7 tsutsui sc->sc_state = TRM_DATA_XFER; 1811 1.7 tsutsui break; 1812 1.1 tsutsui } else { 1813 1.29 tsutsui printf("%s: invalid tag id\n", 1814 1.29 tsutsui device_xname(sc->sc_dev)); 1815 1.1 tsutsui } 1816 1.7 tsutsui 1817 1.7 tsutsui sc->sc_state = TRM_UNEXPECT_RESEL; 1818 1.7 tsutsui sc->sc_msgbuf[0] = MSG_ABORT_TAG; 1819 1.7 tsutsui sc->sc_msgcnt = 1; 1820 1.1 tsutsui bus_space_write_2(iot, ioh, 1821 1.1 tsutsui TRM_SCSI_CONTROL, DO_SETATN); 1822 1.7 tsutsui } else 1823 1.7 tsutsui sc->sc_state = TRM_IDLE; 1824 1.7 tsutsui break; 1825 1.7 tsutsui 1826 1.7 tsutsui case MSG_EXTENDED: 1827 1.7 tsutsui srb = sc->sc_actsrb; 1828 1.7 tsutsui if (srb == NULL) { 1829 1.7 tsutsui DPRINTF(("trm_msgin_phase0: " 1830 1.7 tsutsui "extended message without actsrb\n")); 1831 1.7 tsutsui break; 1832 1.1 tsutsui } 1833 1.7 tsutsui periph = srb->xs->xs_periph; 1834 1.7 tsutsui ti = &sc->sc_tinfo[periph->periph_target]; 1835 1.7 tsutsui 1836 1.7 tsutsui if (sc->sc_msgbuf[2] == MSG_EXT_WDTR && 1837 1.7 tsutsui sc->sc_msgcnt == 4) { 1838 1.7 tsutsui /* 1839 1.7 tsutsui * is Wide data xfer Extended message : 1840 1.7 tsutsui * ====================================== 1841 1.7 tsutsui * WIDE DATA TRANSFER REQUEST 1842 1.7 tsutsui * ====================================== 1843 1.7 tsutsui * byte 0 : Extended message (01h) 1844 1.7 tsutsui * byte 1 : Extended message length (02h) 1845 1.7 tsutsui * byte 2 : WIDE DATA TRANSFER code (03h) 1846 1.7 tsutsui * byte 3 : Transfer width exponent 1847 1.7 tsutsui */ 1848 1.7 tsutsui if (sc->sc_msgbuf[1] != MSG_EXT_WDTR_LEN) { 1849 1.7 tsutsui /* Length is wrong, reject it */ 1850 1.7 tsutsui ti->flag &= ~(WIDE_NEGO_ENABLE | 1851 1.7 tsutsui WIDE_NEGO_DONE); 1852 1.7 tsutsui sc->sc_state = TRM_MSGOUT; 1853 1.7 tsutsui sc->sc_msgbuf[0] = MSG_MESSAGE_REJECT; 1854 1.7 tsutsui sc->sc_msgcnt = 1; 1855 1.7 tsutsui bus_space_write_2(iot, ioh, 1856 1.7 tsutsui TRM_SCSI_CONTROL, DO_SETATN); 1857 1.7 tsutsui break; 1858 1.7 tsutsui } 1859 1.7 tsutsui 1860 1.7 tsutsui if ((ti->flag & WIDE_NEGO_ENABLE) == 0) 1861 1.7 tsutsui sc->sc_msgbuf[3] = 1862 1.7 tsutsui MSG_EXT_WDTR_BUS_8_BIT; 1863 1.7 tsutsui 1864 1.7 tsutsui if (sc->sc_msgbuf[3] > 1865 1.7 tsutsui MSG_EXT_WDTR_BUS_32_BIT) { 1866 1.1 tsutsui /* reject_msg: */ 1867 1.7 tsutsui ti->flag &= ~(WIDE_NEGO_ENABLE | 1868 1.1 tsutsui WIDE_NEGO_DONE); 1869 1.7 tsutsui sc->sc_state = TRM_MSGOUT; 1870 1.7 tsutsui sc->sc_msgbuf[0] = MSG_MESSAGE_REJECT; 1871 1.7 tsutsui sc->sc_msgcnt = 1; 1872 1.1 tsutsui bus_space_write_2(iot, ioh, 1873 1.1 tsutsui TRM_SCSI_CONTROL, DO_SETATN); 1874 1.7 tsutsui break; 1875 1.1 tsutsui } 1876 1.7 tsutsui if (sc->sc_msgbuf[3] == MSG_EXT_WDTR_BUS_32_BIT) 1877 1.1 tsutsui /* do 16 bits */ 1878 1.7 tsutsui sc->sc_msgbuf[3] = 1879 1.7 tsutsui MSG_EXT_WDTR_BUS_16_BIT; 1880 1.7 tsutsui if ((ti->flag & WIDE_NEGO_DONE) == 0) { 1881 1.7 tsutsui ti->flag |= WIDE_NEGO_DONE; 1882 1.7 tsutsui ti->flag &= ~(SYNC_NEGO_DONE | 1883 1.7 tsutsui WIDE_NEGO_ENABLE); 1884 1.7 tsutsui if (sc->sc_msgbuf[3] != 1885 1.7 tsutsui MSG_EXT_WDTR_BUS_8_BIT) 1886 1.7 tsutsui /* is Wide data xfer */ 1887 1.7 tsutsui ti->synctl |= WIDE_SYNC; 1888 1.7 tsutsui trm_update_xfer_mode(sc, 1889 1.7 tsutsui periph->periph_target); 1890 1.1 tsutsui } 1891 1.1 tsutsui 1892 1.7 tsutsui sc->sc_state = TRM_MSGOUT; 1893 1.1 tsutsui bus_space_write_2(iot, ioh, TRM_SCSI_CONTROL, 1894 1.1 tsutsui DO_SETATN); 1895 1.7 tsutsui break; 1896 1.1 tsutsui 1897 1.7 tsutsui } else if (sc->sc_msgbuf[2] == MSG_EXT_SDTR && 1898 1.7 tsutsui sc->sc_msgcnt == 5) { 1899 1.1 tsutsui /* 1900 1.7 tsutsui * is 8bit transfer Extended message : 1901 1.7 tsutsui * ================================= 1902 1.7 tsutsui * SYNCHRONOUS DATA TRANSFER REQUEST 1903 1.7 tsutsui * ================================= 1904 1.7 tsutsui * byte 0 : Extended message (01h) 1905 1.7 tsutsui * byte 1 : Extended message length (03) 1906 1.7 tsutsui * byte 2 : SYNC DATA TRANSFER code (01h) 1907 1.7 tsutsui * byte 3 : Transfer period factor 1908 1.7 tsutsui * byte 4 : REQ/ACK offset 1909 1.1 tsutsui */ 1910 1.7 tsutsui if (sc->sc_msgbuf[1] != MSG_EXT_SDTR_LEN) { 1911 1.7 tsutsui /* reject_msg */ 1912 1.7 tsutsui sc->sc_state = TRM_MSGOUT; 1913 1.7 tsutsui sc->sc_msgbuf[0] = MSG_MESSAGE_REJECT; 1914 1.7 tsutsui sc->sc_msgcnt = 1; 1915 1.7 tsutsui bus_space_write_2(iot, ioh, 1916 1.7 tsutsui TRM_SCSI_CONTROL, DO_SETATN); 1917 1.7 tsutsui break; 1918 1.7 tsutsui } 1919 1.7 tsutsui 1920 1.7 tsutsui if ((ti->flag & SYNC_NEGO_DONE) == 0) { 1921 1.7 tsutsui ti->flag &= 1922 1.7 tsutsui ~(SYNC_NEGO_ENABLE|SYNC_NEGO_DOING); 1923 1.7 tsutsui ti->flag |= SYNC_NEGO_DONE; 1924 1.7 tsutsui if (sc->sc_msgbuf[3] >= TRM_MAX_PERIOD) 1925 1.7 tsutsui sc->sc_msgbuf[3] = 0; 1926 1.7 tsutsui if (sc->sc_msgbuf[4] > TRM_MAX_OFFSET) 1927 1.7 tsutsui sc->sc_msgbuf[4] = 1928 1.7 tsutsui TRM_MAX_OFFSET; 1929 1.7 tsutsui 1930 1.7 tsutsui if (sc->sc_msgbuf[3] == 0 || 1931 1.7 tsutsui sc->sc_msgbuf[4] == 0) { 1932 1.7 tsutsui /* set async */ 1933 1.7 tsutsui ti->synctl = 0; 1934 1.7 tsutsui ti->offset = 0; 1935 1.7 tsutsui } else { 1936 1.7 tsutsui /* set sync */ 1937 1.7 tsutsui /* Transfer period factor */ 1938 1.7 tsutsui ti->period = sc->sc_msgbuf[3]; 1939 1.7 tsutsui /* REQ/ACK offset */ 1940 1.7 tsutsui ti->offset = sc->sc_msgbuf[4]; 1941 1.7 tsutsui for (index = 0; 1942 1.7 tsutsui index < NPERIOD; 1943 1.7 tsutsui index++) 1944 1.7 tsutsui if (ti->period <= 1945 1.7 tsutsui trm_clock_period[ 1946 1.7 tsutsui index]) 1947 1.7 tsutsui break; 1948 1.7 tsutsui 1949 1.7 tsutsui ti->synctl |= ALT_SYNC | index; 1950 1.7 tsutsui } 1951 1.7 tsutsui /* 1952 1.7 tsutsui * program SCSI control register 1953 1.7 tsutsui */ 1954 1.7 tsutsui bus_space_write_1(iot, ioh, 1955 1.7 tsutsui TRM_SCSI_SYNC, ti->synctl); 1956 1.7 tsutsui bus_space_write_1(iot, ioh, 1957 1.7 tsutsui TRM_SCSI_OFFSET, ti->offset); 1958 1.7 tsutsui trm_update_xfer_mode(sc, 1959 1.7 tsutsui periph->periph_target); 1960 1.1 tsutsui } 1961 1.7 tsutsui sc->sc_state = TRM_IDLE; 1962 1.1 tsutsui } 1963 1.7 tsutsui break; 1964 1.7 tsutsui default: 1965 1.7 tsutsui break; 1966 1.1 tsutsui } 1967 1.1 tsutsui } 1968 1.7 tsutsui 1969 1.1 tsutsui /* it's important for atn stop */ 1970 1.1 tsutsui bus_space_write_2(iot, ioh, TRM_SCSI_CONTROL, DO_DATALATCH); 1971 1.1 tsutsui 1972 1.1 tsutsui /* 1973 1.8 wiz * SCSI command 1974 1.1 tsutsui */ 1975 1.1 tsutsui bus_space_write_1(iot, ioh, TRM_SCSI_COMMAND, SCMD_MSGACCEPT); 1976 1.1 tsutsui } 1977 1.1 tsutsui 1978 1.1 tsutsui static void 1979 1.15 tsutsui trm_msgin_phase1(struct trm_softc *sc) 1980 1.1 tsutsui { 1981 1.1 tsutsui bus_space_tag_t iot = sc->sc_iot; 1982 1.1 tsutsui bus_space_handle_t ioh = sc->sc_ioh; 1983 1.1 tsutsui 1984 1.1 tsutsui bus_space_write_2(iot, ioh, TRM_SCSI_CONTROL, DO_CLRFIFO); 1985 1.1 tsutsui bus_space_write_4(iot, ioh, TRM_SCSI_XCNT, 1); 1986 1.7 tsutsui if (sc->sc_state != TRM_MSGIN && sc->sc_state != TRM_EXTEND_MSGIN) { 1987 1.7 tsutsui sc->sc_state = TRM_MSGIN; 1988 1.1 tsutsui } 1989 1.7 tsutsui 1990 1.1 tsutsui /* it's important for atn stop */ 1991 1.18 perry bus_space_write_2(iot, ioh, TRM_SCSI_CONTROL, DO_DATALATCH); 1992 1.1 tsutsui 1993 1.1 tsutsui /* 1994 1.8 wiz * SCSI command 1995 1.1 tsutsui */ 1996 1.1 tsutsui bus_space_write_1(iot, ioh, TRM_SCSI_COMMAND, SCMD_FIFO_IN); 1997 1.1 tsutsui } 1998 1.1 tsutsui 1999 1.1 tsutsui static void 2000 1.15 tsutsui trm_disconnect(struct trm_softc *sc) 2001 1.1 tsutsui { 2002 1.1 tsutsui bus_space_tag_t iot = sc->sc_iot; 2003 1.1 tsutsui bus_space_handle_t ioh = sc->sc_ioh; 2004 1.7 tsutsui struct trm_srb *srb; 2005 1.7 tsutsui int s; 2006 1.1 tsutsui 2007 1.1 tsutsui s = splbio(); 2008 1.1 tsutsui 2009 1.7 tsutsui srb = sc->sc_actsrb; 2010 1.7 tsutsui DPRINTF(("trm_disconnect...............\n")); 2011 1.7 tsutsui 2012 1.7 tsutsui if (srb == NULL) { 2013 1.7 tsutsui DPRINTF(("trm_disconnect: no active srb\n")); 2014 1.1 tsutsui DELAY(1000); /* 1 msec */ 2015 1.1 tsutsui 2016 1.1 tsutsui bus_space_write_2(iot, ioh, TRM_SCSI_CONTROL, 2017 1.1 tsutsui DO_CLRFIFO | DO_HWRESELECT); 2018 1.1 tsutsui return; 2019 1.1 tsutsui } 2020 1.7 tsutsui sc->sc_phase = PH_BUS_FREE; /* SCSI bus free Phase */ 2021 1.1 tsutsui bus_space_write_2(iot, ioh, TRM_SCSI_CONTROL, 2022 1.1 tsutsui DO_CLRFIFO | DO_HWRESELECT); 2023 1.1 tsutsui DELAY(100); 2024 1.7 tsutsui 2025 1.7 tsutsui switch (sc->sc_state) { 2026 1.7 tsutsui case TRM_UNEXPECT_RESEL: 2027 1.7 tsutsui sc->sc_state = TRM_IDLE; 2028 1.7 tsutsui break; 2029 1.7 tsutsui 2030 1.7 tsutsui case TRM_ABORT_SENT: 2031 1.7 tsutsui goto finish; 2032 1.7 tsutsui 2033 1.7 tsutsui case TRM_START: 2034 1.7 tsutsui case TRM_MSGOUT: 2035 1.7 tsutsui { 2036 1.7 tsutsui /* Selection time out - discard all LUNs if empty */ 2037 1.7 tsutsui struct scsipi_periph *periph; 2038 1.7 tsutsui struct trm_tinfo *ti; 2039 1.7 tsutsui struct trm_linfo *li; 2040 1.7 tsutsui int lun; 2041 1.7 tsutsui 2042 1.7 tsutsui DPRINTF(("selection timeout\n")); 2043 1.7 tsutsui 2044 1.7 tsutsui srb->tastat = SCSI_SEL_TIMEOUT; /* XXX Ok? */ 2045 1.7 tsutsui 2046 1.7 tsutsui periph = srb->xs->xs_periph; 2047 1.7 tsutsui ti = &sc->sc_tinfo[periph->periph_target]; 2048 1.7 tsutsui for (lun = 0; lun < TRM_MAX_LUNS; lun++) { 2049 1.7 tsutsui li = ti->linfo[lun]; 2050 1.7 tsutsui if (li != NULL && 2051 1.7 tsutsui li->untagged == NULL && li->used == 0) { 2052 1.7 tsutsui ti->linfo[lun] = NULL; 2053 1.7 tsutsui free(li, M_DEVBUF); 2054 1.7 tsutsui } 2055 1.1 tsutsui } 2056 1.1 tsutsui } 2057 1.7 tsutsui goto finish; 2058 1.7 tsutsui 2059 1.7 tsutsui case TRM_DISCONNECTED: 2060 1.7 tsutsui sc->sc_actsrb = NULL; 2061 1.7 tsutsui sc->sc_state = TRM_IDLE; 2062 1.7 tsutsui goto sched; 2063 1.7 tsutsui 2064 1.7 tsutsui case TRM_COMPLETED: 2065 1.7 tsutsui goto finish; 2066 1.1 tsutsui } 2067 1.7 tsutsui 2068 1.7 tsutsui out: 2069 1.1 tsutsui splx(s); 2070 1.7 tsutsui return; 2071 1.7 tsutsui 2072 1.7 tsutsui finish: 2073 1.7 tsutsui sc->sc_state = TRM_IDLE; 2074 1.7 tsutsui trm_done(sc, srb); 2075 1.7 tsutsui goto out; 2076 1.7 tsutsui 2077 1.7 tsutsui sched: 2078 1.7 tsutsui trm_sched(sc); 2079 1.7 tsutsui goto out; 2080 1.1 tsutsui } 2081 1.1 tsutsui 2082 1.1 tsutsui static void 2083 1.15 tsutsui trm_reselect(struct trm_softc *sc) 2084 1.1 tsutsui { 2085 1.1 tsutsui bus_space_tag_t iot = sc->sc_iot; 2086 1.1 tsutsui bus_space_handle_t ioh = sc->sc_ioh; 2087 1.7 tsutsui struct trm_tinfo *ti; 2088 1.7 tsutsui struct trm_linfo *li; 2089 1.7 tsutsui int target, lun; 2090 1.7 tsutsui 2091 1.7 tsutsui DPRINTF(("trm_reselect.................\n")); 2092 1.7 tsutsui 2093 1.7 tsutsui if (sc->sc_actsrb != NULL) { 2094 1.7 tsutsui /* arbitration lost but reselection win */ 2095 1.7 tsutsui sc->sc_state = TRM_READY; 2096 1.7 tsutsui target = sc->sc_actsrb->xs->xs_periph->periph_target; 2097 1.7 tsutsui ti = &sc->sc_tinfo[target]; 2098 1.7 tsutsui } else { 2099 1.7 tsutsui /* Read Reselected Target Id and LUN */ 2100 1.7 tsutsui target = bus_space_read_1(iot, ioh, TRM_SCSI_TARGETID); 2101 1.7 tsutsui lun = bus_space_read_1(iot, ioh, TRM_SCSI_IDMSG) & 0x07; 2102 1.7 tsutsui ti = &sc->sc_tinfo[target]; 2103 1.7 tsutsui li = ti->linfo[lun]; 2104 1.7 tsutsui DPRINTF(("target = %d, lun = %d\n", target, lun)); 2105 1.7 tsutsui 2106 1.7 tsutsui /* 2107 1.7 tsutsui * Check to see if we are running an un-tagged command. 2108 1.7 tsutsui * Otherwise ack the IDENTIFY and wait for a tag message. 2109 1.7 tsutsui */ 2110 1.7 tsutsui if (li != NULL) { 2111 1.7 tsutsui if (li->untagged != NULL && li->busy) { 2112 1.7 tsutsui sc->sc_actsrb = li->untagged; 2113 1.7 tsutsui sc->sc_state = TRM_DATA_XFER; 2114 1.7 tsutsui } else { 2115 1.7 tsutsui sc->resel_target = target; 2116 1.7 tsutsui sc->resel_lun = lun; 2117 1.7 tsutsui /* XXX XXX XXX */ 2118 1.7 tsutsui sc->sc_flag |= WAIT_TAGMSG; 2119 1.7 tsutsui } 2120 1.7 tsutsui } 2121 1.1 tsutsui 2122 1.7 tsutsui if ((ti->flag & USE_TAG_QUEUING) == 0 && 2123 1.7 tsutsui sc->sc_actsrb == NULL) { 2124 1.7 tsutsui printf("%s: reselect from target %d lun %d " 2125 1.7 tsutsui "without nexus; sending abort\n", 2126 1.29 tsutsui device_xname(sc->sc_dev), target, lun); 2127 1.7 tsutsui sc->sc_state = TRM_UNEXPECT_RESEL; 2128 1.7 tsutsui sc->sc_msgbuf[0] = MSG_ABORT_TAG; 2129 1.7 tsutsui sc->sc_msgcnt = 1; 2130 1.7 tsutsui bus_space_write_2(iot, ioh, 2131 1.7 tsutsui TRM_SCSI_CONTROL, DO_SETATN); 2132 1.1 tsutsui } 2133 1.1 tsutsui } 2134 1.7 tsutsui sc->sc_phase = PH_BUS_FREE; /* SCSI bus free Phase */ 2135 1.1 tsutsui /* 2136 1.1 tsutsui * Program HA ID, target ID, period and offset 2137 1.1 tsutsui */ 2138 1.1 tsutsui /* target ID */ 2139 1.7 tsutsui bus_space_write_1(iot, ioh, TRM_SCSI_TARGETID, target); 2140 1.1 tsutsui 2141 1.1 tsutsui /* host ID */ 2142 1.1 tsutsui bus_space_write_1(iot, ioh, TRM_SCSI_HOSTID, sc->sc_id); 2143 1.1 tsutsui 2144 1.1 tsutsui /* period */ 2145 1.7 tsutsui bus_space_write_1(iot, ioh, TRM_SCSI_SYNC, ti->synctl); 2146 1.1 tsutsui 2147 1.1 tsutsui /* offset */ 2148 1.7 tsutsui bus_space_write_1(iot, ioh, TRM_SCSI_OFFSET, ti->offset); 2149 1.1 tsutsui 2150 1.1 tsutsui /* it's important for atn stop */ 2151 1.1 tsutsui bus_space_write_2(iot, ioh, TRM_SCSI_CONTROL, DO_DATALATCH); 2152 1.1 tsutsui /* 2153 1.8 wiz * SCSI command 2154 1.1 tsutsui */ 2155 1.1 tsutsui /* to rls the /ACK signal */ 2156 1.1 tsutsui bus_space_write_1(iot, ioh, TRM_SCSI_COMMAND, SCMD_MSGACCEPT); 2157 1.1 tsutsui } 2158 1.1 tsutsui 2159 1.1 tsutsui /* 2160 1.1 tsutsui * Complete execution of a SCSI command 2161 1.1 tsutsui * Signal completion to the generic SCSI driver 2162 1.1 tsutsui */ 2163 1.1 tsutsui static void 2164 1.15 tsutsui trm_done(struct trm_softc *sc, struct trm_srb *srb) 2165 1.1 tsutsui { 2166 1.1 tsutsui struct scsipi_xfer *xs = srb->xs; 2167 1.1 tsutsui 2168 1.7 tsutsui DPRINTF(("trm_done..................\n")); 2169 1.1 tsutsui 2170 1.1 tsutsui if (xs == NULL) 2171 1.1 tsutsui return; 2172 1.1 tsutsui 2173 1.5 tsutsui if ((xs->xs_control & XS_CTL_POLL) == 0) 2174 1.5 tsutsui callout_stop(&xs->xs_callout); 2175 1.1 tsutsui 2176 1.5 tsutsui if (xs->xs_control & (XS_CTL_DATA_IN | XS_CTL_DATA_OUT) || 2177 1.5 tsutsui srb->flag & AUTO_REQSENSE) { 2178 1.5 tsutsui bus_dmamap_sync(sc->sc_dmat, srb->dmap, 0, 2179 1.5 tsutsui srb->dmap->dm_mapsize, 2180 1.5 tsutsui ((xs->xs_control & XS_CTL_DATA_IN) || 2181 1.5 tsutsui (srb->flag & AUTO_REQSENSE)) ? 2182 1.5 tsutsui BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE); 2183 1.5 tsutsui bus_dmamap_unload(sc->sc_dmat, srb->dmap); 2184 1.5 tsutsui } 2185 1.1 tsutsui 2186 1.1 tsutsui /* 2187 1.1 tsutsui * target status 2188 1.1 tsutsui */ 2189 1.5 tsutsui xs->status = srb->tastat; 2190 1.5 tsutsui 2191 1.7 tsutsui DPRINTF(("xs->status = 0x%02x\n", xs->status)); 2192 1.7 tsutsui 2193 1.5 tsutsui switch (xs->status) { 2194 1.5 tsutsui case SCSI_OK: 2195 1.1 tsutsui /* 2196 1.1 tsutsui * process initiator status...... 2197 1.1 tsutsui * Adapter (initiator) status 2198 1.1 tsutsui */ 2199 1.7 tsutsui if ((srb->hastat & H_OVER_UNDER_RUN) != 0) { 2200 1.7 tsutsui printf("%s: over/under run error\n", 2201 1.29 tsutsui device_xname(sc->sc_dev)); 2202 1.1 tsutsui srb->tastat = 0; 2203 1.1 tsutsui /* Illegal length (over/under run) */ 2204 1.1 tsutsui xs->error = XS_DRIVER_STUFFUP; 2205 1.7 tsutsui } else if ((srb->flag & PARITY_ERROR) != 0) { 2206 1.29 tsutsui printf("%s: parity error\n", device_xname(sc->sc_dev)); 2207 1.1 tsutsui /* Driver failed to perform operation */ 2208 1.7 tsutsui xs->error = XS_DRIVER_STUFFUP; /* XXX */ 2209 1.7 tsutsui } else if ((srb->flag & SRB_TIMEOUT) != 0) { 2210 1.7 tsutsui xs->resid = srb->buflen; 2211 1.7 tsutsui xs->error = XS_TIMEOUT; 2212 1.5 tsutsui } else { 2213 1.5 tsutsui /* No error */ 2214 1.7 tsutsui xs->resid = srb->buflen; 2215 1.1 tsutsui srb->hastat = 0; 2216 1.5 tsutsui if (srb->flag & AUTO_REQSENSE) { 2217 1.5 tsutsui /* there is no error, (sense is invalid) */ 2218 1.5 tsutsui xs->error = XS_SENSE; 2219 1.5 tsutsui } else { 2220 1.5 tsutsui srb->tastat = 0; 2221 1.5 tsutsui xs->error = XS_NOERROR; 2222 1.5 tsutsui } 2223 1.5 tsutsui } 2224 1.5 tsutsui break; 2225 1.7 tsutsui 2226 1.5 tsutsui case SCSI_CHECK: 2227 1.5 tsutsui if ((srb->flag & AUTO_REQSENSE) != 0 || 2228 1.7 tsutsui trm_request_sense(sc, srb) != 0) { 2229 1.29 tsutsui printf("%s: request sense failed\n", 2230 1.29 tsutsui device_xname(sc->sc_dev)); 2231 1.5 tsutsui xs->error = XS_DRIVER_STUFFUP; 2232 1.5 tsutsui break; 2233 1.1 tsutsui } 2234 1.5 tsutsui xs->error = XS_SENSE; 2235 1.5 tsutsui return; 2236 1.7 tsutsui 2237 1.5 tsutsui case SCSI_SEL_TIMEOUT: 2238 1.5 tsutsui srb->hastat = H_SEL_TIMEOUT; 2239 1.5 tsutsui srb->tastat = 0; 2240 1.7 tsutsui xs->error = XS_SELTIMEOUT; 2241 1.5 tsutsui break; 2242 1.7 tsutsui 2243 1.7 tsutsui case SCSI_QUEUE_FULL: 2244 1.5 tsutsui case SCSI_BUSY: 2245 1.5 tsutsui xs->error = XS_BUSY; 2246 1.5 tsutsui break; 2247 1.7 tsutsui 2248 1.5 tsutsui case SCSI_RESV_CONFLICT: 2249 1.29 tsutsui DPRINTF(("%s: target reserved at ", device_xname(sc->sc_dev))); 2250 1.7 tsutsui DPRINTF(("%s %d\n", __FILE__, __LINE__)); 2251 1.5 tsutsui xs->error = XS_BUSY; 2252 1.5 tsutsui break; 2253 1.7 tsutsui 2254 1.5 tsutsui default: 2255 1.5 tsutsui srb->hastat = 0; 2256 1.7 tsutsui printf("%s: trm_done(): unknown status = %02x\n", 2257 1.29 tsutsui device_xname(sc->sc_dev), xs->status); 2258 1.5 tsutsui xs->error = XS_DRIVER_STUFFUP; 2259 1.5 tsutsui break; 2260 1.1 tsutsui } 2261 1.5 tsutsui 2262 1.7 tsutsui trm_dequeue(sc, srb); 2263 1.7 tsutsui if (srb == sc->sc_actsrb) { 2264 1.7 tsutsui sc->sc_actsrb = NULL; 2265 1.7 tsutsui trm_sched(sc); 2266 1.7 tsutsui } 2267 1.1 tsutsui 2268 1.7 tsutsui TAILQ_INSERT_TAIL(&sc->sc_freesrb, srb, next); 2269 1.5 tsutsui 2270 1.1 tsutsui /* Notify cmd done */ 2271 1.1 tsutsui scsipi_done(xs); 2272 1.1 tsutsui } 2273 1.1 tsutsui 2274 1.7 tsutsui static int 2275 1.15 tsutsui trm_request_sense(struct trm_softc *sc, struct trm_srb *srb) 2276 1.1 tsutsui { 2277 1.1 tsutsui struct scsipi_xfer *xs; 2278 1.7 tsutsui struct scsipi_periph *periph; 2279 1.7 tsutsui struct trm_tinfo *ti; 2280 1.7 tsutsui struct trm_linfo *li; 2281 1.17 thorpej struct scsi_request_sense *ss = (struct scsi_request_sense *)srb->cmd; 2282 1.7 tsutsui int error; 2283 1.1 tsutsui 2284 1.7 tsutsui DPRINTF(("trm_request_sense...\n")); 2285 1.1 tsutsui 2286 1.7 tsutsui xs = srb->xs; 2287 1.7 tsutsui periph = xs->xs_periph; 2288 1.1 tsutsui 2289 1.1 tsutsui srb->flag |= AUTO_REQSENSE; 2290 1.1 tsutsui 2291 1.1 tsutsui /* Status of initiator/target */ 2292 1.1 tsutsui srb->hastat = 0; 2293 1.1 tsutsui srb->tastat = 0; 2294 1.1 tsutsui 2295 1.17 thorpej memset(ss, 0, sizeof(*ss)); 2296 1.17 thorpej ss->opcode = SCSI_REQUEST_SENSE; 2297 1.7 tsutsui ss->byte2 = periph->periph_lun << SCSI_CMD_LUN_SHIFT; 2298 1.17 thorpej ss->length = sizeof(struct scsi_sense_data); 2299 1.1 tsutsui 2300 1.17 thorpej srb->buflen = sizeof(struct scsi_sense_data); 2301 1.1 tsutsui srb->sgcnt = 1; 2302 1.1 tsutsui srb->sgindex = 0; 2303 1.17 thorpej srb->cmdlen = sizeof(struct scsi_request_sense); 2304 1.1 tsutsui 2305 1.1 tsutsui if ((error = bus_dmamap_load(sc->sc_dmat, srb->dmap, 2306 1.1 tsutsui &xs->sense.scsi_sense, srb->buflen, NULL, 2307 1.1 tsutsui BUS_DMA_READ|BUS_DMA_NOWAIT)) != 0) { 2308 1.5 tsutsui return error; 2309 1.1 tsutsui } 2310 1.1 tsutsui bus_dmamap_sync(sc->sc_dmat, srb->dmap, 0, 2311 1.1 tsutsui srb->buflen, BUS_DMASYNC_PREREAD); 2312 1.1 tsutsui 2313 1.1 tsutsui srb->sgentry[0].address = htole32(srb->dmap->dm_segs[0].ds_addr); 2314 1.17 thorpej srb->sgentry[0].length = htole32(sizeof(struct scsi_sense_data)); 2315 1.1 tsutsui bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap, srb->sgoffset, 2316 1.1 tsutsui TRM_SG_SIZE, BUS_DMASYNC_PREWRITE); 2317 1.1 tsutsui 2318 1.7 tsutsui ti = &sc->sc_tinfo[periph->periph_target]; 2319 1.7 tsutsui li = ti->linfo[periph->periph_lun]; 2320 1.7 tsutsui if (li->busy > 0) 2321 1.7 tsutsui li->busy = 0; 2322 1.7 tsutsui trm_dequeue(sc, srb); 2323 1.7 tsutsui li->untagged = srb; /* must be executed first to fix C/A */ 2324 1.7 tsutsui li->busy = 2; 2325 1.7 tsutsui 2326 1.7 tsutsui if (srb == sc->sc_actsrb) 2327 1.7 tsutsui trm_select(sc, srb); 2328 1.7 tsutsui else { 2329 1.7 tsutsui TAILQ_INSERT_HEAD(&sc->sc_readysrb, srb, next); 2330 1.7 tsutsui if (sc->sc_actsrb == NULL) 2331 1.7 tsutsui trm_sched(sc); 2332 1.7 tsutsui } 2333 1.5 tsutsui return 0; 2334 1.1 tsutsui } 2335 1.1 tsutsui 2336 1.1 tsutsui static void 2337 1.15 tsutsui trm_dequeue(struct trm_softc *sc, struct trm_srb *srb) 2338 1.1 tsutsui { 2339 1.7 tsutsui struct scsipi_periph *periph; 2340 1.7 tsutsui struct trm_tinfo *ti; 2341 1.7 tsutsui struct trm_linfo *li; 2342 1.7 tsutsui 2343 1.7 tsutsui periph = srb->xs->xs_periph; 2344 1.7 tsutsui ti = &sc->sc_tinfo[periph->periph_target]; 2345 1.7 tsutsui li = ti->linfo[periph->periph_lun]; 2346 1.1 tsutsui 2347 1.7 tsutsui if (li->untagged == srb) { 2348 1.7 tsutsui li->busy = 0; 2349 1.7 tsutsui li->untagged = NULL; 2350 1.7 tsutsui } 2351 1.7 tsutsui if (srb->tag[0] != 0 && li->queued[srb->tag[1]] != NULL) { 2352 1.7 tsutsui li->queued[srb->tag[1]] = NULL; 2353 1.7 tsutsui li->used--; 2354 1.7 tsutsui } 2355 1.1 tsutsui } 2356 1.1 tsutsui 2357 1.1 tsutsui static void 2358 1.15 tsutsui trm_reset_scsi_bus(struct trm_softc *sc) 2359 1.1 tsutsui { 2360 1.7 tsutsui bus_space_tag_t iot = sc->sc_iot; 2361 1.7 tsutsui bus_space_handle_t ioh = sc->sc_ioh; 2362 1.7 tsutsui int timeout, s; 2363 1.1 tsutsui 2364 1.7 tsutsui DPRINTF(("trm_reset_scsi_bus.........\n")); 2365 1.1 tsutsui 2366 1.1 tsutsui s = splbio(); 2367 1.7 tsutsui 2368 1.7 tsutsui sc->sc_flag |= RESET_DEV; 2369 1.7 tsutsui bus_space_write_2(iot, ioh, TRM_SCSI_CONTROL, DO_RSTSCSI); 2370 1.7 tsutsui for (timeout = 20000; timeout >= 0; timeout--) { 2371 1.7 tsutsui DELAY(1); 2372 1.7 tsutsui if ((bus_space_read_2(iot, ioh, TRM_SCSI_INTSTATUS) & 2373 1.7 tsutsui INT_SCSIRESET) == 0) 2374 1.7 tsutsui break; 2375 1.1 tsutsui } 2376 1.7 tsutsui if (timeout == 0) 2377 1.7 tsutsui printf(": scsibus reset timeout\n"); 2378 1.18 perry 2379 1.1 tsutsui splx(s); 2380 1.1 tsutsui } 2381 1.1 tsutsui 2382 1.1 tsutsui static void 2383 1.15 tsutsui trm_scsi_reset_detect(struct trm_softc *sc) 2384 1.1 tsutsui { 2385 1.7 tsutsui bus_space_tag_t iot = sc->sc_iot; 2386 1.7 tsutsui bus_space_handle_t ioh = sc->sc_ioh; 2387 1.7 tsutsui int s; 2388 1.7 tsutsui 2389 1.7 tsutsui DPRINTF(("trm_scsi_reset_detect...............\n")); 2390 1.7 tsutsui DELAY(1000000); /* delay 1 sec */ 2391 1.7 tsutsui 2392 1.7 tsutsui s = splbio(); 2393 1.1 tsutsui 2394 1.7 tsutsui bus_space_write_1(iot, ioh, TRM_DMA_CONTROL, STOPDMAXFER); 2395 1.7 tsutsui bus_space_write_2(iot, ioh, TRM_SCSI_CONTROL, DO_CLRFIFO); 2396 1.1 tsutsui 2397 1.7 tsutsui if (sc->sc_flag & RESET_DEV) { 2398 1.7 tsutsui sc->sc_flag |= RESET_DONE; 2399 1.7 tsutsui } else { 2400 1.7 tsutsui sc->sc_flag |= RESET_DETECT; 2401 1.7 tsutsui sc->sc_actsrb = NULL; 2402 1.7 tsutsui sc->sc_flag = 0; 2403 1.7 tsutsui trm_sched(sc); 2404 1.1 tsutsui } 2405 1.7 tsutsui splx(s); 2406 1.1 tsutsui } 2407 1.1 tsutsui 2408 1.1 tsutsui /* 2409 1.7 tsutsui * read seeprom 128 bytes to struct eeprom and check checksum. 2410 1.8 wiz * If it is wrong, update with default value. 2411 1.1 tsutsui */ 2412 1.1 tsutsui static void 2413 1.15 tsutsui trm_check_eeprom(struct trm_softc *sc, struct trm_nvram *eeprom) 2414 1.1 tsutsui { 2415 1.7 tsutsui struct nvram_target *target; 2416 1.16 tsutsui uint16_t *ep; 2417 1.16 tsutsui uint16_t chksum; 2418 1.7 tsutsui int i; 2419 1.7 tsutsui 2420 1.7 tsutsui DPRINTF(("trm_check_eeprom......\n")); 2421 1.7 tsutsui trm_eeprom_read_all(sc, eeprom); 2422 1.16 tsutsui ep = (uint16_t *)eeprom; 2423 1.7 tsutsui chksum = 0; 2424 1.7 tsutsui for (i = 0; i < 64; i++) 2425 1.7 tsutsui chksum += le16toh(*ep++); 2426 1.7 tsutsui 2427 1.7 tsutsui if (chksum != TRM_NVRAM_CKSUM) { 2428 1.7 tsutsui DPRINTF(("TRM_S1040 EEPROM Check Sum ERROR (load default).\n")); 2429 1.7 tsutsui /* 2430 1.7 tsutsui * Checksum error, load default 2431 1.7 tsutsui */ 2432 1.7 tsutsui eeprom->subvendor_id[0] = PCI_VENDOR_TEKRAM2 & 0xFF; 2433 1.7 tsutsui eeprom->subvendor_id[1] = PCI_VENDOR_TEKRAM2 >> 8; 2434 1.7 tsutsui eeprom->subsys_id[0] = PCI_PRODUCT_TEKRAM2_DC315 & 0xFF; 2435 1.7 tsutsui eeprom->subsys_id[1] = PCI_PRODUCT_TEKRAM2_DC315 >> 8; 2436 1.7 tsutsui eeprom->subclass = 0x00; 2437 1.7 tsutsui eeprom->vendor_id[0] = PCI_VENDOR_TEKRAM2 & 0xFF; 2438 1.7 tsutsui eeprom->vendor_id[1] = PCI_VENDOR_TEKRAM2 >> 8; 2439 1.7 tsutsui eeprom->device_id[0] = PCI_PRODUCT_TEKRAM2_DC315 & 0xFF; 2440 1.7 tsutsui eeprom->device_id[1] = PCI_PRODUCT_TEKRAM2_DC315 >> 8; 2441 1.7 tsutsui eeprom->reserved0 = 0x00; 2442 1.7 tsutsui 2443 1.7 tsutsui for (i = 0, target = eeprom->target; 2444 1.7 tsutsui i < TRM_MAX_TARGETS; 2445 1.7 tsutsui i++, target++) { 2446 1.7 tsutsui target->config0 = 0x77; 2447 1.7 tsutsui target->period = 0x00; 2448 1.7 tsutsui target->config2 = 0x00; 2449 1.7 tsutsui target->config3 = 0x00; 2450 1.7 tsutsui } 2451 1.1 tsutsui 2452 1.7 tsutsui eeprom->scsi_id = 7; 2453 1.7 tsutsui eeprom->channel_cfg = 0x0F; 2454 1.7 tsutsui eeprom->delay_time = 0; 2455 1.7 tsutsui eeprom->max_tag = 4; 2456 1.7 tsutsui eeprom->reserved1 = 0x15; 2457 1.7 tsutsui eeprom->boot_target = 0; 2458 1.7 tsutsui eeprom->boot_lun = 0; 2459 1.7 tsutsui eeprom->reserved2 = 0; 2460 1.7 tsutsui memset(eeprom->reserved3, 0, sizeof(eeprom->reserved3)); 2461 1.1 tsutsui 2462 1.7 tsutsui chksum = 0; 2463 1.16 tsutsui ep = (uint16_t *)eeprom; 2464 1.7 tsutsui for (i = 0; i < 63; i++) 2465 1.7 tsutsui chksum += le16toh(*ep++); 2466 1.1 tsutsui 2467 1.7 tsutsui chksum = TRM_NVRAM_CKSUM - chksum; 2468 1.7 tsutsui eeprom->checksum0 = chksum & 0xFF; 2469 1.7 tsutsui eeprom->checksum1 = chksum >> 8; 2470 1.1 tsutsui 2471 1.7 tsutsui trm_eeprom_write_all(sc, eeprom); 2472 1.7 tsutsui } 2473 1.1 tsutsui } 2474 1.1 tsutsui 2475 1.1 tsutsui /* 2476 1.7 tsutsui * write struct eeprom 128 bytes to seeprom 2477 1.1 tsutsui */ 2478 1.1 tsutsui static void 2479 1.15 tsutsui trm_eeprom_write_all(struct trm_softc *sc, struct trm_nvram *eeprom) 2480 1.1 tsutsui { 2481 1.1 tsutsui bus_space_tag_t iot = sc->sc_iot; 2482 1.1 tsutsui bus_space_handle_t ioh = sc->sc_ioh; 2483 1.20 christos uint8_t *sbuf = (uint8_t *)eeprom; 2484 1.16 tsutsui uint8_t addr; 2485 1.1 tsutsui 2486 1.1 tsutsui /* Enable SEEPROM */ 2487 1.1 tsutsui bus_space_write_1(iot, ioh, TRM_GEN_CONTROL, 2488 1.1 tsutsui bus_space_read_1(iot, ioh, TRM_GEN_CONTROL) | EN_EEPROM); 2489 1.1 tsutsui 2490 1.1 tsutsui /* 2491 1.1 tsutsui * Write enable 2492 1.1 tsutsui */ 2493 1.1 tsutsui trm_eeprom_write_cmd(sc, 0x04, 0xFF); 2494 1.1 tsutsui bus_space_write_1(iot, ioh, TRM_GEN_NVRAM, 0); 2495 1.7 tsutsui trm_eeprom_wait(); 2496 1.1 tsutsui 2497 1.20 christos for (addr = 0; addr < 128; addr++, sbuf++) 2498 1.20 christos trm_eeprom_set_data(sc, addr, *sbuf); 2499 1.1 tsutsui 2500 1.1 tsutsui /* 2501 1.1 tsutsui * Write disable 2502 1.1 tsutsui */ 2503 1.1 tsutsui trm_eeprom_write_cmd(sc, 0x04, 0x00); 2504 1.1 tsutsui bus_space_write_1(iot, ioh, TRM_GEN_NVRAM, 0); 2505 1.7 tsutsui trm_eeprom_wait(); 2506 1.1 tsutsui 2507 1.1 tsutsui /* Disable SEEPROM */ 2508 1.1 tsutsui bus_space_write_1(iot, ioh, TRM_GEN_CONTROL, 2509 1.1 tsutsui bus_space_read_1(iot, ioh, TRM_GEN_CONTROL) & ~EN_EEPROM); 2510 1.1 tsutsui } 2511 1.1 tsutsui 2512 1.1 tsutsui /* 2513 1.1 tsutsui * write one byte to seeprom 2514 1.1 tsutsui */ 2515 1.1 tsutsui static void 2516 1.16 tsutsui trm_eeprom_set_data(struct trm_softc *sc, uint8_t addr, uint8_t data) 2517 1.1 tsutsui { 2518 1.1 tsutsui bus_space_tag_t iot = sc->sc_iot; 2519 1.1 tsutsui bus_space_handle_t ioh = sc->sc_ioh; 2520 1.1 tsutsui int i; 2521 1.16 tsutsui uint8_t send; 2522 1.1 tsutsui 2523 1.1 tsutsui /* 2524 1.1 tsutsui * Send write command & address 2525 1.1 tsutsui */ 2526 1.1 tsutsui trm_eeprom_write_cmd(sc, 0x05, addr); 2527 1.1 tsutsui /* 2528 1.1 tsutsui * Write data 2529 1.1 tsutsui */ 2530 1.1 tsutsui for (i = 0; i < 8; i++, data <<= 1) { 2531 1.1 tsutsui send = NVR_SELECT; 2532 1.1 tsutsui if (data & 0x80) /* Start from bit 7 */ 2533 1.1 tsutsui send |= NVR_BITOUT; 2534 1.1 tsutsui 2535 1.1 tsutsui bus_space_write_1(iot, ioh, TRM_GEN_NVRAM, send); 2536 1.7 tsutsui trm_eeprom_wait(); 2537 1.1 tsutsui bus_space_write_1(iot, ioh, TRM_GEN_NVRAM, send | NVR_CLOCK); 2538 1.7 tsutsui trm_eeprom_wait(); 2539 1.1 tsutsui } 2540 1.1 tsutsui bus_space_write_1(iot, ioh, TRM_GEN_NVRAM, NVR_SELECT); 2541 1.7 tsutsui trm_eeprom_wait(); 2542 1.1 tsutsui /* 2543 1.1 tsutsui * Disable chip select 2544 1.1 tsutsui */ 2545 1.1 tsutsui bus_space_write_1(iot, ioh, TRM_GEN_NVRAM, 0); 2546 1.7 tsutsui trm_eeprom_wait(); 2547 1.1 tsutsui bus_space_write_1(iot, ioh, TRM_GEN_NVRAM, NVR_SELECT); 2548 1.7 tsutsui trm_eeprom_wait(); 2549 1.1 tsutsui /* 2550 1.1 tsutsui * Wait for write ready 2551 1.1 tsutsui */ 2552 1.1 tsutsui for (;;) { 2553 1.1 tsutsui bus_space_write_1(iot, ioh, TRM_GEN_NVRAM, 2554 1.1 tsutsui NVR_SELECT | NVR_CLOCK); 2555 1.7 tsutsui trm_eeprom_wait(); 2556 1.1 tsutsui bus_space_write_1(iot, ioh, TRM_GEN_NVRAM, NVR_SELECT); 2557 1.7 tsutsui trm_eeprom_wait(); 2558 1.1 tsutsui if (bus_space_read_1(iot, ioh, TRM_GEN_NVRAM) & NVR_BITIN) 2559 1.1 tsutsui break; 2560 1.1 tsutsui } 2561 1.1 tsutsui /* 2562 1.1 tsutsui * Disable chip select 2563 1.1 tsutsui */ 2564 1.1 tsutsui bus_space_write_1(iot, ioh, TRM_GEN_NVRAM, 0); 2565 1.1 tsutsui } 2566 1.1 tsutsui 2567 1.1 tsutsui /* 2568 1.7 tsutsui * read seeprom 128 bytes to struct eeprom 2569 1.1 tsutsui */ 2570 1.1 tsutsui static void 2571 1.15 tsutsui trm_eeprom_read_all(struct trm_softc *sc, struct trm_nvram *eeprom) 2572 1.1 tsutsui { 2573 1.1 tsutsui bus_space_tag_t iot = sc->sc_iot; 2574 1.1 tsutsui bus_space_handle_t ioh = sc->sc_ioh; 2575 1.20 christos uint8_t *sbuf = (uint8_t *)eeprom; 2576 1.16 tsutsui uint8_t addr; 2577 1.1 tsutsui 2578 1.1 tsutsui /* 2579 1.1 tsutsui * Enable SEEPROM 2580 1.1 tsutsui */ 2581 1.1 tsutsui bus_space_write_1(iot, ioh, TRM_GEN_CONTROL, 2582 1.1 tsutsui bus_space_read_1(iot, ioh, TRM_GEN_CONTROL) | EN_EEPROM); 2583 1.1 tsutsui 2584 1.7 tsutsui for (addr = 0; addr < 128; addr++) 2585 1.20 christos *sbuf++ = trm_eeprom_get_data(sc, addr); 2586 1.1 tsutsui 2587 1.1 tsutsui /* 2588 1.1 tsutsui * Disable SEEPROM 2589 1.1 tsutsui */ 2590 1.1 tsutsui bus_space_write_1(iot, ioh, TRM_GEN_CONTROL, 2591 1.1 tsutsui bus_space_read_1(iot, ioh, TRM_GEN_CONTROL) & ~EN_EEPROM); 2592 1.1 tsutsui } 2593 1.1 tsutsui 2594 1.1 tsutsui /* 2595 1.1 tsutsui * read one byte from seeprom 2596 1.1 tsutsui */ 2597 1.16 tsutsui static uint8_t 2598 1.16 tsutsui trm_eeprom_get_data(struct trm_softc *sc, uint8_t addr) 2599 1.1 tsutsui { 2600 1.1 tsutsui bus_space_tag_t iot = sc->sc_iot; 2601 1.1 tsutsui bus_space_handle_t ioh = sc->sc_ioh; 2602 1.1 tsutsui int i; 2603 1.16 tsutsui uint8_t read, data = 0; 2604 1.1 tsutsui 2605 1.1 tsutsui /* 2606 1.1 tsutsui * Send read command & address 2607 1.1 tsutsui */ 2608 1.1 tsutsui trm_eeprom_write_cmd(sc, 0x06, addr); 2609 1.1 tsutsui 2610 1.1 tsutsui for (i = 0; i < 8; i++) { /* Read data */ 2611 1.1 tsutsui bus_space_write_1(iot, ioh, TRM_GEN_NVRAM, 2612 1.1 tsutsui NVR_SELECT | NVR_CLOCK); 2613 1.7 tsutsui trm_eeprom_wait(); 2614 1.1 tsutsui bus_space_write_1(iot, ioh, TRM_GEN_NVRAM, NVR_SELECT); 2615 1.1 tsutsui /* 2616 1.1 tsutsui * Get data bit while falling edge 2617 1.1 tsutsui */ 2618 1.1 tsutsui read = bus_space_read_1(iot, ioh, TRM_GEN_NVRAM); 2619 1.1 tsutsui data <<= 1; 2620 1.1 tsutsui if (read & NVR_BITIN) 2621 1.1 tsutsui data |= 1; 2622 1.1 tsutsui 2623 1.7 tsutsui trm_eeprom_wait(); 2624 1.1 tsutsui } 2625 1.1 tsutsui /* 2626 1.1 tsutsui * Disable chip select 2627 1.1 tsutsui */ 2628 1.1 tsutsui bus_space_write_1(iot, ioh, TRM_GEN_NVRAM, 0); 2629 1.29 tsutsui return data; 2630 1.1 tsutsui } 2631 1.1 tsutsui 2632 1.1 tsutsui /* 2633 1.1 tsutsui * write SB and Op Code into seeprom 2634 1.1 tsutsui */ 2635 1.1 tsutsui static void 2636 1.16 tsutsui trm_eeprom_write_cmd(struct trm_softc *sc, uint8_t cmd, uint8_t addr) 2637 1.1 tsutsui { 2638 1.1 tsutsui bus_space_tag_t iot = sc->sc_iot; 2639 1.1 tsutsui bus_space_handle_t ioh = sc->sc_ioh; 2640 1.1 tsutsui int i; 2641 1.16 tsutsui uint8_t send; 2642 1.1 tsutsui 2643 1.1 tsutsui /* Program SB+OP code */ 2644 1.1 tsutsui for (i = 0; i < 3; i++, cmd <<= 1) { 2645 1.1 tsutsui send = NVR_SELECT; 2646 1.1 tsutsui if (cmd & 0x04) /* Start from bit 2 */ 2647 1.1 tsutsui send |= NVR_BITOUT; 2648 1.1 tsutsui 2649 1.1 tsutsui bus_space_write_1(iot, ioh, TRM_GEN_NVRAM, send); 2650 1.7 tsutsui trm_eeprom_wait(); 2651 1.1 tsutsui bus_space_write_1(iot, ioh, TRM_GEN_NVRAM, send | NVR_CLOCK); 2652 1.7 tsutsui trm_eeprom_wait(); 2653 1.1 tsutsui } 2654 1.1 tsutsui 2655 1.1 tsutsui /* Program address */ 2656 1.1 tsutsui for (i = 0; i < 7; i++, addr <<= 1) { 2657 1.1 tsutsui send = NVR_SELECT; 2658 1.1 tsutsui if (addr & 0x40) /* Start from bit 6 */ 2659 1.1 tsutsui send |= NVR_BITOUT; 2660 1.1 tsutsui 2661 1.1 tsutsui bus_space_write_1(iot, ioh, TRM_GEN_NVRAM, send); 2662 1.7 tsutsui trm_eeprom_wait(); 2663 1.1 tsutsui bus_space_write_1(iot, ioh, TRM_GEN_NVRAM, send | NVR_CLOCK); 2664 1.7 tsutsui trm_eeprom_wait(); 2665 1.1 tsutsui } 2666 1.1 tsutsui bus_space_write_1(iot, ioh, TRM_GEN_NVRAM, NVR_SELECT); 2667 1.7 tsutsui trm_eeprom_wait(); 2668 1.1 tsutsui } 2669