1 1.53 thorpej /* $NetBSD: adv.c,v 1.53 2022/09/25 18:43:32 thorpej Exp $ */ 2 1.2 dante 3 1.1 dante /* 4 1.4 dante * Generic driver for the Advanced Systems Inc. Narrow SCSI controllers 5 1.1 dante * 6 1.1 dante * Copyright (c) 1998 The NetBSD Foundation, Inc. 7 1.1 dante * All rights reserved. 8 1.1 dante * 9 1.1 dante * Author: Baldassare Dante Profeta <dante (at) mclink.it> 10 1.1 dante * 11 1.1 dante * Redistribution and use in source and binary forms, with or without 12 1.1 dante * modification, are permitted provided that the following conditions 13 1.1 dante * are met: 14 1.1 dante * 1. Redistributions of source code must retain the above copyright 15 1.1 dante * notice, this list of conditions and the following disclaimer. 16 1.1 dante * 2. Redistributions in binary form must reproduce the above copyright 17 1.1 dante * notice, this list of conditions and the following disclaimer in the 18 1.1 dante * documentation and/or other materials provided with the distribution. 19 1.1 dante * 20 1.1 dante * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 21 1.1 dante * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 1.1 dante * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 1.1 dante * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 24 1.1 dante * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 1.1 dante * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 1.1 dante * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 1.1 dante * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 1.1 dante * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 1.1 dante * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 1.1 dante * POSSIBILITY OF SUCH DAMAGE. 31 1.1 dante */ 32 1.29 lukem 33 1.29 lukem #include <sys/cdefs.h> 34 1.53 thorpej __KERNEL_RCSID(0, "$NetBSD: adv.c,v 1.53 2022/09/25 18:43:32 thorpej Exp $"); 35 1.1 dante 36 1.1 dante #include <sys/param.h> 37 1.1 dante #include <sys/systm.h> 38 1.16 thorpej #include <sys/callout.h> 39 1.1 dante #include <sys/kernel.h> 40 1.1 dante #include <sys/errno.h> 41 1.1 dante #include <sys/ioctl.h> 42 1.1 dante #include <sys/device.h> 43 1.1 dante #include <sys/buf.h> 44 1.1 dante #include <sys/proc.h> 45 1.1 dante 46 1.41 ad #include <sys/bus.h> 47 1.41 ad #include <sys/intr.h> 48 1.1 dante 49 1.1 dante #include <dev/scsipi/scsi_all.h> 50 1.1 dante #include <dev/scsipi/scsipi_all.h> 51 1.1 dante #include <dev/scsipi/scsiconf.h> 52 1.1 dante 53 1.10 dante #include <dev/ic/advlib.h> 54 1.1 dante #include <dev/ic/adv.h> 55 1.3 thorpej 56 1.3 thorpej #ifndef DDB 57 1.3 thorpej #define Debugger() panic("should call debugger here (adv.c)") 58 1.3 thorpej #endif /* ! DDB */ 59 1.1 dante 60 1.6 dante 61 1.6 dante /* #define ASC_DEBUG */ 62 1.6 dante 63 1.1 dante /******************************************************************************/ 64 1.1 dante 65 1.1 dante 66 1.34 perry static int adv_alloc_control_data(ASC_SOFTC *); 67 1.34 perry static void adv_free_control_data(ASC_SOFTC *); 68 1.34 perry static int adv_create_ccbs(ASC_SOFTC *, ADV_CCB *, int); 69 1.34 perry static void adv_free_ccb(ASC_SOFTC *, ADV_CCB *); 70 1.34 perry static void adv_reset_ccb(ADV_CCB *); 71 1.34 perry static int adv_init_ccb(ASC_SOFTC *, ADV_CCB *); 72 1.34 perry static ADV_CCB *adv_get_ccb(ASC_SOFTC *); 73 1.34 perry static void adv_queue_ccb(ASC_SOFTC *, ADV_CCB *); 74 1.34 perry static void adv_start_ccbs(ASC_SOFTC *); 75 1.34 perry 76 1.34 perry 77 1.34 perry static void adv_scsipi_request(struct scsipi_channel *, 78 1.34 perry scsipi_adapter_req_t, void *); 79 1.34 perry static void advminphys(struct buf *); 80 1.34 perry static void adv_narrow_isr_callback(ASC_SOFTC *, ASC_QDONE_INFO *); 81 1.34 perry 82 1.34 perry static int adv_poll(ASC_SOFTC *, struct scsipi_xfer *, int); 83 1.34 perry static void adv_timeout(void *); 84 1.34 perry static void adv_watchdog(void *); 85 1.1 dante 86 1.1 dante 87 1.1 dante /******************************************************************************/ 88 1.1 dante 89 1.1 dante #define ADV_ABORT_TIMEOUT 2000 /* time to wait for abort (mSec) */ 90 1.1 dante #define ADV_WATCH_TIMEOUT 1000 /* time to wait for watchdog (mSec) */ 91 1.1 dante 92 1.1 dante /******************************************************************************/ 93 1.1 dante /* Control Blocks routines */ 94 1.1 dante /******************************************************************************/ 95 1.1 dante 96 1.1 dante 97 1.1 dante static int 98 1.43 dsl adv_alloc_control_data(ASC_SOFTC *sc) 99 1.1 dante { 100 1.22 thorpej int error; 101 1.1 dante 102 1.1 dante /* 103 1.24 bouyer * Allocate the control blocks. 104 1.24 bouyer */ 105 1.1 dante if ((error = bus_dmamem_alloc(sc->sc_dmat, sizeof(struct adv_control), 106 1.22 thorpej PAGE_SIZE, 0, &sc->sc_control_seg, 1, 107 1.22 thorpej &sc->sc_control_nsegs, BUS_DMA_NOWAIT)) != 0) { 108 1.47 msaitoh aprint_error_dev(sc->sc_dev, "unable to allocate control " 109 1.47 msaitoh "structures, error = %d\n", error); 110 1.1 dante return (error); 111 1.1 dante } 112 1.22 thorpej if ((error = bus_dmamem_map(sc->sc_dmat, &sc->sc_control_seg, 113 1.22 thorpej sc->sc_control_nsegs, sizeof(struct adv_control), 114 1.39 christos (void **) & sc->sc_control, 115 1.22 thorpej BUS_DMA_NOWAIT | BUS_DMA_COHERENT)) != 0) { 116 1.47 msaitoh aprint_error_dev(sc->sc_dev, 117 1.47 msaitoh "unable to map control structures, error = %d\n", error); 118 1.1 dante return (error); 119 1.1 dante } 120 1.1 dante /* 121 1.24 bouyer * Create and load the DMA map used for the control blocks. 122 1.24 bouyer */ 123 1.1 dante if ((error = bus_dmamap_create(sc->sc_dmat, sizeof(struct adv_control), 124 1.1 dante 1, sizeof(struct adv_control), 0, BUS_DMA_NOWAIT, 125 1.1 dante &sc->sc_dmamap_control)) != 0) { 126 1.47 msaitoh aprint_error_dev(sc->sc_dev, 127 1.47 msaitoh "unable to create control DMA map, error = %d\n", error); 128 1.1 dante return (error); 129 1.1 dante } 130 1.1 dante if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_dmamap_control, 131 1.1 dante sc->sc_control, sizeof(struct adv_control), NULL, 132 1.1 dante BUS_DMA_NOWAIT)) != 0) { 133 1.47 msaitoh aprint_error_dev(sc->sc_dev, 134 1.47 msaitoh "unable to load control DMA map, error = %d\n", error); 135 1.1 dante return (error); 136 1.1 dante } 137 1.13 thorpej 138 1.13 thorpej /* 139 1.13 thorpej * Initialize the overrun_buf address. 140 1.13 thorpej */ 141 1.13 thorpej sc->overrun_buf = sc->sc_dmamap_control->dm_segs[0].ds_addr + 142 1.13 thorpej offsetof(struct adv_control, overrun_buf); 143 1.13 thorpej 144 1.1 dante return (0); 145 1.1 dante } 146 1.1 dante 147 1.22 thorpej static void 148 1.43 dsl adv_free_control_data(ASC_SOFTC *sc) 149 1.22 thorpej { 150 1.22 thorpej 151 1.22 thorpej bus_dmamap_unload(sc->sc_dmat, sc->sc_dmamap_control); 152 1.22 thorpej bus_dmamap_destroy(sc->sc_dmat, sc->sc_dmamap_control); 153 1.22 thorpej sc->sc_dmamap_control = NULL; 154 1.22 thorpej 155 1.39 christos bus_dmamem_unmap(sc->sc_dmat, (void *) sc->sc_control, 156 1.22 thorpej sizeof(struct adv_control)); 157 1.22 thorpej bus_dmamem_free(sc->sc_dmat, &sc->sc_control_seg, 158 1.22 thorpej sc->sc_control_nsegs); 159 1.22 thorpej } 160 1.1 dante 161 1.1 dante /* 162 1.1 dante * Create a set of ccbs and add them to the free list. Called once 163 1.1 dante * by adv_init(). We return the number of CCBs successfully created. 164 1.1 dante */ 165 1.1 dante static int 166 1.43 dsl adv_create_ccbs(ASC_SOFTC *sc, ADV_CCB *ccbstore, int count) 167 1.1 dante { 168 1.1 dante ADV_CCB *ccb; 169 1.1 dante int i, error; 170 1.1 dante 171 1.27 thorpej memset(ccbstore, 0, sizeof(ADV_CCB) * count); 172 1.1 dante for (i = 0; i < count; i++) { 173 1.1 dante ccb = &ccbstore[i]; 174 1.1 dante if ((error = adv_init_ccb(sc, ccb)) != 0) { 175 1.47 msaitoh aprint_error_dev(sc->sc_dev, 176 1.47 msaitoh "unable to initialize ccb, error = %d\n", error); 177 1.1 dante return (i); 178 1.1 dante } 179 1.1 dante TAILQ_INSERT_TAIL(&sc->sc_free_ccb, ccb, chain); 180 1.1 dante } 181 1.1 dante 182 1.1 dante return (i); 183 1.1 dante } 184 1.1 dante 185 1.1 dante 186 1.1 dante /* 187 1.1 dante * A ccb is put onto the free list. 188 1.1 dante */ 189 1.1 dante static void 190 1.43 dsl adv_free_ccb(ASC_SOFTC *sc, ADV_CCB *ccb) 191 1.1 dante { 192 1.1 dante int s; 193 1.1 dante 194 1.1 dante s = splbio(); 195 1.1 dante adv_reset_ccb(ccb); 196 1.1 dante TAILQ_INSERT_HEAD(&sc->sc_free_ccb, ccb, chain); 197 1.1 dante splx(s); 198 1.1 dante } 199 1.1 dante 200 1.1 dante 201 1.1 dante static void 202 1.43 dsl adv_reset_ccb(ADV_CCB *ccb) 203 1.1 dante { 204 1.1 dante 205 1.1 dante ccb->flags = 0; 206 1.1 dante } 207 1.1 dante 208 1.1 dante 209 1.1 dante static int 210 1.43 dsl adv_init_ccb(ASC_SOFTC *sc, ADV_CCB *ccb) 211 1.1 dante { 212 1.10 dante int hashnum, error; 213 1.1 dante 214 1.40 ad callout_init(&ccb->ccb_watchdog, 0); 215 1.16 thorpej 216 1.1 dante /* 217 1.24 bouyer * Create the DMA map for this CCB. 218 1.24 bouyer */ 219 1.1 dante error = bus_dmamap_create(sc->sc_dmat, 220 1.1 dante (ASC_MAX_SG_LIST - 1) * PAGE_SIZE, 221 1.1 dante ASC_MAX_SG_LIST, (ASC_MAX_SG_LIST - 1) * PAGE_SIZE, 222 1.1 dante 0, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &ccb->dmamap_xfer); 223 1.1 dante if (error) { 224 1.47 msaitoh aprint_error_dev(sc->sc_dev, 225 1.47 msaitoh "unable to create DMA map, error = %d\n", error); 226 1.1 dante return (error); 227 1.1 dante } 228 1.10 dante 229 1.10 dante /* 230 1.10 dante * put in the phystokv hash table 231 1.10 dante * Never gets taken out. 232 1.10 dante */ 233 1.10 dante ccb->hashkey = sc->sc_dmamap_control->dm_segs[0].ds_addr + 234 1.10 dante ADV_CCB_OFF(ccb); 235 1.10 dante hashnum = CCB_HASH(ccb->hashkey); 236 1.10 dante ccb->nexthash = sc->sc_ccbhash[hashnum]; 237 1.10 dante sc->sc_ccbhash[hashnum] = ccb; 238 1.10 dante 239 1.1 dante adv_reset_ccb(ccb); 240 1.1 dante return (0); 241 1.1 dante } 242 1.1 dante 243 1.1 dante 244 1.1 dante /* 245 1.1 dante * Get a free ccb 246 1.1 dante * 247 1.1 dante * If there are none, see if we can allocate a new one 248 1.1 dante */ 249 1.1 dante static ADV_CCB * 250 1.43 dsl adv_get_ccb(ASC_SOFTC *sc) 251 1.1 dante { 252 1.1 dante ADV_CCB *ccb = 0; 253 1.1 dante int s; 254 1.1 dante 255 1.1 dante s = splbio(); 256 1.24 bouyer ccb = TAILQ_FIRST(&sc->sc_free_ccb); 257 1.24 bouyer if (ccb != NULL) { 258 1.24 bouyer TAILQ_REMOVE(&sc->sc_free_ccb, ccb, chain); 259 1.24 bouyer ccb->flags |= CCB_ALLOC; 260 1.1 dante } 261 1.1 dante splx(s); 262 1.1 dante return (ccb); 263 1.1 dante } 264 1.1 dante 265 1.1 dante 266 1.1 dante /* 267 1.10 dante * Given a physical address, find the ccb that it corresponds to. 268 1.10 dante */ 269 1.10 dante ADV_CCB * 270 1.43 dsl adv_ccb_phys_kv(ASC_SOFTC *sc, u_long ccb_phys) 271 1.10 dante { 272 1.10 dante int hashnum = CCB_HASH(ccb_phys); 273 1.10 dante ADV_CCB *ccb = sc->sc_ccbhash[hashnum]; 274 1.10 dante 275 1.10 dante while (ccb) { 276 1.10 dante if (ccb->hashkey == ccb_phys) 277 1.10 dante break; 278 1.10 dante ccb = ccb->nexthash; 279 1.10 dante } 280 1.10 dante return (ccb); 281 1.10 dante } 282 1.10 dante 283 1.10 dante 284 1.10 dante /* 285 1.1 dante * Queue a CCB to be sent to the controller, and send it if possible. 286 1.1 dante */ 287 1.1 dante static void 288 1.43 dsl adv_queue_ccb(ASC_SOFTC *sc, ADV_CCB *ccb) 289 1.1 dante { 290 1.1 dante 291 1.1 dante TAILQ_INSERT_TAIL(&sc->sc_waiting_ccb, ccb, chain); 292 1.1 dante 293 1.1 dante adv_start_ccbs(sc); 294 1.1 dante } 295 1.1 dante 296 1.1 dante 297 1.1 dante static void 298 1.43 dsl adv_start_ccbs(ASC_SOFTC *sc) 299 1.1 dante { 300 1.1 dante ADV_CCB *ccb; 301 1.1 dante 302 1.1 dante while ((ccb = sc->sc_waiting_ccb.tqh_first) != NULL) { 303 1.1 dante if (ccb->flags & CCB_WATCHDOG) 304 1.16 thorpej callout_stop(&ccb->ccb_watchdog); 305 1.1 dante 306 1.1 dante if (AscExeScsiQueue(sc, &ccb->scsiq) == ASC_BUSY) { 307 1.1 dante ccb->flags |= CCB_WATCHDOG; 308 1.16 thorpej callout_reset(&ccb->ccb_watchdog, 309 1.16 thorpej (ADV_WATCH_TIMEOUT * hz) / 1000, 310 1.16 thorpej adv_watchdog, ccb); 311 1.1 dante break; 312 1.1 dante } 313 1.1 dante TAILQ_REMOVE(&sc->sc_waiting_ccb, ccb, chain); 314 1.1 dante 315 1.14 thorpej if ((ccb->xs->xs_control & XS_CTL_POLL) == 0) 316 1.16 thorpej callout_reset(&ccb->xs->xs_callout, 317 1.31 bouyer mstohz(ccb->timeout), adv_timeout, ccb); 318 1.1 dante } 319 1.1 dante } 320 1.1 dante 321 1.1 dante 322 1.1 dante /******************************************************************************/ 323 1.1 dante /* SCSI layer interfacing routines */ 324 1.1 dante /******************************************************************************/ 325 1.1 dante 326 1.1 dante 327 1.1 dante int 328 1.43 dsl adv_init(ASC_SOFTC *sc) 329 1.1 dante { 330 1.1 dante int warn; 331 1.1 dante 332 1.12 dante if (!AscFindSignature(sc->sc_iot, sc->sc_ioh)) { 333 1.32 thorpej aprint_error("adv_init: failed to find signature\n"); 334 1.12 dante return (1); 335 1.12 dante } 336 1.1 dante 337 1.4 dante /* 338 1.24 bouyer * Read the board configuration 339 1.24 bouyer */ 340 1.4 dante AscInitASC_SOFTC(sc); 341 1.4 dante warn = AscInitFromEEP(sc); 342 1.4 dante if (warn) { 343 1.46 chs aprint_error_dev(sc->sc_dev, "-get: "); 344 1.4 dante switch (warn) { 345 1.4 dante case -1: 346 1.32 thorpej aprint_normal("Chip is not halted\n"); 347 1.4 dante break; 348 1.4 dante 349 1.4 dante case -2: 350 1.32 thorpej aprint_normal("Couldn't get MicroCode Start" 351 1.4 dante " address\n"); 352 1.4 dante break; 353 1.4 dante 354 1.4 dante case ASC_WARN_IO_PORT_ROTATE: 355 1.32 thorpej aprint_normal("I/O port address modified\n"); 356 1.4 dante break; 357 1.4 dante 358 1.4 dante case ASC_WARN_AUTO_CONFIG: 359 1.32 thorpej aprint_normal("I/O port increment switch enabled\n"); 360 1.4 dante break; 361 1.4 dante 362 1.4 dante case ASC_WARN_EEPROM_CHKSUM: 363 1.32 thorpej aprint_normal("EEPROM checksum error\n"); 364 1.4 dante break; 365 1.4 dante 366 1.4 dante case ASC_WARN_IRQ_MODIFIED: 367 1.32 thorpej aprint_normal("IRQ modified\n"); 368 1.4 dante break; 369 1.4 dante 370 1.4 dante case ASC_WARN_CMD_QNG_CONFLICT: 371 1.32 thorpej aprint_normal("tag queuing enabled w/o disconnects\n"); 372 1.4 dante break; 373 1.1 dante 374 1.4 dante default: 375 1.32 thorpej aprint_normal("unknown warning %d\n", warn); 376 1.1 dante } 377 1.4 dante } 378 1.4 dante if (sc->scsi_reset_wait > ASC_MAX_SCSI_RESET_WAIT) 379 1.4 dante sc->scsi_reset_wait = ASC_MAX_SCSI_RESET_WAIT; 380 1.4 dante 381 1.4 dante /* 382 1.24 bouyer * Modify the board configuration 383 1.24 bouyer */ 384 1.4 dante warn = AscInitFromASC_SOFTC(sc); 385 1.4 dante if (warn) { 386 1.46 chs aprint_error_dev(sc->sc_dev, "-set: "); 387 1.4 dante switch (warn) { 388 1.4 dante case ASC_WARN_CMD_QNG_CONFLICT: 389 1.32 thorpej aprint_normal("tag queuing enabled w/o disconnects\n"); 390 1.4 dante break; 391 1.1 dante 392 1.4 dante case ASC_WARN_AUTO_CONFIG: 393 1.32 thorpej aprint_normal("I/O port increment switch enabled\n"); 394 1.4 dante break; 395 1.1 dante 396 1.4 dante default: 397 1.32 thorpej aprint_normal("unknown warning %d\n", warn); 398 1.1 dante } 399 1.4 dante } 400 1.49 uwe sc->isr_callback = adv_narrow_isr_callback; 401 1.1 dante 402 1.1 dante return (0); 403 1.1 dante } 404 1.1 dante 405 1.1 dante 406 1.1 dante void 407 1.43 dsl adv_attach(ASC_SOFTC *sc) 408 1.1 dante { 409 1.24 bouyer struct scsipi_adapter *adapt = &sc->sc_adapter; 410 1.24 bouyer struct scsipi_channel *chan = &sc->sc_channel; 411 1.1 dante int i, error; 412 1.1 dante 413 1.4 dante /* 414 1.24 bouyer * Initialize board RISC chip and enable interrupts. 415 1.24 bouyer */ 416 1.4 dante switch (AscInitDriver(sc)) { 417 1.4 dante case 0: 418 1.4 dante /* AllOK */ 419 1.4 dante break; 420 1.1 dante 421 1.4 dante case 1: 422 1.46 chs panic("%s: bad signature", device_xname(sc->sc_dev)); 423 1.4 dante break; 424 1.1 dante 425 1.4 dante case 2: 426 1.4 dante panic("%s: unable to load MicroCode", 427 1.46 chs device_xname(sc->sc_dev)); 428 1.4 dante break; 429 1.1 dante 430 1.4 dante case 3: 431 1.4 dante panic("%s: unable to initialize MicroCode", 432 1.46 chs device_xname(sc->sc_dev)); 433 1.4 dante break; 434 1.1 dante 435 1.4 dante default: 436 1.4 dante panic("%s: unable to initialize board RISC chip", 437 1.46 chs device_xname(sc->sc_dev)); 438 1.1 dante } 439 1.1 dante 440 1.7 thorpej /* 441 1.24 bouyer * Fill in the scsipi_adapter. 442 1.7 thorpej */ 443 1.24 bouyer memset(adapt, 0, sizeof(*adapt)); 444 1.46 chs adapt->adapt_dev = sc->sc_dev; 445 1.24 bouyer adapt->adapt_nchannels = 1; 446 1.24 bouyer /* adapt_openings initialized below */ 447 1.24 bouyer /* adapt_max_periph initialized below */ 448 1.24 bouyer adapt->adapt_request = adv_scsipi_request; 449 1.24 bouyer adapt->adapt_minphys = advminphys; 450 1.1 dante 451 1.1 dante /* 452 1.24 bouyer * Fill in the scsipi_channel. 453 1.24 bouyer */ 454 1.24 bouyer memset(chan, 0, sizeof(*chan)); 455 1.24 bouyer chan->chan_adapter = adapt; 456 1.24 bouyer chan->chan_bustype = &scsi_bustype; 457 1.24 bouyer chan->chan_channel = 0; 458 1.24 bouyer chan->chan_ntargets = 8; 459 1.24 bouyer chan->chan_nluns = 8; 460 1.24 bouyer chan->chan_id = sc->chip_scsi_id; 461 1.1 dante 462 1.1 dante TAILQ_INIT(&sc->sc_free_ccb); 463 1.1 dante TAILQ_INIT(&sc->sc_waiting_ccb); 464 1.1 dante 465 1.1 dante /* 466 1.24 bouyer * Allocate the Control Blocks and the overrun buffer. 467 1.24 bouyer */ 468 1.13 thorpej error = adv_alloc_control_data(sc); 469 1.1 dante if (error) 470 1.12 dante return; /* (error) */ 471 1.1 dante 472 1.1 dante /* 473 1.24 bouyer * Create and initialize the Control Blocks. 474 1.24 bouyer */ 475 1.1 dante i = adv_create_ccbs(sc, sc->sc_control->ccbs, ADV_MAX_CCB); 476 1.1 dante if (i == 0) { 477 1.47 msaitoh aprint_error_dev(sc->sc_dev, 478 1.47 msaitoh "unable to create control blocks\n"); 479 1.1 dante return; /* (ENOMEM) */ ; 480 1.1 dante } else if (i != ADV_MAX_CCB) { 481 1.47 msaitoh aprint_error_dev(sc->sc_dev, 482 1.42 cegger "WARNING: only %d of %d control blocks created\n", 483 1.42 cegger i, ADV_MAX_CCB); 484 1.1 dante } 485 1.24 bouyer 486 1.24 bouyer adapt->adapt_openings = i; 487 1.24 bouyer adapt->adapt_max_periph = adapt->adapt_openings; 488 1.24 bouyer 489 1.52 thorpej sc->sc_child = config_found(sc->sc_dev, chan, scsiprint, CFARGS_NONE); 490 1.1 dante } 491 1.1 dante 492 1.22 thorpej int 493 1.43 dsl adv_detach(ASC_SOFTC *sc, int flags) 494 1.22 thorpej { 495 1.22 thorpej int rv = 0; 496 1.22 thorpej 497 1.22 thorpej if (sc->sc_child != NULL) 498 1.22 thorpej rv = config_detach(sc->sc_child, flags); 499 1.22 thorpej 500 1.22 thorpej adv_free_control_data(sc); 501 1.22 thorpej 502 1.22 thorpej return (rv); 503 1.22 thorpej } 504 1.1 dante 505 1.1 dante static void 506 1.43 dsl advminphys(struct buf *bp) 507 1.1 dante { 508 1.1 dante 509 1.1 dante if (bp->b_bcount > ((ASC_MAX_SG_LIST - 1) * PAGE_SIZE)) 510 1.1 dante bp->b_bcount = ((ASC_MAX_SG_LIST - 1) * PAGE_SIZE); 511 1.1 dante minphys(bp); 512 1.1 dante } 513 1.1 dante 514 1.1 dante 515 1.1 dante /* 516 1.1 dante * start a scsi operation given the command and the data address. Also needs 517 1.1 dante * the unit, target and lu. 518 1.1 dante */ 519 1.1 dante 520 1.24 bouyer static void 521 1.47 msaitoh adv_scsipi_request(struct scsipi_channel *chan, scsipi_adapter_req_t req, 522 1.47 msaitoh void *arg) 523 1.24 bouyer { 524 1.24 bouyer struct scsipi_xfer *xs; 525 1.24 bouyer struct scsipi_periph *periph; 526 1.46 chs ASC_SOFTC *sc = device_private(chan->chan_adapter->adapt_dev); 527 1.24 bouyer bus_dma_tag_t dmat = sc->sc_dmat; 528 1.24 bouyer ADV_CCB *ccb; 529 1.24 bouyer int s, flags, error, nsegs; 530 1.36 perry 531 1.24 bouyer switch (req) { 532 1.24 bouyer case ADAPTER_REQ_RUN_XFER: 533 1.24 bouyer xs = arg; 534 1.24 bouyer periph = xs->xs_periph; 535 1.24 bouyer flags = xs->xs_control; 536 1.36 perry 537 1.24 bouyer /* 538 1.24 bouyer * Get a CCB to use. 539 1.24 bouyer */ 540 1.24 bouyer ccb = adv_get_ccb(sc); 541 1.24 bouyer #ifdef DIAGNOSTIC 542 1.24 bouyer /* 543 1.24 bouyer * This should never happen as we track the resources 544 1.24 bouyer * in the mid-layer. 545 1.24 bouyer */ 546 1.24 bouyer if (ccb == NULL) { 547 1.24 bouyer scsipi_printaddr(periph); 548 1.24 bouyer printf("unable to allocate ccb\n"); 549 1.24 bouyer panic("adv_scsipi_request"); 550 1.24 bouyer } 551 1.24 bouyer #endif 552 1.36 perry 553 1.24 bouyer ccb->xs = xs; 554 1.24 bouyer ccb->timeout = xs->timeout; 555 1.36 perry 556 1.24 bouyer /* 557 1.24 bouyer * Build up the request 558 1.24 bouyer */ 559 1.24 bouyer memset(&ccb->scsiq, 0, sizeof(ASC_SCSI_Q)); 560 1.36 perry 561 1.24 bouyer ccb->scsiq.q2.ccb_ptr = 562 1.24 bouyer sc->sc_dmamap_control->dm_segs[0].ds_addr + 563 1.24 bouyer ADV_CCB_OFF(ccb); 564 1.36 perry 565 1.24 bouyer ccb->scsiq.cdbptr = &xs->cmd->opcode; 566 1.24 bouyer ccb->scsiq.q2.cdb_len = xs->cmdlen; 567 1.24 bouyer ccb->scsiq.q1.target_id = 568 1.24 bouyer ASC_TID_TO_TARGET_ID(periph->periph_target); 569 1.24 bouyer ccb->scsiq.q1.target_lun = periph->periph_lun; 570 1.24 bouyer ccb->scsiq.q2.target_ix = 571 1.24 bouyer ASC_TIDLUN_TO_IX(periph->periph_target, 572 1.24 bouyer periph->periph_lun); 573 1.24 bouyer ccb->scsiq.q1.sense_addr = 574 1.24 bouyer sc->sc_dmamap_control->dm_segs[0].ds_addr + 575 1.24 bouyer ADV_CCB_OFF(ccb) + offsetof(struct adv_ccb, scsi_sense); 576 1.35 thorpej ccb->scsiq.q1.sense_len = sizeof(struct scsi_sense_data); 577 1.36 perry 578 1.24 bouyer /* 579 1.24 bouyer * If there are any outstanding requests for the current 580 1.24 bouyer * target, then every 255th request send an ORDERED request. 581 1.24 bouyer * This heuristic tries to retain the benefit of request 582 1.24 bouyer * sorting while preventing request starvation. 255 is the 583 1.24 bouyer * max number of tags or pending commands a device may have 584 1.24 bouyer * outstanding. 585 1.24 bouyer */ 586 1.24 bouyer sc->reqcnt[periph->periph_target]++; 587 1.24 bouyer if (((sc->reqcnt[periph->periph_target] > 0) && 588 1.24 bouyer (sc->reqcnt[periph->periph_target] % 255) == 0) || 589 1.24 bouyer xs->bp == NULL || (xs->bp->b_flags & B_ASYNC) == 0) { 590 1.24 bouyer ccb->scsiq.q2.tag_code = M2_QTAG_MSG_ORDERED; 591 1.24 bouyer } else { 592 1.24 bouyer ccb->scsiq.q2.tag_code = M2_QTAG_MSG_SIMPLE; 593 1.24 bouyer } 594 1.36 perry 595 1.24 bouyer if (xs->datalen) { 596 1.24 bouyer /* 597 1.24 bouyer * Map the DMA transfer. 598 1.24 bouyer */ 599 1.1 dante #ifdef TFS 600 1.24 bouyer if (flags & SCSI_DATA_UIO) { 601 1.24 bouyer error = bus_dmamap_load_uio(dmat, 602 1.24 bouyer ccb->dmamap_xfer, (struct uio *) xs->data, 603 1.24 bouyer ((flags & XS_CTL_NOSLEEP) ? BUS_DMA_NOWAIT : 604 1.28 thorpej BUS_DMA_WAITOK) | BUS_DMA_STREAMING | 605 1.28 thorpej ((flags & XS_CTL_DATA_IN) ? BUS_DMA_READ : 606 1.28 thorpej BUS_DMA_WRITE)); 607 1.24 bouyer } else 608 1.24 bouyer #endif /* TFS */ 609 1.24 bouyer { 610 1.24 bouyer error = bus_dmamap_load(dmat, ccb->dmamap_xfer, 611 1.24 bouyer xs->data, xs->datalen, NULL, 612 1.24 bouyer ((flags & XS_CTL_NOSLEEP) ? BUS_DMA_NOWAIT : 613 1.28 thorpej BUS_DMA_WAITOK) | BUS_DMA_STREAMING | 614 1.28 thorpej ((flags & XS_CTL_DATA_IN) ? BUS_DMA_READ : 615 1.28 thorpej BUS_DMA_WRITE)); 616 1.24 bouyer } 617 1.36 perry 618 1.24 bouyer switch (error) { 619 1.24 bouyer case 0: 620 1.24 bouyer break; 621 1.24 bouyer 622 1.36 perry 623 1.24 bouyer case ENOMEM: 624 1.24 bouyer case EAGAIN: 625 1.24 bouyer xs->error = XS_RESOURCE_SHORTAGE; 626 1.24 bouyer goto out_bad; 627 1.36 perry 628 1.24 bouyer default: 629 1.24 bouyer xs->error = XS_DRIVER_STUFFUP; 630 1.24 bouyer if (error == EFBIG) { 631 1.47 msaitoh aprint_error_dev(sc->sc_dev, 632 1.47 msaitoh "adv_scsi_cmd, more than %d" 633 1.33 wiz " DMA segments\n", 634 1.24 bouyer ASC_MAX_SG_LIST); 635 1.24 bouyer } else { 636 1.47 msaitoh aprint_error_dev(sc->sc_dev, 637 1.47 msaitoh "adv_scsi_cmd, error %d" 638 1.47 msaitoh " loading DMA map\n", error); 639 1.24 bouyer } 640 1.24 bouyer 641 1.24 bouyer out_bad: 642 1.24 bouyer adv_free_ccb(sc, ccb); 643 1.24 bouyer scsipi_done(xs); 644 1.24 bouyer return; 645 1.24 bouyer } 646 1.24 bouyer bus_dmamap_sync(dmat, ccb->dmamap_xfer, 0, 647 1.24 bouyer ccb->dmamap_xfer->dm_mapsize, 648 1.24 bouyer (flags & XS_CTL_DATA_IN) ? 649 1.24 bouyer BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE); 650 1.36 perry 651 1.24 bouyer memset(&ccb->sghead, 0, sizeof(ASC_SG_HEAD)); 652 1.36 perry 653 1.24 bouyer for (nsegs = 0; 654 1.24 bouyer nsegs < ccb->dmamap_xfer->dm_nsegs; nsegs++) { 655 1.24 bouyer ccb->sghead.sg_list[nsegs].addr = 656 1.24 bouyer ccb->dmamap_xfer->dm_segs[nsegs].ds_addr; 657 1.24 bouyer ccb->sghead.sg_list[nsegs].bytes = 658 1.24 bouyer ccb->dmamap_xfer->dm_segs[nsegs].ds_len; 659 1.24 bouyer } 660 1.36 perry 661 1.24 bouyer ccb->sghead.entry_cnt = ccb->scsiq.q1.sg_queue_cnt = 662 1.24 bouyer ccb->dmamap_xfer->dm_nsegs; 663 1.36 perry 664 1.24 bouyer ccb->scsiq.q1.cntl |= ASC_QC_SG_HEAD; 665 1.24 bouyer ccb->scsiq.sg_head = &ccb->sghead; 666 1.24 bouyer ccb->scsiq.q1.data_addr = 0; 667 1.24 bouyer ccb->scsiq.q1.data_cnt = 0; 668 1.24 bouyer } else { 669 1.24 bouyer /* 670 1.24 bouyer * No data xfer, use non S/G values. 671 1.24 bouyer */ 672 1.24 bouyer ccb->scsiq.q1.data_addr = 0; 673 1.24 bouyer ccb->scsiq.q1.data_cnt = 0; 674 1.24 bouyer } 675 1.36 perry 676 1.6 dante #ifdef ASC_DEBUG 677 1.38 christos printf("id = %d, lun = %d, cmd = %d, ccb = 0x%lX\n", 678 1.24 bouyer periph->periph_target, 679 1.24 bouyer periph->periph_lun, xs->cmd->opcode, 680 1.24 bouyer (unsigned long)ccb); 681 1.6 dante #endif 682 1.24 bouyer s = splbio(); 683 1.24 bouyer adv_queue_ccb(sc, ccb); 684 1.24 bouyer splx(s); 685 1.36 perry 686 1.24 bouyer if ((flags & XS_CTL_POLL) == 0) 687 1.24 bouyer return; 688 1.36 perry 689 1.24 bouyer /* Not allowed to use interrupts, poll for completion. */ 690 1.24 bouyer if (adv_poll(sc, xs, ccb->timeout)) { 691 1.24 bouyer adv_timeout(ccb); 692 1.24 bouyer if (adv_poll(sc, xs, ccb->timeout)) 693 1.24 bouyer adv_timeout(ccb); 694 1.24 bouyer } 695 1.24 bouyer return; 696 1.36 perry 697 1.24 bouyer case ADAPTER_REQ_GROW_RESOURCES: 698 1.24 bouyer /* XXX Not supported. */ 699 1.24 bouyer return; 700 1.36 perry 701 1.24 bouyer case ADAPTER_REQ_SET_XFER_MODE: 702 1.24 bouyer { 703 1.24 bouyer /* 704 1.24 bouyer * We can't really set the mode, but we know how to 705 1.24 bouyer * query what the firmware negotiated. 706 1.24 bouyer */ 707 1.24 bouyer struct scsipi_xfer_mode *xm = arg; 708 1.24 bouyer u_int8_t sdtr_data; 709 1.24 bouyer ASC_SCSI_BIT_ID_TYPE tid_bit; 710 1.36 perry 711 1.24 bouyer tid_bit = ASC_TIX_TO_TARGET_ID(xm->xm_target); 712 1.36 perry 713 1.24 bouyer xm->xm_mode = 0; 714 1.24 bouyer xm->xm_period = 0; 715 1.24 bouyer xm->xm_offset = 0; 716 1.36 perry 717 1.24 bouyer if (sc->init_sdtr & tid_bit) { 718 1.24 bouyer xm->xm_mode |= PERIPH_CAP_SYNC; 719 1.24 bouyer sdtr_data = sc->sdtr_data[xm->xm_target]; 720 1.24 bouyer xm->xm_period = 721 1.24 bouyer sc->sdtr_period_tbl[(sdtr_data >> 4) & 722 1.24 bouyer (sc->max_sdtr_index - 1)]; 723 1.24 bouyer xm->xm_offset = sdtr_data & ASC_SYN_MAX_OFFSET; 724 1.24 bouyer } 725 1.36 perry 726 1.24 bouyer if (sc->use_tagged_qng & tid_bit) 727 1.24 bouyer xm->xm_mode |= PERIPH_CAP_TQING; 728 1.36 perry 729 1.24 bouyer scsipi_async_event(chan, ASYNC_EVENT_XFER_MODE, xm); 730 1.24 bouyer return; 731 1.24 bouyer } 732 1.24 bouyer } 733 1.1 dante } 734 1.1 dante 735 1.1 dante int 736 1.43 dsl adv_intr(void *arg) 737 1.1 dante { 738 1.1 dante ASC_SOFTC *sc = arg; 739 1.1 dante 740 1.6 dante #ifdef ASC_DEBUG 741 1.6 dante int int_pend = FALSE; 742 1.6 dante 743 1.47 msaitoh if (ASC_IS_INT_PENDING(sc->sc_iot, sc->sc_ioh)) { 744 1.6 dante int_pend = TRUE; 745 1.6 dante printf("ISR - "); 746 1.6 dante } 747 1.6 dante #endif 748 1.4 dante AscISR(sc); 749 1.6 dante #ifdef ASC_DEBUG 750 1.6 dante if(int_pend) 751 1.6 dante printf("\n"); 752 1.6 dante #endif 753 1.1 dante 754 1.1 dante return (1); 755 1.1 dante } 756 1.1 dante 757 1.1 dante 758 1.1 dante /* 759 1.1 dante * Poll a particular unit, looking for a particular xs 760 1.1 dante */ 761 1.1 dante static int 762 1.43 dsl adv_poll(ASC_SOFTC *sc, struct scsipi_xfer *xs, int count) 763 1.1 dante { 764 1.1 dante 765 1.1 dante /* timeouts are in msec, so we loop in 1000 usec cycles */ 766 1.1 dante while (count) { 767 1.1 dante adv_intr(sc); 768 1.14 thorpej if (xs->xs_status & XS_STS_DONE) 769 1.1 dante return (0); 770 1.1 dante delay(1000); /* only happens in boot so ok */ 771 1.1 dante count--; 772 1.1 dante } 773 1.1 dante return (1); 774 1.1 dante } 775 1.1 dante 776 1.1 dante 777 1.1 dante static void 778 1.43 dsl adv_timeout(void *arg) 779 1.1 dante { 780 1.1 dante ADV_CCB *ccb = arg; 781 1.1 dante struct scsipi_xfer *xs = ccb->xs; 782 1.24 bouyer struct scsipi_periph *periph = xs->xs_periph; 783 1.24 bouyer ASC_SOFTC *sc = 784 1.46 chs device_private(periph->periph_channel->chan_adapter->adapt_dev); 785 1.1 dante int s; 786 1.1 dante 787 1.24 bouyer scsipi_printaddr(periph); 788 1.1 dante printf("timed out"); 789 1.1 dante 790 1.1 dante s = splbio(); 791 1.1 dante 792 1.1 dante /* 793 1.24 bouyer * If it has been through before, then a previous abort has failed, 794 1.24 bouyer * don't try abort again, reset the bus instead. 795 1.24 bouyer */ 796 1.1 dante if (ccb->flags & CCB_ABORT) { 797 1.1 dante /* abort timed out */ 798 1.1 dante printf(" AGAIN. Resetting Bus\n"); 799 1.1 dante /* Lets try resetting the bus! */ 800 1.1 dante if (AscResetBus(sc) == ASC_ERROR) { 801 1.1 dante ccb->timeout = sc->scsi_reset_wait; 802 1.1 dante adv_queue_ccb(sc, ccb); 803 1.1 dante } 804 1.1 dante } else { 805 1.1 dante /* abort the operation that has timed out */ 806 1.1 dante printf("\n"); 807 1.10 dante AscAbortCCB(sc, ccb); 808 1.1 dante ccb->xs->error = XS_TIMEOUT; 809 1.1 dante ccb->timeout = ADV_ABORT_TIMEOUT; 810 1.1 dante ccb->flags |= CCB_ABORT; 811 1.1 dante adv_queue_ccb(sc, ccb); 812 1.1 dante } 813 1.1 dante 814 1.1 dante splx(s); 815 1.1 dante } 816 1.1 dante 817 1.1 dante 818 1.1 dante static void 819 1.43 dsl adv_watchdog(void *arg) 820 1.1 dante { 821 1.1 dante ADV_CCB *ccb = arg; 822 1.1 dante struct scsipi_xfer *xs = ccb->xs; 823 1.24 bouyer struct scsipi_periph *periph = xs->xs_periph; 824 1.24 bouyer ASC_SOFTC *sc = 825 1.46 chs device_private(periph->periph_channel->chan_adapter->adapt_dev); 826 1.1 dante int s; 827 1.1 dante 828 1.1 dante s = splbio(); 829 1.1 dante 830 1.1 dante ccb->flags &= ~CCB_WATCHDOG; 831 1.1 dante adv_start_ccbs(sc); 832 1.1 dante 833 1.1 dante splx(s); 834 1.1 dante } 835 1.1 dante 836 1.1 dante 837 1.1 dante /******************************************************************************/ 838 1.10 dante /* NARROW boards Interrupt callbacks */ 839 1.1 dante /******************************************************************************/ 840 1.1 dante 841 1.1 dante 842 1.1 dante /* 843 1.1 dante * adv_narrow_isr_callback() - Second Level Interrupt Handler called by AscISR() 844 1.1 dante * 845 1.1 dante * Interrupt callback function for the Narrow SCSI Asc Library. 846 1.1 dante */ 847 1.1 dante static void 848 1.43 dsl adv_narrow_isr_callback(ASC_SOFTC *sc, ASC_QDONE_INFO *qdonep) 849 1.1 dante { 850 1.1 dante bus_dma_tag_t dmat = sc->sc_dmat; 851 1.10 dante ADV_CCB *ccb; 852 1.10 dante struct scsipi_xfer *xs; 853 1.35 thorpej struct scsi_sense_data *s1, *s2; 854 1.1 dante 855 1.10 dante 856 1.10 dante ccb = adv_ccb_phys_kv(sc, qdonep->d2.ccb_ptr); 857 1.10 dante xs = ccb->xs; 858 1.1 dante 859 1.6 dante #ifdef ASC_DEBUG 860 1.6 dante printf(" - ccb=0x%lx, id=%d, lun=%d, cmd=%d, ", 861 1.6 dante (unsigned long)ccb, 862 1.24 bouyer xs->xs_periph->periph_target, 863 1.24 bouyer xs->xs_periph->periph_lun, xs->cmd->opcode); 864 1.6 dante #endif 865 1.16 thorpej callout_stop(&ccb->xs->xs_callout); 866 1.1 dante 867 1.1 dante /* 868 1.24 bouyer * If we were a data transfer, unload the map that described 869 1.24 bouyer * the data buffer. 870 1.24 bouyer */ 871 1.1 dante if (xs->datalen) { 872 1.1 dante bus_dmamap_sync(dmat, ccb->dmamap_xfer, 0, 873 1.1 dante ccb->dmamap_xfer->dm_mapsize, 874 1.14 thorpej (xs->xs_control & XS_CTL_DATA_IN) ? 875 1.14 thorpej BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE); 876 1.1 dante bus_dmamap_unload(dmat, ccb->dmamap_xfer); 877 1.1 dante } 878 1.1 dante if ((ccb->flags & CCB_ALLOC) == 0) { 879 1.46 chs aprint_error_dev(sc->sc_dev, "exiting ccb not allocated!\n"); 880 1.1 dante Debugger(); 881 1.1 dante return; 882 1.1 dante } 883 1.1 dante /* 884 1.24 bouyer * 'qdonep' contains the command's ending status. 885 1.24 bouyer */ 886 1.6 dante #ifdef ASC_DEBUG 887 1.6 dante printf("d_s=%d, h_s=%d", qdonep->d3.done_stat, qdonep->d3.host_stat); 888 1.6 dante #endif 889 1.1 dante switch (qdonep->d3.done_stat) { 890 1.1 dante case ASC_QD_NO_ERROR: 891 1.1 dante switch (qdonep->d3.host_stat) { 892 1.1 dante case ASC_QHSTA_NO_ERROR: 893 1.1 dante xs->error = XS_NOERROR; 894 1.48 rin /* 895 1.48 rin * XXX 896 1.48 rin * According to the original Linux driver, xs->resid 897 1.48 rin * should be qdonep->remain_bytes. However, its value 898 1.48 rin * is bogus, which seems like a H/W bug. The best thing 899 1.48 rin * we can do would be to ignore it, assuming that all 900 1.48 rin * data has been successfully transferred... 901 1.48 rin */ 902 1.1 dante xs->resid = 0; 903 1.1 dante break; 904 1.1 dante 905 1.1 dante default: 906 1.1 dante /* QHSTA error occurred */ 907 1.1 dante xs->error = XS_DRIVER_STUFFUP; 908 1.1 dante break; 909 1.1 dante } 910 1.1 dante 911 1.1 dante /* 912 1.24 bouyer * If an INQUIRY command completed successfully, then call 913 1.24 bouyer * the AscInquiryHandling() function to patch bugged boards. 914 1.24 bouyer */ 915 1.1 dante if ((xs->cmd->opcode == SCSICMD_Inquiry) && 916 1.24 bouyer (xs->xs_periph->periph_lun == 0) && 917 1.1 dante (xs->datalen - qdonep->remain_bytes) >= 8) { 918 1.1 dante AscInquiryHandling(sc, 919 1.24 bouyer xs->xs_periph->periph_target & 0x7, 920 1.1 dante (ASC_SCSI_INQUIRY *) xs->data); 921 1.1 dante } 922 1.1 dante break; 923 1.1 dante 924 1.1 dante case ASC_QD_WITH_ERROR: 925 1.1 dante switch (qdonep->d3.host_stat) { 926 1.1 dante case ASC_QHSTA_NO_ERROR: 927 1.1 dante if (qdonep->d3.scsi_stat == SS_CHK_CONDITION) { 928 1.1 dante s1 = &ccb->scsi_sense; 929 1.1 dante s2 = &xs->sense.scsi_sense; 930 1.1 dante *s2 = *s1; 931 1.1 dante xs->error = XS_SENSE; 932 1.4 dante } else { 933 1.1 dante xs->error = XS_DRIVER_STUFFUP; 934 1.4 dante } 935 1.25 briggs break; 936 1.25 briggs 937 1.25 briggs case ASC_QHSTA_M_SEL_TIMEOUT: 938 1.26 briggs xs->error = XS_SELTIMEOUT; 939 1.1 dante break; 940 1.1 dante 941 1.1 dante default: 942 1.1 dante /* QHSTA error occurred */ 943 1.1 dante xs->error = XS_DRIVER_STUFFUP; 944 1.1 dante break; 945 1.1 dante } 946 1.1 dante break; 947 1.1 dante 948 1.1 dante case ASC_QD_ABORTED_BY_HOST: 949 1.1 dante default: 950 1.1 dante xs->error = XS_DRIVER_STUFFUP; 951 1.1 dante break; 952 1.1 dante } 953 1.1 dante 954 1.1 dante adv_free_ccb(sc, ccb); 955 1.1 dante scsipi_done(xs); 956 1.1 dante } 957