1 /* $OpenBSD: gdt_common.c,v 1.26 2003/06/28 23:56:40 avsm Exp $ */ 2 3 /* 4 * Copyright (c) 1999, 2000 Niklas Hallqvist. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27 /* 28 * This driver would not have written if it was not for the hardware donations 29 * from both ICP-Vortex and �ko.neT. I want to thank them for their support. 30 */ 31 32 #include <sys/param.h> 33 #include <sys/buf.h> 34 #include <sys/device.h> 35 #include <sys/ioctl.h> 36 #include <sys/kernel.h> 37 #include <sys/malloc.h> 38 #include <sys/systm.h> 39 40 #include <machine/bus.h> 41 42 #include <uvm/uvm_extern.h> 43 44 #include <scsi/scsi_all.h> 45 #include <scsi/scsi_disk.h> 46 #include <scsi/scsiconf.h> 47 48 #include <dev/biovar.h> 49 #include <dev/ic/gdtreg.h> 50 #include <dev/ic/gdtvar.h> 51 52 #include "bio.h" 53 54 #ifdef GDT_DEBUG 55 int gdt_maxcmds = GDT_MAXCMDS; 56 #undef GDT_MAXCMDS 57 #define GDT_MAXCMDS gdt_maxcmds 58 #endif 59 60 #define GDT_DRIVER_VERSION 1 61 #define GDT_DRIVER_SUBVERSION 1 62 63 int gdt_async_event(struct gdt_softc *, int); 64 void gdt_chain(struct gdt_softc *); 65 void gdt_clear_events(struct gdt_softc *); 66 void gdt_copy_internal_data(struct scsi_xfer *, u_int8_t *, size_t); 67 struct scsi_xfer *gdt_dequeue(struct gdt_softc *); 68 void gdt_enqueue(struct gdt_softc *, struct scsi_xfer *, int); 69 void gdt_enqueue_ccb(struct gdt_softc *, struct gdt_ccb *); 70 void gdt_eval_mapping(u_int32_t, int *, int *, int *); 71 int gdt_exec_ccb(struct gdt_ccb *); 72 void gdt_free_ccb(struct gdt_softc *, struct gdt_ccb *); 73 struct gdt_ccb *gdt_get_ccb(struct gdt_softc *, int); 74 int gdt_internal_cache_cmd(struct scsi_xfer *); 75 int gdt_internal_cmd(struct gdt_softc *, u_int8_t, u_int16_t, 76 u_int32_t, u_int32_t, u_int32_t); 77 #if NBIO > 0 78 int gdt_ioctl(struct device *, u_long, caddr_t); 79 #endif 80 int gdt_raw_scsi_cmd(struct scsi_xfer *); 81 int gdt_scsi_cmd(struct scsi_xfer *); 82 void gdt_start_ccbs(struct gdt_softc *); 83 int gdt_sync_event(struct gdt_softc *, int, u_int8_t, 84 struct scsi_xfer *); 85 void gdt_timeout(void *); 86 int gdt_wait(struct gdt_softc *, struct gdt_ccb *, int); 87 void gdt_watchdog(void *); 88 89 struct cfdriver gdt_cd = { 90 NULL, "gdt", DV_DULL 91 }; 92 93 struct scsi_adapter gdt_switch = { 94 gdt_scsi_cmd, gdtminphys, 0, 0, 95 }; 96 97 struct scsi_adapter gdt_raw_switch = { 98 gdt_raw_scsi_cmd, gdtminphys, 0, 0, 99 }; 100 101 struct scsi_device gdt_dev = { 102 NULL, NULL, NULL, NULL 103 }; 104 105 int gdt_cnt = 0; 106 u_int8_t gdt_polling; 107 u_int8_t gdt_from_wait; 108 struct gdt_softc *gdt_wait_gdt; 109 int gdt_wait_index; 110 #ifdef GDT_DEBUG 111 int gdt_debug = GDT_DEBUG; 112 #endif 113 114 int 115 gdt_attach(gdt) 116 struct gdt_softc *gdt; 117 { 118 u_int16_t cdev_cnt; 119 int i, id, drv_cyls, drv_hds, drv_secs, error, nsegs; 120 121 gdt_polling = 1; 122 gdt_from_wait = 0; 123 124 if (bus_dmamem_alloc(gdt->sc_dmat, GDT_SCRATCH_SZ, PAGE_SIZE, 0, 125 &gdt->sc_scratch_seg, 1, &nsegs, BUS_DMA_NOWAIT)) 126 panic("%s: bus_dmamem_alloc failed", gdt->sc_dev.dv_xname); 127 if (bus_dmamem_map(gdt->sc_dmat, &gdt->sc_scratch_seg, 1, 128 GDT_SCRATCH_SZ, &gdt->sc_scratch, BUS_DMA_NOWAIT)) 129 panic("%s: bus_dmamem_map failed", gdt->sc_dev.dv_xname); 130 131 gdt_clear_events(gdt); 132 133 TAILQ_INIT(&gdt->sc_free_ccb); 134 TAILQ_INIT(&gdt->sc_ccbq); 135 TAILQ_INIT(&gdt->sc_ucmdq); 136 LIST_INIT(&gdt->sc_queue); 137 138 /* Initialize the ccbs */ 139 for (i = 0; i < GDT_MAXCMDS; i++) { 140 gdt->sc_ccbs[i].gc_cmd_index = i + 2; 141 error = bus_dmamap_create(gdt->sc_dmat, 142 (GDT_MAXOFFSETS - 1) << PGSHIFT, GDT_MAXOFFSETS, 143 (GDT_MAXOFFSETS - 1) << PGSHIFT, 0, 144 BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, 145 &gdt->sc_ccbs[i].gc_dmamap_xfer); 146 if (error) { 147 printf("%s: cannot create ccb dmamap (%d)", 148 gdt->sc_dev.dv_xname, error); 149 return (1); 150 } 151 (void)gdt_ccb_set_cmd(gdt->sc_ccbs + i, GDT_GCF_UNUSED); 152 TAILQ_INSERT_TAIL(&gdt->sc_free_ccb, &gdt->sc_ccbs[i], 153 gc_chain); 154 } 155 156 /* Fill in the prototype scsi_link. */ 157 gdt->sc_link.adapter_softc = gdt; 158 gdt->sc_link.adapter = &gdt_switch; 159 gdt->sc_link.device = &gdt_dev; 160 /* XXX what is optimal? */ 161 gdt->sc_link.openings = GDT_MAXCMDS; 162 gdt->sc_link.adapter_buswidth = 163 (gdt->sc_class & GDT_FC) ? GDT_MAXID : GDT_MAX_HDRIVES; 164 gdt->sc_link.adapter_target = gdt->sc_link.adapter_buswidth; 165 166 if (!gdt_internal_cmd(gdt, GDT_SCREENSERVICE, GDT_INIT, 0, 0, 0)) { 167 printf("screen service initialization error %d\n", 168 gdt->sc_status); 169 return (1); 170 } 171 172 if (!gdt_internal_cmd(gdt, GDT_CACHESERVICE, GDT_INIT, GDT_LINUX_OS, 0, 173 0)) { 174 printf("cache service initialization error %d\n", 175 gdt->sc_status); 176 return (1); 177 } 178 179 if (!gdt_internal_cmd(gdt, GDT_CACHESERVICE, GDT_MOUNT, 0xffff, 1, 180 0)) { 181 printf("cache service mount error %d\n", 182 gdt->sc_status); 183 return (1); 184 } 185 186 if (!gdt_internal_cmd(gdt, GDT_CACHESERVICE, GDT_INIT, GDT_LINUX_OS, 0, 187 0)) { 188 printf("cache service post-mount initialization error %d\n", 189 gdt->sc_status); 190 return (1); 191 } 192 cdev_cnt = (u_int16_t)gdt->sc_info; 193 194 /* Detect number of busses */ 195 gdt_enc32(gdt->sc_scratch + GDT_IOC_VERSION, GDT_IOC_NEWEST); 196 gdt->sc_scratch[GDT_IOC_LIST_ENTRIES] = GDT_MAXBUS; 197 gdt->sc_scratch[GDT_IOC_FIRST_CHAN] = 0; 198 gdt->sc_scratch[GDT_IOC_LAST_CHAN] = GDT_MAXBUS - 1; 199 gdt_enc32(gdt->sc_scratch + GDT_IOC_LIST_OFFSET, GDT_IOC_HDR_SZ); 200 if (gdt_internal_cmd(gdt, GDT_CACHESERVICE, GDT_IOCTL, 201 GDT_IOCHAN_RAW_DESC, GDT_INVALID_CHANNEL, 202 GDT_IOC_HDR_SZ + GDT_RAWIOC_SZ)) { 203 gdt->sc_bus_cnt = gdt->sc_scratch[GDT_IOC_CHAN_COUNT]; 204 for (i = 0; i < gdt->sc_bus_cnt; i++) { 205 id = gdt->sc_scratch[GDT_IOC_HDR_SZ + 206 i * GDT_RAWIOC_SZ + GDT_RAWIOC_PROC_ID]; 207 gdt->sc_bus_id[id] = id < GDT_MAXBUS ? id : 0xff; 208 } 209 210 } else { 211 /* New method failed, use fallback. */ 212 gdt_enc32(gdt->sc_scratch + GDT_GETCH_CHANNEL_NO, i); 213 for (i = 0; i < GDT_MAXBUS; i++) { 214 if (!gdt_internal_cmd(gdt, GDT_CACHESERVICE, GDT_IOCTL, 215 GDT_SCSI_CHAN_CNT | GDT_L_CTRL_PATTERN, 216 GDT_IO_CHANNEL | GDT_INVALID_CHANNEL, 217 GDT_GETCH_SZ)) { 218 if (i == 0) { 219 printf("cannot get channel count, " 220 "error %d\n", gdt->sc_status); 221 return (1); 222 } 223 break; 224 } 225 gdt->sc_bus_id[i] = 226 (gdt->sc_scratch[GDT_GETCH_SIOP_ID] < GDT_MAXID) ? 227 gdt->sc_scratch[GDT_GETCH_SIOP_ID] : 0xff; 228 } 229 gdt->sc_bus_cnt = i; 230 } 231 232 /* Read cache configuration */ 233 if (!gdt_internal_cmd(gdt, GDT_CACHESERVICE, GDT_IOCTL, GDT_CACHE_INFO, 234 GDT_INVALID_CHANNEL, GDT_CINFO_SZ)) { 235 printf("cannot get cache info, error %d\n", gdt->sc_status); 236 return (1); 237 } 238 gdt->sc_cpar.cp_version = 239 gdt_dec32(gdt->sc_scratch + GDT_CPAR_VERSION); 240 gdt->sc_cpar.cp_state = gdt_dec16(gdt->sc_scratch + GDT_CPAR_STATE); 241 gdt->sc_cpar.cp_strategy = 242 gdt_dec16(gdt->sc_scratch + GDT_CPAR_STRATEGY); 243 gdt->sc_cpar.cp_write_back = 244 gdt_dec16(gdt->sc_scratch + GDT_CPAR_WRITE_BACK); 245 gdt->sc_cpar.cp_block_size = 246 gdt_dec16(gdt->sc_scratch + GDT_CPAR_BLOCK_SIZE); 247 248 /* Read board information and features */ 249 gdt->sc_more_proc = 0; 250 if (gdt_internal_cmd(gdt, GDT_CACHESERVICE, GDT_IOCTL, GDT_BOARD_INFO, 251 GDT_INVALID_CHANNEL, GDT_BINFO_SZ)) { 252 /* XXX A lot of these assignments can probably go later */ 253 gdt->sc_binfo.bi_ser_no = 254 gdt_dec32(gdt->sc_scratch + GDT_BINFO_SER_NO); 255 bcopy(gdt->sc_scratch + GDT_BINFO_OEM_ID, 256 gdt->sc_binfo.bi_oem_id, sizeof gdt->sc_binfo.bi_oem_id); 257 gdt->sc_binfo.bi_ep_flags = 258 gdt_dec16(gdt->sc_scratch + GDT_BINFO_EP_FLAGS); 259 gdt->sc_binfo.bi_proc_id = 260 gdt_dec32(gdt->sc_scratch + GDT_BINFO_PROC_ID); 261 gdt->sc_binfo.bi_memsize = 262 gdt_dec32(gdt->sc_scratch + GDT_BINFO_MEMSIZE); 263 gdt->sc_binfo.bi_mem_banks = 264 gdt->sc_scratch[GDT_BINFO_MEM_BANKS]; 265 gdt->sc_binfo.bi_chan_type = 266 gdt->sc_scratch[GDT_BINFO_CHAN_TYPE]; 267 gdt->sc_binfo.bi_chan_count = 268 gdt->sc_scratch[GDT_BINFO_CHAN_COUNT]; 269 gdt->sc_binfo.bi_rdongle_pres = 270 gdt->sc_scratch[GDT_BINFO_RDONGLE_PRES]; 271 gdt->sc_binfo.bi_epr_fw_ver = 272 gdt_dec32(gdt->sc_scratch + GDT_BINFO_EPR_FW_VER); 273 gdt->sc_binfo.bi_upd_fw_ver = 274 gdt_dec32(gdt->sc_scratch + GDT_BINFO_UPD_FW_VER); 275 gdt->sc_binfo.bi_upd_revision = 276 gdt_dec32(gdt->sc_scratch + GDT_BINFO_UPD_REVISION); 277 bcopy(gdt->sc_scratch + GDT_BINFO_TYPE_STRING, 278 gdt->sc_binfo.bi_type_string, 279 sizeof gdt->sc_binfo.bi_type_string); 280 bcopy(gdt->sc_scratch + GDT_BINFO_RAID_STRING, 281 gdt->sc_binfo.bi_raid_string, 282 sizeof gdt->sc_binfo.bi_raid_string); 283 gdt->sc_binfo.bi_update_pres = 284 gdt->sc_scratch[GDT_BINFO_UPDATE_PRES]; 285 gdt->sc_binfo.bi_xor_pres = 286 gdt->sc_scratch[GDT_BINFO_XOR_PRES]; 287 gdt->sc_binfo.bi_prom_type = 288 gdt->sc_scratch[GDT_BINFO_PROM_TYPE]; 289 gdt->sc_binfo.bi_prom_count = 290 gdt->sc_scratch[GDT_BINFO_PROM_COUNT]; 291 gdt->sc_binfo.bi_dup_pres = 292 gdt_dec32(gdt->sc_scratch + GDT_BINFO_DUP_PRES); 293 gdt->sc_binfo.bi_chan_pres = 294 gdt_dec32(gdt->sc_scratch + GDT_BINFO_CHAN_PRES); 295 gdt->sc_binfo.bi_mem_pres = 296 gdt_dec32(gdt->sc_scratch + GDT_BINFO_MEM_PRES); 297 gdt->sc_binfo.bi_ft_bus_system = 298 gdt->sc_scratch[GDT_BINFO_FT_BUS_SYSTEM]; 299 gdt->sc_binfo.bi_subtype_valid = 300 gdt->sc_scratch[GDT_BINFO_SUBTYPE_VALID]; 301 gdt->sc_binfo.bi_board_subtype = 302 gdt->sc_scratch[GDT_BINFO_BOARD_SUBTYPE]; 303 gdt->sc_binfo.bi_rampar_pres = 304 gdt->sc_scratch[GDT_BINFO_RAMPAR_PRES]; 305 306 if (gdt_internal_cmd(gdt, GDT_CACHESERVICE, GDT_IOCTL, 307 GDT_BOARD_FEATURES, GDT_INVALID_CHANNEL, GDT_BFEAT_SZ)) { 308 gdt->sc_bfeat.bf_chaining = 309 gdt->sc_scratch[GDT_BFEAT_CHAINING]; 310 gdt->sc_bfeat.bf_striping = 311 gdt->sc_scratch[GDT_BFEAT_STRIPING]; 312 gdt->sc_bfeat.bf_mirroring = 313 gdt->sc_scratch[GDT_BFEAT_MIRRORING]; 314 gdt->sc_bfeat.bf_raid = 315 gdt->sc_scratch[GDT_BFEAT_RAID]; 316 gdt->sc_more_proc = 1; 317 } 318 } else { 319 /* XXX Not implemented yet */ 320 } 321 322 /* Read more information */ 323 if (gdt->sc_more_proc) { 324 /* XXX Not implemented yet */ 325 } 326 327 if (!gdt_internal_cmd(gdt, GDT_SCSIRAWSERVICE, GDT_INIT, 0, 0, 0)) { 328 printf("raw service initialization error %d\n", 329 gdt->sc_status); 330 return (1); 331 } 332 333 /* Set/get features raw service (scatter/gather) */ 334 gdt->sc_raw_feat = 0; 335 if (gdt_internal_cmd(gdt, GDT_SCSIRAWSERVICE, GDT_SET_FEAT, 336 GDT_SCATTER_GATHER, 0, 0)) 337 if (gdt_internal_cmd(gdt, GDT_SCSIRAWSERVICE, GDT_GET_FEAT, 0, 338 0, 0)) 339 gdt->sc_raw_feat = gdt->sc_info; 340 341 /* Set/get features cache service (scatter/gather) */ 342 gdt->sc_cache_feat = 0; 343 if (gdt_internal_cmd(gdt, GDT_CACHESERVICE, GDT_SET_FEAT, 0, 344 GDT_SCATTER_GATHER, 0)) 345 if (gdt_internal_cmd(gdt, GDT_CACHESERVICE, GDT_GET_FEAT, 0, 0, 346 0)) 347 gdt->sc_cache_feat = gdt->sc_info; 348 349 /* XXX Linux reserve drives here, potentially */ 350 351 /* Scan for cache devices */ 352 for (i = 0; i < cdev_cnt && i < GDT_MAX_HDRIVES; i++) 353 if (gdt_internal_cmd(gdt, GDT_CACHESERVICE, GDT_INFO, i, 0, 354 0)) { 355 gdt->sc_hdr[i].hd_present = 1; 356 gdt->sc_hdr[i].hd_size = gdt->sc_info; 357 358 /* 359 * Evaluate mapping (sectors per head, heads per cyl) 360 */ 361 gdt->sc_hdr[i].hd_size &= ~GDT_SECS32; 362 if (gdt->sc_info2 == 0) 363 gdt_eval_mapping(gdt->sc_hdr[i].hd_size, 364 &drv_cyls, &drv_hds, &drv_secs); 365 else { 366 drv_hds = gdt->sc_info2 & 0xff; 367 drv_secs = (gdt->sc_info2 >> 8) & 0xff; 368 drv_cyls = gdt->sc_hdr[i].hd_size / drv_hds / 369 drv_secs; 370 } 371 gdt->sc_hdr[i].hd_heads = drv_hds; 372 gdt->sc_hdr[i].hd_secs = drv_secs; 373 /* Round the size */ 374 gdt->sc_hdr[i].hd_size = drv_cyls * drv_hds * drv_secs; 375 376 if (gdt_internal_cmd(gdt, GDT_CACHESERVICE, 377 GDT_DEVTYPE, i, 0, 0)) 378 gdt->sc_hdr[i].hd_devtype = gdt->sc_info; 379 } 380 381 printf("dpmem %x %d-bus %d cache device%s\n", gdt->sc_dpmembase, 382 gdt->sc_bus_cnt, cdev_cnt, cdev_cnt == 1 ? "" : "s"); 383 printf("%s: ver %x, cache %s, strategy %d, writeback %s, blksz %d\n", 384 gdt->sc_dev.dv_xname, gdt->sc_cpar.cp_version, 385 gdt->sc_cpar.cp_state ? "on" : "off", gdt->sc_cpar.cp_strategy, 386 gdt->sc_cpar.cp_write_back ? "on" : "off", 387 gdt->sc_cpar.cp_block_size); 388 #if 1 389 printf("%s: raw feat %x cache feat %x\n", gdt->sc_dev.dv_xname, 390 gdt->sc_raw_feat, gdt->sc_cache_feat); 391 #endif 392 393 #if NBIO > 0 394 if (bio_register(&gdt->sc_dev, gdt_ioctl) != 0) 395 panic("%s: controller registration failed", gdt->sc_dev.dv_xname); 396 #endif 397 gdt_cnt++; 398 399 config_found(&gdt->sc_dev, &gdt->sc_link, scsiprint); 400 401 gdt->sc_raw_link = malloc(gdt->sc_bus_cnt * sizeof (struct scsi_link), 402 M_DEVBUF, M_NOWAIT); 403 if (gdt->sc_raw_link == NULL) 404 panic("gdt_attach"); 405 bzero(gdt->sc_raw_link, gdt->sc_bus_cnt * sizeof (struct scsi_link)); 406 407 for (i = 0; i < gdt->sc_bus_cnt; i++) { 408 /* Fill in the prototype scsi_link. */ 409 gdt->sc_raw_link[i].adapter_softc = gdt; 410 gdt->sc_raw_link[i].adapter = &gdt_raw_switch; 411 gdt->sc_raw_link[i].adapter_target = 7; 412 gdt->sc_raw_link[i].device = &gdt_dev; 413 gdt->sc_raw_link[i].openings = 4; /* XXX a guess */ 414 gdt->sc_raw_link[i].adapter_buswidth = 415 (gdt->sc_class & GDT_FC) ? GDT_MAXID : 16; /* XXX */ 416 417 config_found(&gdt->sc_dev, &gdt->sc_raw_link[i], scsiprint); 418 } 419 420 gdt_polling = 0; 421 return (0); 422 } 423 424 void 425 gdt_eval_mapping(size, cyls, heads, secs) 426 u_int32_t size; 427 int *cyls, *heads, *secs; 428 { 429 *cyls = size / GDT_HEADS / GDT_SECS; 430 if (*cyls < GDT_MAXCYLS) { 431 *heads = GDT_HEADS; 432 *secs = GDT_SECS; 433 } else { 434 /* Too high for 64 * 32 */ 435 *cyls = size / GDT_MEDHEADS / GDT_MEDSECS; 436 if (*cyls < GDT_MAXCYLS) { 437 *heads = GDT_MEDHEADS; 438 *secs = GDT_MEDSECS; 439 } else { 440 /* Too high for 127 * 63 */ 441 *cyls = size / GDT_BIGHEADS / GDT_BIGSECS; 442 *heads = GDT_BIGHEADS; 443 *secs = GDT_BIGSECS; 444 } 445 } 446 } 447 448 /* 449 * Insert a command into the driver queue, either at the front or at the tail. 450 * It's ok to overload the freelist link as these structures are never on 451 * the freelist at this time. 452 */ 453 void 454 gdt_enqueue(gdt, xs, infront) 455 struct gdt_softc *gdt; 456 struct scsi_xfer *xs; 457 int infront; 458 { 459 if (infront || LIST_FIRST(&gdt->sc_queue) == NULL) { 460 if (LIST_FIRST(&gdt->sc_queue) == NULL) 461 gdt->sc_queuelast = xs; 462 LIST_INSERT_HEAD(&gdt->sc_queue, xs, free_list); 463 return; 464 } 465 LIST_INSERT_AFTER(gdt->sc_queuelast, xs, free_list); 466 gdt->sc_queuelast = xs; 467 } 468 469 /* 470 * Pull a command off the front of the driver queue. 471 */ 472 struct scsi_xfer * 473 gdt_dequeue(gdt) 474 struct gdt_softc *gdt; 475 { 476 struct scsi_xfer *xs; 477 478 xs = LIST_FIRST(&gdt->sc_queue); 479 if (xs == NULL) 480 return (NULL); 481 LIST_REMOVE(xs, free_list); 482 483 if (LIST_FIRST(&gdt->sc_queue) == NULL) 484 gdt->sc_queuelast = NULL; 485 486 return (xs); 487 } 488 489 /* 490 * Start a SCSI operation on a cache device. 491 * XXX Polled operation is not yet complete. What kind of locking do we need? 492 */ 493 int 494 gdt_scsi_cmd(xs) 495 struct scsi_xfer *xs; 496 { 497 struct scsi_link *link = xs->sc_link; 498 struct gdt_softc *gdt = link->adapter_softc; 499 u_int8_t target = link->target; 500 struct gdt_ccb *ccb; 501 #if 0 502 struct gdt_ucmd *ucmd; 503 #endif 504 u_int32_t blockno, blockcnt; 505 struct scsi_rw *rw; 506 struct scsi_rw_big *rwb; 507 bus_dmamap_t xfer; 508 int error, retval = SUCCESSFULLY_QUEUED; 509 gdt_lock_t lock; 510 511 GDT_DPRINTF(GDT_D_CMD, ("gdt_scsi_cmd ")); 512 513 xs->error = XS_NOERROR; 514 515 if (target >= GDT_MAX_HDRIVES || !gdt->sc_hdr[target].hd_present || 516 link->lun != 0) { 517 /* 518 * XXX Should be XS_SENSE but that would require setting up a 519 * faked sense too. 520 */ 521 xs->error = XS_DRIVER_STUFFUP; 522 xs->flags |= ITSDONE; 523 scsi_done(xs); 524 return (COMPLETE); 525 } 526 527 lock = GDT_LOCK_GDT(lock); 528 529 /* Don't double enqueue if we came from gdt_chain. */ 530 if (xs != LIST_FIRST(&gdt->sc_queue)) 531 gdt_enqueue(gdt, xs, 0); 532 533 while ((xs = gdt_dequeue(gdt)) != NULL) { 534 xs->error = XS_NOERROR; 535 ccb = NULL; 536 link = xs->sc_link; 537 target = link->target; 538 539 if (!gdt_polling && !(xs->flags & SCSI_POLL) && 540 gdt->sc_test_busy(gdt)) { 541 /* 542 * Put it back in front. XXX Should we instead 543 * set xs->error to XS_BUSY? 544 */ 545 gdt_enqueue(gdt, xs, 1); 546 break; 547 } 548 549 switch (xs->cmd->opcode) { 550 case TEST_UNIT_READY: 551 case REQUEST_SENSE: 552 case INQUIRY: 553 case MODE_SENSE: 554 case START_STOP: 555 case READ_CAPACITY: 556 #if 0 557 case VERIFY: 558 #endif 559 if (!gdt_internal_cache_cmd(xs)) { 560 GDT_UNLOCK_GDT(gdt, lock); 561 return (TRY_AGAIN_LATER); 562 } 563 xs->flags |= ITSDONE; 564 scsi_done(xs); 565 goto ready; 566 567 case PREVENT_ALLOW: 568 GDT_DPRINTF(GDT_D_CMD, ("PREVENT/ALLOW ")); 569 /* XXX Not yet implemented */ 570 xs->error = XS_NOERROR; 571 xs->flags |= ITSDONE; 572 scsi_done(xs); 573 goto ready; 574 575 default: 576 GDT_DPRINTF(GDT_D_CMD, 577 ("unknown opc %d ", xs->cmd->opcode)); 578 /* XXX Not yet implemented */ 579 xs->error = XS_DRIVER_STUFFUP; 580 xs->flags |= ITSDONE; 581 scsi_done(xs); 582 goto ready; 583 584 case READ_COMMAND: 585 case READ_BIG: 586 case WRITE_COMMAND: 587 case WRITE_BIG: 588 case SYNCHRONIZE_CACHE: 589 /* 590 * A new command chain, start from the beginning. 591 */ 592 gdt->sc_cmd_off = 0; 593 594 if (xs->cmd->opcode != SYNCHRONIZE_CACHE) { 595 /* A read or write operation. */ 596 if (xs->cmdlen == 6) { 597 rw = (struct scsi_rw *)xs->cmd; 598 blockno = _3btol(rw->addr) & 599 (SRW_TOPADDR << 16 | 0xffff); 600 blockcnt = 601 rw->length ? rw->length : 0x100; 602 } else { 603 rwb = (struct scsi_rw_big *)xs->cmd; 604 blockno = _4btol(rwb->addr); 605 blockcnt = _2btol(rwb->length); 606 } 607 if (blockno >= gdt->sc_hdr[target].hd_size || 608 blockno + blockcnt > 609 gdt->sc_hdr[target].hd_size) { 610 printf( 611 "%s: out of bounds %u-%u >= %u\n", 612 gdt->sc_dev.dv_xname, blockno, 613 blockcnt, 614 gdt->sc_hdr[target].hd_size); 615 /* 616 * XXX Should be XS_SENSE but that 617 * would require setting up a faked 618 * sense too. 619 */ 620 xs->error = XS_DRIVER_STUFFUP; 621 xs->flags |= ITSDONE; 622 scsi_done(xs); 623 goto ready; 624 } 625 } 626 627 ccb = gdt_get_ccb(gdt, xs->flags); 628 /* 629 * We are out of commands, try again in a little while. 630 */ 631 if (ccb == NULL) { 632 xs->error = XS_DRIVER_STUFFUP; 633 GDT_UNLOCK_GDT(gdt, lock); 634 return (TRY_AGAIN_LATER); 635 } 636 637 ccb->gc_blockno = blockno; 638 ccb->gc_blockcnt = blockcnt; 639 ccb->gc_xs = xs; 640 ccb->gc_timeout = xs->timeout; 641 ccb->gc_service = GDT_CACHESERVICE; 642 gdt_ccb_set_cmd(ccb, GDT_GCF_SCSI); 643 644 if (xs->cmd->opcode != SYNCHRONIZE_CACHE) { 645 xfer = ccb->gc_dmamap_xfer; 646 error = bus_dmamap_load(gdt->sc_dmat, xfer, 647 xs->data, xs->datalen, NULL, 648 (xs->flags & SCSI_NOSLEEP) ? 649 BUS_DMA_NOWAIT : BUS_DMA_WAITOK); 650 if (error) { 651 printf("%s: gdt_scsi_cmd: ", 652 gdt->sc_dev.dv_xname); 653 if (error == EFBIG) 654 printf( 655 "more than %d dma segs\n", 656 GDT_MAXOFFSETS); 657 else 658 printf("error %d " 659 "loading dma map\n", 660 error); 661 662 gdt_free_ccb(gdt, ccb); 663 xs->error = XS_DRIVER_STUFFUP; 664 xs->flags |= ITSDONE; 665 scsi_done(xs); 666 goto ready; 667 } 668 bus_dmamap_sync(gdt->sc_dmat, xfer, 0, 669 xfer->dm_mapsize, 670 (xs->flags & SCSI_DATA_IN) ? 671 BUS_DMASYNC_PREREAD : 672 BUS_DMASYNC_PREWRITE); 673 } 674 675 gdt_enqueue_ccb(gdt, ccb); 676 /* XXX what if enqueue did not start a transfer? */ 677 if (gdt_polling || (xs->flags & SCSI_POLL)) { 678 if (!gdt_wait(gdt, ccb, ccb->gc_timeout)) { 679 GDT_UNLOCK_GDT(gdt, lock); 680 printf("%s: command %d timed out\n", 681 gdt->sc_dev.dv_xname, 682 ccb->gc_cmd_index); 683 xs->error = XS_TIMEOUT; 684 return (TRY_AGAIN_LATER); 685 } 686 xs->flags |= ITSDONE; 687 scsi_done(xs); 688 } 689 } 690 691 ready: 692 /* 693 * Don't process the queue if we are polling. 694 */ 695 if (xs->flags & SCSI_POLL) { 696 retval = COMPLETE; 697 break; 698 } 699 } 700 701 GDT_UNLOCK_GDT(gdt, lock); 702 return (retval); 703 } 704 705 /* XXX Currently only for cacheservice, returns 0 if busy */ 706 int 707 gdt_exec_ccb(ccb) 708 struct gdt_ccb *ccb; 709 { 710 struct scsi_xfer *xs = ccb->gc_xs; 711 struct scsi_link *link = xs->sc_link; 712 struct gdt_softc *gdt = link->adapter_softc; 713 u_int8_t target = link->target; 714 u_int32_t sg_canz; 715 bus_dmamap_t xfer; 716 int i; 717 718 GDT_DPRINTF(GDT_D_CMD, ("gdt_exec_ccb(%p, %p) ", xs, ccb)); 719 720 gdt->sc_cmd_cnt = 0; 721 722 /* 723 * XXX Yeah I know it's an always-true condition, but that may change 724 * later. 725 */ 726 if (gdt->sc_cmd_cnt == 0) 727 gdt->sc_set_sema0(gdt); 728 729 gdt_enc32(gdt->sc_cmd + GDT_CMD_COMMANDINDEX, ccb->gc_cmd_index); 730 gdt_enc32(gdt->sc_cmd + GDT_CMD_BOARDNODE, GDT_LOCALBOARD); 731 gdt_enc16(gdt->sc_cmd + GDT_CMD_UNION + GDT_CACHE_DEVICENO, 732 target); 733 734 switch (xs->cmd->opcode) { 735 case PREVENT_ALLOW: 736 case SYNCHRONIZE_CACHE: 737 if (xs->cmd->opcode == PREVENT_ALLOW) { 738 /* XXX PREVENT_ALLOW support goes here */ 739 } else { 740 GDT_DPRINTF(GDT_D_CMD, 741 ("SYNCHRONIZE CACHE tgt %d ", target)); 742 gdt->sc_cmd[GDT_CMD_OPCODE] = GDT_FLUSH; 743 } 744 gdt_enc32(gdt->sc_cmd + GDT_CMD_UNION + GDT_CACHE_BLOCKNO, 745 1); 746 sg_canz = 0; 747 break; 748 749 case WRITE_COMMAND: 750 case WRITE_BIG: 751 /* XXX WRITE_THR could be supported too */ 752 gdt->sc_cmd[GDT_CMD_OPCODE] = GDT_WRITE; 753 break; 754 755 case READ_COMMAND: 756 case READ_BIG: 757 gdt->sc_cmd[GDT_CMD_OPCODE] = GDT_READ; 758 break; 759 } 760 761 if (xs->cmd->opcode != PREVENT_ALLOW && 762 xs->cmd->opcode != SYNCHRONIZE_CACHE) { 763 gdt_enc32(gdt->sc_cmd + GDT_CMD_UNION + GDT_CACHE_BLOCKNO, 764 ccb->gc_blockno); 765 gdt_enc32(gdt->sc_cmd + GDT_CMD_UNION + GDT_CACHE_BLOCKCNT, 766 ccb->gc_blockcnt); 767 768 xfer = ccb->gc_dmamap_xfer; 769 if (gdt->sc_cache_feat & GDT_SCATTER_GATHER) { 770 gdt_enc32( 771 gdt->sc_cmd + GDT_CMD_UNION + GDT_CACHE_DESTADDR, 772 0xffffffff); 773 for (i = 0; i < xfer->dm_nsegs; i++) { 774 gdt_enc32(gdt->sc_cmd + GDT_CMD_UNION + 775 GDT_CACHE_SG_LST + i * GDT_SG_SZ + 776 GDT_SG_PTR, 777 xfer->dm_segs[i].ds_addr); 778 gdt_enc32(gdt->sc_cmd + GDT_CMD_UNION + 779 GDT_CACHE_SG_LST + i * GDT_SG_SZ + 780 GDT_SG_LEN, 781 xfer->dm_segs[i].ds_len); 782 GDT_DPRINTF(GDT_D_IO, 783 ("#%d va %p pa %p len %x\n", i, buf, 784 xfer->dm_segs[i].ds_addr, 785 xfer->dm_segs[i].ds_len)); 786 } 787 sg_canz = xfer->dm_nsegs; 788 gdt_enc32( 789 gdt->sc_cmd + GDT_CMD_UNION + GDT_CACHE_SG_LST + 790 sg_canz * GDT_SG_SZ + GDT_SG_LEN, 0); 791 } else { 792 /* XXX Hardly correct */ 793 gdt_enc32( 794 gdt->sc_cmd + GDT_CMD_UNION + GDT_CACHE_DESTADDR, 795 xfer->dm_segs[0].ds_addr); 796 sg_canz = 0; 797 } 798 } 799 gdt_enc32(gdt->sc_cmd + GDT_CMD_UNION + GDT_CACHE_SG_CANZ, sg_canz); 800 801 gdt->sc_cmd_len = 802 roundup(GDT_CMD_UNION + GDT_CACHE_SG_LST + sg_canz * GDT_SG_SZ, 803 sizeof (u_int32_t)); 804 805 if (gdt->sc_cmd_cnt > 0 && 806 gdt->sc_cmd_off + gdt->sc_cmd_len + GDT_DPMEM_COMMAND_OFFSET > 807 gdt->sc_ic_all_size) { 808 printf("%s: DPMEM overflow\n", gdt->sc_dev.dv_xname); 809 gdt_free_ccb(gdt, ccb); 810 xs->error = XS_BUSY; 811 return (0); 812 } 813 814 gdt->sc_copy_cmd(gdt, ccb); 815 gdt->sc_release_event(gdt, ccb); 816 817 xs->error = XS_NOERROR; 818 xs->resid = 0; 819 return (1); 820 } 821 822 void 823 gdt_copy_internal_data(xs, data, size) 824 struct scsi_xfer *xs; 825 u_int8_t *data; 826 size_t size; 827 { 828 size_t copy_cnt; 829 830 GDT_DPRINTF(GDT_D_MISC, ("gdt_copy_internal_data ")); 831 832 if (!xs->datalen) 833 printf("uio move not yet supported\n"); 834 else { 835 copy_cnt = MIN(size, xs->datalen); 836 bcopy(data, xs->data, copy_cnt); 837 } 838 } 839 840 /* Emulated SCSI operation on cache device */ 841 int 842 gdt_internal_cache_cmd(xs) 843 struct scsi_xfer *xs; 844 { 845 struct scsi_link *link = xs->sc_link; 846 struct gdt_softc *gdt = link->adapter_softc; 847 struct scsi_inquiry_data inq; 848 struct scsi_sense_data sd; 849 struct { 850 struct scsi_mode_header hd; 851 struct scsi_blk_desc bd; 852 union scsi_disk_pages dp; 853 } mpd; 854 struct scsi_read_cap_data rcd; 855 u_int8_t target = link->target; 856 857 GDT_DPRINTF(GDT_D_CMD, ("gdt_internal_cache_cmd ")); 858 859 switch (xs->cmd->opcode) { 860 case TEST_UNIT_READY: 861 case START_STOP: 862 #if 0 863 case VERIFY: 864 #endif 865 GDT_DPRINTF(GDT_D_CMD, ("opc %d tgt %d ", xs->cmd->opcode, 866 target)); 867 break; 868 869 case REQUEST_SENSE: 870 GDT_DPRINTF(GDT_D_CMD, ("REQUEST SENSE tgt %d ", target)); 871 bzero(&sd, sizeof sd); 872 sd.error_code = 0x70; 873 sd.segment = 0; 874 sd.flags = SKEY_NO_SENSE; 875 gdt_enc32(sd.info, 0); 876 sd.extra_len = 0; 877 gdt_copy_internal_data(xs, (u_int8_t *)&sd, sizeof sd); 878 break; 879 880 case INQUIRY: 881 GDT_DPRINTF(GDT_D_CMD, ("INQUIRY tgt %d devtype %x ", target, 882 gdt->sc_hdr[target].hd_devtype)); 883 bzero(&inq, sizeof inq); 884 inq.device = 885 (gdt->sc_hdr[target].hd_devtype & 4) ? T_CDROM : T_DIRECT; 886 inq.dev_qual2 = 887 (gdt->sc_hdr[target].hd_devtype & 1) ? SID_REMOVABLE : 0; 888 inq.version = 2; 889 inq.response_format = 2; 890 inq.additional_length = 32; 891 strlcpy(inq.vendor, "ICP ", sizeof inq.vendor); 892 snprintf(inq.product, sizeof inq.product, "Host drive #%02d", 893 target); 894 strlcpy(inq.revision, " ", sizeof inq.revision); 895 gdt_copy_internal_data(xs, (u_int8_t *)&inq, sizeof inq); 896 break; 897 898 case MODE_SENSE: 899 GDT_DPRINTF(GDT_D_CMD, ("MODE SENSE tgt %d ", target)); 900 901 bzero(&mpd, sizeof mpd); 902 switch (((struct scsi_mode_sense *)xs->cmd)->page) { 903 case 4: 904 /* scsi_disk.h says this should be 0x16 */ 905 mpd.dp.rigid_geometry.pg_length = 0x16; 906 mpd.hd.data_length = sizeof mpd.hd + sizeof mpd.bd + 907 mpd.dp.rigid_geometry.pg_length; 908 mpd.hd.blk_desc_len = sizeof mpd.bd; 909 910 /* XXX */ 911 mpd.hd.dev_spec = 912 (gdt->sc_hdr[target].hd_devtype & 2) ? 0x80 : 0; 913 _lto3b(GDT_SECTOR_SIZE, mpd.bd.blklen); 914 mpd.dp.rigid_geometry.pg_code = 4; 915 _lto3b(gdt->sc_hdr[target].hd_size / 916 gdt->sc_hdr[target].hd_heads / 917 gdt->sc_hdr[target].hd_secs, 918 mpd.dp.rigid_geometry.ncyl); 919 mpd.dp.rigid_geometry.nheads = 920 gdt->sc_hdr[target].hd_heads; 921 gdt_copy_internal_data(xs, (u_int8_t *)&mpd, 922 sizeof mpd); 923 break; 924 925 default: 926 printf("%s: mode sense page %d not simulated\n", 927 gdt->sc_dev.dv_xname, 928 ((struct scsi_mode_sense *)xs->cmd)->page); 929 xs->error = XS_DRIVER_STUFFUP; 930 return (0); 931 } 932 break; 933 934 case READ_CAPACITY: 935 GDT_DPRINTF(GDT_D_CMD, ("READ CAPACITY tgt %d ", target)); 936 bzero(&rcd, sizeof rcd); 937 _lto4b(gdt->sc_hdr[target].hd_size - 1, rcd.addr); 938 _lto4b(GDT_SECTOR_SIZE, rcd.length); 939 gdt_copy_internal_data(xs, (u_int8_t *)&rcd, sizeof rcd); 940 break; 941 942 default: 943 printf("gdt_internal_cache_cmd got bad opcode: %d\n", 944 xs->cmd->opcode); 945 xs->error = XS_DRIVER_STUFFUP; 946 return (0); 947 } 948 949 xs->error = XS_NOERROR; 950 return (1); 951 } 952 953 /* Start a raw SCSI operation */ 954 int 955 gdt_raw_scsi_cmd(xs) 956 struct scsi_xfer *xs; 957 { 958 GDT_DPRINTF(GDT_D_CMD, ("gdt_raw_scsi_cmd ")); 959 960 /* XXX Not yet implemented */ 961 xs->error = XS_DRIVER_STUFFUP; 962 return (COMPLETE); 963 } 964 965 void 966 gdt_clear_events(gdt) 967 struct gdt_softc *gdt; 968 { 969 GDT_DPRINTF(GDT_D_MISC, ("gdt_clear_events(%p) ", gdt)); 970 971 /* XXX To be implemented */ 972 } 973 974 int 975 gdt_async_event(gdt, service) 976 struct gdt_softc *gdt; 977 int service; 978 { 979 GDT_DPRINTF(GDT_D_INTR, ("gdt_async_event(%p, %d) ", gdt, service)); 980 981 if (service == GDT_SCREENSERVICE) { 982 /* XXX To be implemented */ 983 } else { 984 /* XXX To be implemented */ 985 } 986 987 return (0); 988 } 989 990 int 991 gdt_sync_event(gdt, service, index, xs) 992 struct gdt_softc *gdt; 993 int service; 994 u_int8_t index; 995 struct scsi_xfer *xs; 996 { 997 GDT_DPRINTF(GDT_D_INTR, 998 ("gdt_sync_event(%p, %d, %d, %p) ", gdt, service, index, xs)); 999 1000 if (service == GDT_SCREENSERVICE) { 1001 GDT_DPRINTF(GDT_D_INTR, ("service == GDT_SCREENSERVICE ")); 1002 /* XXX To be implemented */ 1003 return (0); 1004 } else { 1005 switch (gdt->sc_status) { 1006 case GDT_S_OK: 1007 GDT_DPRINTF(GDT_D_INTR, ("sc_status == GDT_S_OK ")); 1008 /* XXX To be implemented */ 1009 break; 1010 case GDT_S_BSY: 1011 GDT_DPRINTF(GDT_D_INTR, ("sc_status == GDT_S_BSY ")); 1012 /* XXX To be implemented */ 1013 return (2); 1014 default: 1015 GDT_DPRINTF(GDT_D_INTR, ("sc_status is %d ", 1016 gdt->sc_status)); 1017 /* XXX To be implemented */ 1018 return (0); 1019 } 1020 } 1021 1022 return (1); 1023 } 1024 1025 int 1026 gdt_intr(arg) 1027 void *arg; 1028 { 1029 struct gdt_softc *gdt = arg; 1030 struct gdt_intr_ctx ctx; 1031 int chain = 1; 1032 int sync_val = 0; 1033 struct scsi_xfer *xs; 1034 int prev_cmd; 1035 struct gdt_ccb *ccb; 1036 gdt_lock_t lock; 1037 1038 GDT_DPRINTF(GDT_D_INTR, ("gdt_intr(%p) ", gdt)); 1039 1040 /* If polling and we were not called from gdt_wait, just return */ 1041 if (gdt_polling && !gdt_from_wait) 1042 return (0); 1043 1044 if (!gdt_polling) 1045 lock = GDT_LOCK_GDT(gdt); 1046 1047 ctx.istatus = gdt->sc_get_status(gdt); 1048 if (!ctx.istatus) { 1049 if (!gdt_polling) 1050 GDT_UNLOCK_GDT(gdt, lock); 1051 gdt->sc_status = GDT_S_NO_STATUS; 1052 return (0); 1053 } 1054 1055 gdt_wait_index = 0; 1056 ctx.service = ctx.info2 = 0; 1057 1058 gdt->sc_intr(gdt, &ctx); 1059 1060 gdt->sc_status = ctx.cmd_status; 1061 gdt->sc_info = ctx.info; 1062 gdt->sc_info2 = ctx.info2; 1063 1064 if (gdt_from_wait) { 1065 gdt_wait_gdt = gdt; 1066 gdt_wait_index = ctx.istatus; 1067 } 1068 1069 switch (ctx.istatus) { 1070 case GDT_ASYNCINDEX: 1071 gdt_async_event(gdt, ctx.service); 1072 goto finish; 1073 1074 case GDT_SPEZINDEX: 1075 printf("%s: uninitialized or unknown service (%d %d)\n", 1076 gdt->sc_dev.dv_xname, ctx.info, ctx.info2); 1077 chain = 0; 1078 goto finish; 1079 } 1080 1081 ccb = &gdt->sc_ccbs[ctx.istatus - 2]; 1082 xs = ccb->gc_xs; 1083 if (!gdt_polling) 1084 timeout_del(&xs->stimeout); 1085 ctx.service = ccb->gc_service; 1086 prev_cmd = ccb->gc_flags & GDT_GCF_CMD_MASK; 1087 if (xs && xs->cmd->opcode != PREVENT_ALLOW && 1088 xs->cmd->opcode != SYNCHRONIZE_CACHE) { 1089 bus_dmamap_sync(gdt->sc_dmat, ccb->gc_dmamap_xfer, 0, 1090 ccb->gc_dmamap_xfer->dm_mapsize, 1091 (xs->flags & SCSI_DATA_IN) ? BUS_DMASYNC_POSTREAD : 1092 BUS_DMASYNC_POSTWRITE); 1093 bus_dmamap_unload(gdt->sc_dmat, ccb->gc_dmamap_xfer); 1094 } 1095 gdt_free_ccb(gdt, ccb); 1096 switch (prev_cmd) { 1097 case GDT_GCF_UNUSED: 1098 /* XXX Not yet implemented */ 1099 chain = 0; 1100 goto finish; 1101 case GDT_GCF_INTERNAL: 1102 chain = 0; 1103 goto finish; 1104 } 1105 1106 sync_val = gdt_sync_event(gdt, ctx.service, ctx.istatus, xs); 1107 1108 finish: 1109 if (!gdt_polling) 1110 GDT_UNLOCK_GDT(gdt, lock); 1111 1112 switch (sync_val) { 1113 case 1: 1114 xs->flags |= ITSDONE; 1115 scsi_done(xs); 1116 break; 1117 1118 case 2: 1119 gdt_enqueue(gdt, xs, 0); 1120 } 1121 1122 if (chain) 1123 gdt_chain(gdt); 1124 return (1); 1125 } 1126 1127 void 1128 gdtminphys(bp) 1129 struct buf *bp; 1130 { 1131 GDT_DPRINTF(GDT_D_MISC, ("gdtminphys(0x%x) ", bp)); 1132 1133 /* As this is way more than MAXPHYS it's really not necessary. */ 1134 if ((GDT_MAXOFFSETS - 1) * PAGE_SIZE < MAXPHYS && 1135 bp->b_bcount > ((GDT_MAXOFFSETS - 1) * PAGE_SIZE)) 1136 bp->b_bcount = ((GDT_MAXOFFSETS - 1) * PAGE_SIZE); 1137 1138 minphys(bp); 1139 } 1140 1141 int 1142 gdt_wait(gdt, ccb, timeout) 1143 struct gdt_softc *gdt; 1144 struct gdt_ccb *ccb; 1145 int timeout; 1146 { 1147 int rv = 0; 1148 1149 GDT_DPRINTF(GDT_D_MISC, 1150 ("gdt_wait(%p, %p, %d) ", gdt, ccb, timeout)); 1151 1152 gdt_from_wait = 1; 1153 do { 1154 if (gdt_intr(gdt) && gdt == gdt_wait_gdt && 1155 ccb->gc_cmd_index == gdt_wait_index) { 1156 rv = 1; 1157 break; 1158 } 1159 DELAY(1); 1160 } while (--timeout); 1161 gdt_from_wait = 0; 1162 1163 while (gdt->sc_test_busy(gdt)) 1164 DELAY(0); /* XXX correct? */ 1165 1166 return (rv); 1167 } 1168 1169 int 1170 gdt_internal_cmd(gdt, service, opcode, arg1, arg2, arg3) 1171 struct gdt_softc *gdt; 1172 u_int8_t service; 1173 u_int16_t opcode; 1174 u_int32_t arg1, arg2, arg3; 1175 { 1176 int retries; 1177 struct gdt_ccb *ccb; 1178 1179 GDT_DPRINTF(GDT_D_CMD, ("gdt_internal_cmd(%p, %d, %d, %d, %d, %d) ", 1180 gdt, service, opcode, arg1, arg2, arg3)); 1181 1182 bzero(gdt->sc_cmd, GDT_CMD_SZ); 1183 1184 for (retries = GDT_RETRIES; ; ) { 1185 ccb = gdt_get_ccb(gdt, SCSI_NOSLEEP); 1186 if (ccb == NULL) { 1187 printf("%s: no free command index found\n", 1188 gdt->sc_dev.dv_xname); 1189 return (0); 1190 } 1191 ccb->gc_service = service; 1192 gdt_ccb_set_cmd(ccb, GDT_GCF_INTERNAL); 1193 1194 gdt->sc_set_sema0(gdt); 1195 gdt_enc32(gdt->sc_cmd + GDT_CMD_COMMANDINDEX, 1196 ccb->gc_cmd_index); 1197 gdt_enc16(gdt->sc_cmd + GDT_CMD_OPCODE, opcode); 1198 gdt_enc32(gdt->sc_cmd + GDT_CMD_BOARDNODE, GDT_LOCALBOARD); 1199 1200 switch (service) { 1201 case GDT_CACHESERVICE: 1202 if (opcode == GDT_IOCTL) { 1203 gdt_enc32(gdt->sc_cmd + GDT_CMD_UNION + 1204 GDT_IOCTL_SUBFUNC, arg1); 1205 gdt_enc32(gdt->sc_cmd + GDT_CMD_UNION + 1206 GDT_IOCTL_CHANNEL, arg2); 1207 gdt_enc16(gdt->sc_cmd + GDT_CMD_UNION + 1208 GDT_IOCTL_PARAM_SIZE, (u_int16_t)arg3); 1209 gdt_enc32(gdt->sc_cmd + GDT_CMD_UNION + 1210 GDT_IOCTL_P_PARAM, 1211 gdt->sc_scratch_seg.ds_addr); 1212 } else { 1213 gdt_enc16(gdt->sc_cmd + GDT_CMD_UNION + 1214 GDT_CACHE_DEVICENO, (u_int16_t)arg1); 1215 gdt_enc32(gdt->sc_cmd + GDT_CMD_UNION + 1216 GDT_CACHE_BLOCKNO, arg2); 1217 } 1218 break; 1219 1220 case GDT_SCSIRAWSERVICE: 1221 gdt_enc32(gdt->sc_cmd + GDT_CMD_UNION + 1222 GDT_RAW_DIRECTION, arg1); 1223 gdt->sc_cmd[GDT_CMD_UNION + GDT_RAW_BUS] = 1224 (u_int8_t)arg2; 1225 gdt->sc_cmd[GDT_CMD_UNION + GDT_RAW_TARGET] = 1226 (u_int8_t)arg3; 1227 gdt->sc_cmd[GDT_CMD_UNION + GDT_RAW_LUN] = 1228 (u_int8_t)(arg3 >> 8); 1229 } 1230 1231 gdt->sc_cmd_len = GDT_CMD_SZ; 1232 gdt->sc_cmd_off = 0; 1233 gdt->sc_cmd_cnt = 0; 1234 gdt->sc_copy_cmd(gdt, ccb); 1235 gdt->sc_release_event(gdt, ccb); 1236 DELAY(20); 1237 if (!gdt_wait(gdt, ccb, GDT_POLL_TIMEOUT)) 1238 return (0); 1239 if (gdt->sc_status != GDT_S_BSY || --retries == 0) 1240 break; 1241 DELAY(1); 1242 } 1243 return (gdt->sc_status == GDT_S_OK); 1244 } 1245 1246 struct gdt_ccb * 1247 gdt_get_ccb(gdt, flags) 1248 struct gdt_softc *gdt; 1249 int flags; 1250 { 1251 struct gdt_ccb *ccb; 1252 gdt_lock_t lock; 1253 1254 GDT_DPRINTF(GDT_D_QUEUE, ("gdt_get_ccb(%p, 0x%x) ", gdt, flags)); 1255 1256 lock = GDT_LOCK_GDT(gdt); 1257 1258 for (;;) { 1259 ccb = TAILQ_FIRST(&gdt->sc_free_ccb); 1260 if (ccb != NULL) 1261 break; 1262 if (flags & SCSI_NOSLEEP) 1263 goto bail_out; 1264 tsleep(&gdt->sc_free_ccb, PRIBIO, "gdt_ccb", 0); 1265 } 1266 1267 TAILQ_REMOVE(&gdt->sc_free_ccb, ccb, gc_chain); 1268 1269 bail_out: 1270 GDT_UNLOCK_GDT(gdt, lock); 1271 return (ccb); 1272 } 1273 1274 void 1275 gdt_free_ccb(gdt, ccb) 1276 struct gdt_softc *gdt; 1277 struct gdt_ccb *ccb; 1278 { 1279 gdt_lock_t lock; 1280 1281 GDT_DPRINTF(GDT_D_QUEUE, ("gdt_free_ccb(%p, %p) ", gdt, ccb)); 1282 1283 lock = GDT_LOCK_GDT(gdt); 1284 1285 TAILQ_INSERT_HEAD(&gdt->sc_free_ccb, ccb, gc_chain); 1286 1287 /* If the free list was empty, wake up potential waiters. */ 1288 if (TAILQ_NEXT(ccb, gc_chain) == NULL) 1289 wakeup(&gdt->sc_free_ccb); 1290 1291 GDT_UNLOCK_GDT(gdt, lock); 1292 } 1293 1294 void 1295 gdt_enqueue_ccb(gdt, ccb) 1296 struct gdt_softc *gdt; 1297 struct gdt_ccb *ccb; 1298 { 1299 GDT_DPRINTF(GDT_D_QUEUE, ("gdt_enqueue_ccb(%p, %p) ", gdt, ccb)); 1300 1301 timeout_set(&ccb->gc_xs->stimeout, gdt_timeout, ccb); 1302 TAILQ_INSERT_TAIL(&gdt->sc_ccbq, ccb, gc_chain); 1303 gdt_start_ccbs(gdt); 1304 } 1305 1306 void 1307 gdt_start_ccbs(gdt) 1308 struct gdt_softc *gdt; 1309 { 1310 struct gdt_ccb *ccb; 1311 struct scsi_xfer *xs; 1312 1313 GDT_DPRINTF(GDT_D_QUEUE, ("gdt_start_ccbs(%p) ", gdt)); 1314 1315 while ((ccb = TAILQ_FIRST(&gdt->sc_ccbq)) != NULL) { 1316 1317 xs = ccb->gc_xs; 1318 if (ccb->gc_flags & GDT_GCF_WATCHDOG) 1319 timeout_del(&xs->stimeout); 1320 1321 if (gdt_exec_ccb(ccb) == 0) { 1322 ccb->gc_flags |= GDT_GCF_WATCHDOG; 1323 timeout_set(&ccb->gc_xs->stimeout, gdt_watchdog, ccb); 1324 timeout_add(&xs->stimeout, 1325 (GDT_WATCH_TIMEOUT * hz) / 1000); 1326 break; 1327 } 1328 TAILQ_REMOVE(&gdt->sc_ccbq, ccb, gc_chain); 1329 1330 if ((xs->flags & SCSI_POLL) == 0) { 1331 timeout_set(&ccb->gc_xs->stimeout, gdt_timeout, ccb); 1332 timeout_add(&xs->stimeout, 1333 (ccb->gc_timeout * hz) / 1000); 1334 } 1335 } 1336 } 1337 1338 void 1339 gdt_chain(gdt) 1340 struct gdt_softc *gdt; 1341 { 1342 GDT_DPRINTF(GDT_D_INTR, ("gdt_chain(%p) ", gdt)); 1343 1344 if (LIST_FIRST(&gdt->sc_queue)) 1345 gdt_scsi_cmd(LIST_FIRST(&gdt->sc_queue)); 1346 } 1347 1348 void 1349 gdt_timeout(arg) 1350 void *arg; 1351 { 1352 struct gdt_ccb *ccb = arg; 1353 struct scsi_link *link = ccb->gc_xs->sc_link; 1354 struct gdt_softc *gdt = link->adapter_softc; 1355 gdt_lock_t lock; 1356 1357 sc_print_addr(link); 1358 printf("timed out\n"); 1359 1360 /* XXX Test for multiple timeouts */ 1361 1362 ccb->gc_xs->error = XS_TIMEOUT; 1363 lock = GDT_LOCK_GDT(gdt); 1364 gdt_enqueue_ccb(gdt, ccb); 1365 GDT_UNLOCK_GDT(gdt, lock); 1366 } 1367 1368 void 1369 gdt_watchdog(arg) 1370 void *arg; 1371 { 1372 struct gdt_ccb *ccb = arg; 1373 struct scsi_link *link = ccb->gc_xs->sc_link; 1374 struct gdt_softc *gdt = link->adapter_softc; 1375 gdt_lock_t lock; 1376 1377 lock = GDT_LOCK_GDT(gdt); 1378 ccb->gc_flags &= ~GDT_GCF_WATCHDOG; 1379 gdt_start_ccbs(gdt); 1380 GDT_UNLOCK_GDT(gdt, lock); 1381 } 1382 1383 #if NBIO > 0 1384 int 1385 gdt_ioctl(dev, cmd, addr) 1386 struct device *dev; 1387 u_long cmd; 1388 caddr_t addr; 1389 { 1390 int error = 0; 1391 struct gdt_dummy *dummy; 1392 1393 switch (cmd) { 1394 case GDT_IOCTL_DUMMY: 1395 dummy = (struct gdt_dummy *)addr; 1396 printf("%s: GDT_IOCTL_DUMMY %d\n", dev->dv_xname, dummy->x++); 1397 break; 1398 1399 case GDT_IOCTL_GENERAL: { 1400 gdt_ucmd_t *ucmd; 1401 struct gdt_softc *gdt = (struct gdt_softc *)dev; 1402 gdt_lock_t lock; 1403 1404 ucmd = (gdt_ucmd_t *)addr; 1405 lock = GDT_LOCK_GDT(gdt); 1406 TAILQ_INSERT_TAIL(&gdt->sc_ucmdq, ucmd, links); 1407 ucmd->complete_flag = FALSE; 1408 GDT_UNLOCK_GDT(gdt, lock); 1409 gdt_chain(gdt); 1410 if (!ucmd->complete_flag) 1411 (void)tsleep((void *)ucmd, PCATCH | PRIBIO, "gdtucw", 1412 0); 1413 break; 1414 } 1415 1416 case GDT_IOCTL_DRVERS: 1417 ((gdt_drvers_t *)addr)->vers = 1418 (GDT_DRIVER_VERSION << 8) | GDT_DRIVER_SUBVERSION; 1419 break; 1420 1421 case GDT_IOCTL_CTRCNT: 1422 ((gdt_ctrcnt_t *)addr)->cnt = gdt_cnt; 1423 break; 1424 1425 #ifdef notyet 1426 case GDT_IOCTL_CTRTYPE: { 1427 gdt_ctrt_t *p; 1428 struct gdt_softc *gdt = (struct gdt_softc *)dev; 1429 1430 p = (gdt_ctrt_t *)addr; 1431 p->oem_id = 0x8000; 1432 p->type = 0xfd; 1433 p->info = (gdt->sc_bus << 8) | (gdt->sc_slot << 3); 1434 p->ext_type = 0x6000 | gdt->sc_subdevice; 1435 p->device_id = gdt->sc_device; 1436 p->sub_device_id = gdt->sc_subdevice; 1437 break; 1438 } 1439 #endif 1440 1441 case GDT_IOCTL_OSVERS: { 1442 gdt_osv_t *p; 1443 1444 p = (gdt_osv_t *)addr; 1445 p->oscode = 10; 1446 p->version = osrelease[0] - '0'; 1447 if (osrelease[1] == '.') 1448 p->subversion = osrelease[2] - '0'; 1449 else 1450 p->subversion = 0; 1451 if (osrelease[3] == '.') 1452 p->revision = osrelease[4] - '0'; 1453 else 1454 p->revision = 0; 1455 strlcpy(p->name, ostype, sizeof p->name); 1456 break; 1457 } 1458 1459 #ifdef notyet 1460 case GDT_IOCTL_EVENT: { 1461 gdt_event_t *p; 1462 gdt_lock_t lock; 1463 1464 p = (gdt_event_t *)addr; 1465 if (p->erase == 0xff) { 1466 if (p->dvr.event_source == GDT_ES_TEST) 1467 p->dvr.event_data.size = 1468 sizeof(p->dvr.event_data.eu.test); 1469 else if (p->dvr.event_source == GDT_ES_DRIVER) 1470 p->dvr.event_data.size = 1471 sizeof(p->dvr.event_data.eu.driver); 1472 else if (p->dvr.event_source == GDT_ES_SYNC) 1473 p->dvr.event_data.size = 1474 sizeof(p->dvr.event_data.eu.sync); 1475 else 1476 p->dvr.event_data.size = 1477 sizeof(p->dvr.event_data.eu.async); 1478 lock = GDT_LOCK_GDT(gdt); 1479 gdt_store_event(p->dvr.event_source, p->dvr.event_idx, 1480 &p->dvr.event_data); 1481 GDT_UNLOCK_GDT(gdt, lock); 1482 } else if (p->erase == 0xfe) { 1483 lock = GDT_LOCK_GDT(gdt); 1484 gdt_clear_events(); 1485 GDT_UNLOCK_GDT(gdt, lock); 1486 } else if (p->erase == 0) { 1487 p->handle = gdt_read_event(p->handle, &p->dvr); 1488 } else { 1489 gdt_readapp_event((u_int8_t)p->erase, &p->dvr); 1490 } 1491 break; 1492 } 1493 #endif 1494 1495 case GDT_IOCTL_STATIST: 1496 #if 0 1497 bcopy(&gdt_stat, (gdt_statist_t *)addr, sizeof gdt_stat); 1498 #else 1499 error = EOPNOTSUPP; 1500 #endif 1501 break; 1502 1503 default: 1504 error = EINVAL; 1505 } 1506 return (error); 1507 } 1508 #endif 1509