1 /* 2 * Copyright (c) 1997 by Simon Shapiro 3 * All Rights Reserved 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions, and the following disclaimer, 10 * without modification, immediately at the beginning of the file. 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 * 3. The name of the author may not be used to endorse or promote products 15 * derived from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR 21 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 */ 29 30 /* 31 * dpt_scsi.c: SCSI dependant code for the DPT driver 32 * 33 * credits: Assisted by Mike Neuffer in the early low level DPT code 34 * Thanx to Mark Salyzyn of DPT for his assistance. 35 * Special thanx to Justin Gibbs for invaluable help in 36 * making this driver look and work like a FreeBSD component. 37 * Last but not least, many thanx to UCB and the FreeBSD 38 * team for creating and maintaining such a wonderful O/S. 39 * 40 * TODO: * Add ISA probe code. 41 * * Add driver-level RAID-0. This will allow interoperability with 42 * NiceTry, M$-Doze, Win-Dog, Slowlaris, etc., in recognizing RAID 43 * arrays that span controllers (Wow!). 44 */ 45 46 #ident "$FreeBSD: src/sys/dev/dpt/dpt_scsi.c,v 1.28.2.3 2003/01/31 02:47:10 grog Exp $" 47 #ident "$DragonFly: src/sys/dev/raid/dpt/dpt_scsi.c,v 1.6 2004/06/21 15:39:31 dillon Exp $" 48 49 #define _DPT_C_ 50 51 #include "opt_dpt.h" 52 #include <sys/param.h> 53 #include <sys/systm.h> 54 #include <sys/eventhandler.h> 55 #include <sys/malloc.h> 56 #include <sys/kernel.h> 57 58 #include <sys/bus.h> 59 60 #include <machine/bus_memio.h> 61 #include <machine/bus_pio.h> 62 #include <machine/bus.h> 63 64 #include <machine/clock.h> 65 66 #include <bus/cam/cam.h> 67 #include <bus/cam/cam_ccb.h> 68 #include <bus/cam/cam_sim.h> 69 #include <bus/cam/cam_xpt_sim.h> 70 #include <bus/cam/cam_debug.h> 71 #include <bus/cam/scsi/scsi_all.h> 72 #include <bus/cam/scsi/scsi_message.h> 73 74 #include <vm/vm.h> 75 #include <vm/pmap.h> 76 77 #include "dpt.h" 78 79 /* dpt_isa.c, dpt_eisa.c, and dpt_pci.c need this in a central place */ 80 int dpt_controllers_present; 81 82 u_long dpt_unit; /* Next unit number to use */ 83 84 /* The linked list of softc structures */ 85 struct dpt_softc_list dpt_softcs = TAILQ_HEAD_INITIALIZER(dpt_softcs); 86 87 #define microtime_now dpt_time_now() 88 89 #define dpt_inl(dpt, port) \ 90 bus_space_read_4((dpt)->tag, (dpt)->bsh, port) 91 #define dpt_inb(dpt, port) \ 92 bus_space_read_1((dpt)->tag, (dpt)->bsh, port) 93 #define dpt_outl(dpt, port, value) \ 94 bus_space_write_4((dpt)->tag, (dpt)->bsh, port, value) 95 #define dpt_outb(dpt, port, value) \ 96 bus_space_write_1((dpt)->tag, (dpt)->bsh, port, value) 97 98 /* 99 * These will have to be setup by parameters passed at boot/load time. For 100 * perfromance reasons, we make them constants for the time being. 101 */ 102 #define dpt_min_segs DPT_MAX_SEGS 103 #define dpt_max_segs DPT_MAX_SEGS 104 105 /* Definitions for our use of the SIM private CCB area */ 106 #define ccb_dccb_ptr spriv_ptr0 107 #define ccb_dpt_ptr spriv_ptr1 108 109 /* ================= Private Inline Function declarations ===================*/ 110 static __inline int dpt_just_reset(dpt_softc_t * dpt); 111 static __inline int dpt_raid_busy(dpt_softc_t * dpt); 112 static __inline int dpt_pio_wait (u_int32_t, u_int, u_int, u_int); 113 static __inline int dpt_wait(dpt_softc_t *dpt, u_int bits, 114 u_int state); 115 static __inline struct dpt_ccb* dptgetccb(struct dpt_softc *dpt); 116 static __inline void dptfreeccb(struct dpt_softc *dpt, 117 struct dpt_ccb *dccb); 118 static __inline u_int32_t dptccbvtop(struct dpt_softc *dpt, 119 struct dpt_ccb *dccb); 120 121 static __inline int dpt_send_immediate(dpt_softc_t *dpt, 122 eata_ccb_t *cmd_block, 123 u_int32_t cmd_busaddr, 124 u_int retries, 125 u_int ifc, u_int code, 126 u_int code2); 127 128 /* ==================== Private Function declarations =======================*/ 129 static void dptmapmem(void *arg, bus_dma_segment_t *segs, 130 int nseg, int error); 131 132 static struct sg_map_node* 133 dptallocsgmap(struct dpt_softc *dpt); 134 135 static int dptallocccbs(dpt_softc_t *dpt); 136 137 static int dpt_get_conf(dpt_softc_t *dpt, dpt_ccb_t *dccb, 138 u_int32_t dccb_busaddr, u_int size, 139 u_int page, u_int target, int extent); 140 static void dpt_detect_cache(dpt_softc_t *dpt, dpt_ccb_t *dccb, 141 u_int32_t dccb_busaddr, 142 u_int8_t *buff); 143 144 static void dpt_poll(struct cam_sim *sim); 145 146 static void dptexecuteccb(void *arg, bus_dma_segment_t *dm_segs, 147 int nseg, int error); 148 149 static void dpt_action(struct cam_sim *sim, union ccb *ccb); 150 151 static int dpt_send_eata_command(dpt_softc_t *dpt, eata_ccb_t *cmd, 152 u_int32_t cmd_busaddr, 153 u_int command, u_int retries, 154 u_int ifc, u_int code, 155 u_int code2); 156 static void dptprocesserror(dpt_softc_t *dpt, dpt_ccb_t *dccb, 157 union ccb *ccb, u_int hba_stat, 158 u_int scsi_stat, u_int32_t resid); 159 160 static void dpttimeout(void *arg); 161 static void dptshutdown(void *arg, int howto); 162 163 /* ================= Private Inline Function definitions ====================*/ 164 static __inline int 165 dpt_just_reset(dpt_softc_t * dpt) 166 { 167 if ((dpt_inb(dpt, 2) == 'D') 168 && (dpt_inb(dpt, 3) == 'P') 169 && (dpt_inb(dpt, 4) == 'T') 170 && (dpt_inb(dpt, 5) == 'H')) 171 return (1); 172 else 173 return (0); 174 } 175 176 static __inline int 177 dpt_raid_busy(dpt_softc_t * dpt) 178 { 179 if ((dpt_inb(dpt, 0) == 'D') 180 && (dpt_inb(dpt, 1) == 'P') 181 && (dpt_inb(dpt, 2) == 'T')) 182 return (1); 183 else 184 return (0); 185 } 186 187 static __inline int 188 dpt_pio_wait (u_int32_t base, u_int reg, u_int bits, u_int state) 189 { 190 int i; 191 u_int c; 192 193 for (i = 0; i < 20000; i++) { /* wait 20ms for not busy */ 194 c = inb(base + reg) & bits; 195 if (!(c == state)) 196 return (0); 197 else 198 DELAY(50); 199 } 200 return (-1); 201 } 202 203 static __inline int 204 dpt_wait(dpt_softc_t *dpt, u_int bits, u_int state) 205 { 206 int i; 207 u_int c; 208 209 for (i = 0; i < 20000; i++) { /* wait 20ms for not busy */ 210 c = dpt_inb(dpt, HA_RSTATUS) & bits; 211 if (c == state) 212 return (0); 213 else 214 DELAY(50); 215 } 216 return (-1); 217 } 218 219 static __inline struct dpt_ccb* 220 dptgetccb(struct dpt_softc *dpt) 221 { 222 struct dpt_ccb* dccb; 223 int s; 224 225 s = splcam(); 226 if ((dccb = SLIST_FIRST(&dpt->free_dccb_list)) != NULL) { 227 SLIST_REMOVE_HEAD(&dpt->free_dccb_list, links); 228 dpt->free_dccbs--; 229 } else if (dpt->total_dccbs < dpt->max_dccbs) { 230 dptallocccbs(dpt); 231 dccb = SLIST_FIRST(&dpt->free_dccb_list); 232 if (dccb == NULL) 233 printf("dpt%d: Can't malloc DCCB\n", dpt->unit); 234 else { 235 SLIST_REMOVE_HEAD(&dpt->free_dccb_list, links); 236 dpt->free_dccbs--; 237 } 238 } 239 splx(s); 240 241 return (dccb); 242 } 243 244 static __inline void 245 dptfreeccb(struct dpt_softc *dpt, struct dpt_ccb *dccb) 246 { 247 int s; 248 249 s = splcam(); 250 if ((dccb->state & DCCB_ACTIVE) != 0) 251 LIST_REMOVE(&dccb->ccb->ccb_h, sim_links.le); 252 if ((dccb->state & DCCB_RELEASE_SIMQ) != 0) 253 dccb->ccb->ccb_h.status |= CAM_RELEASE_SIMQ; 254 else if (dpt->resource_shortage != 0 255 && (dccb->ccb->ccb_h.status & CAM_RELEASE_SIMQ) == 0) { 256 dccb->ccb->ccb_h.status |= CAM_RELEASE_SIMQ; 257 dpt->resource_shortage = FALSE; 258 } 259 dccb->state = DCCB_FREE; 260 SLIST_INSERT_HEAD(&dpt->free_dccb_list, dccb, links); 261 ++dpt->free_dccbs; 262 splx(s); 263 } 264 265 static __inline u_int32_t 266 dptccbvtop(struct dpt_softc *dpt, struct dpt_ccb *dccb) 267 { 268 return (dpt->dpt_ccb_busbase 269 + (u_int32_t)((caddr_t)dccb - (caddr_t)dpt->dpt_dccbs)); 270 } 271 272 static __inline struct dpt_ccb * 273 dptccbptov(struct dpt_softc *dpt, u_int32_t busaddr) 274 { 275 return (dpt->dpt_dccbs 276 + ((struct dpt_ccb *)busaddr 277 - (struct dpt_ccb *)dpt->dpt_ccb_busbase)); 278 } 279 280 /* 281 * Send a command for immediate execution by the DPT 282 * See above function for IMPORTANT notes. 283 */ 284 static __inline int 285 dpt_send_immediate(dpt_softc_t *dpt, eata_ccb_t *cmd_block, 286 u_int32_t cmd_busaddr, u_int retries, 287 u_int ifc, u_int code, u_int code2) 288 { 289 return (dpt_send_eata_command(dpt, cmd_block, cmd_busaddr, 290 EATA_CMD_IMMEDIATE, retries, ifc, 291 code, code2)); 292 } 293 294 295 /* ===================== Private Function definitions =======================*/ 296 static void 297 dptmapmem(void *arg, bus_dma_segment_t *segs, int nseg, int error) 298 { 299 bus_addr_t *busaddrp; 300 301 busaddrp = (bus_addr_t *)arg; 302 *busaddrp = segs->ds_addr; 303 } 304 305 static struct sg_map_node * 306 dptallocsgmap(struct dpt_softc *dpt) 307 { 308 struct sg_map_node *sg_map; 309 310 sg_map = malloc(sizeof(*sg_map), M_DEVBUF, M_INTWAIT); 311 312 /* Allocate S/G space for the next batch of CCBS */ 313 if (bus_dmamem_alloc(dpt->sg_dmat, (void **)&sg_map->sg_vaddr, 314 BUS_DMA_NOWAIT, &sg_map->sg_dmamap) != 0) { 315 free(sg_map, M_DEVBUF); 316 return (NULL); 317 } 318 319 (void)bus_dmamap_load(dpt->sg_dmat, sg_map->sg_dmamap, sg_map->sg_vaddr, 320 PAGE_SIZE, dptmapmem, &sg_map->sg_physaddr, 321 /*flags*/0); 322 323 SLIST_INSERT_HEAD(&dpt->sg_maps, sg_map, links); 324 325 return (sg_map); 326 } 327 328 /* 329 * Allocate another chunk of CCB's. Return count of entries added. 330 * Assumed to be called at splcam(). 331 */ 332 static int 333 dptallocccbs(dpt_softc_t *dpt) 334 { 335 struct dpt_ccb *next_ccb; 336 struct sg_map_node *sg_map; 337 bus_addr_t physaddr; 338 dpt_sg_t *segs; 339 int newcount; 340 int i; 341 342 next_ccb = &dpt->dpt_dccbs[dpt->total_dccbs]; 343 344 if (next_ccb == dpt->dpt_dccbs) { 345 /* 346 * First time through. Re-use the S/G 347 * space we allocated for initialization 348 * CCBS. 349 */ 350 sg_map = SLIST_FIRST(&dpt->sg_maps); 351 } else { 352 sg_map = dptallocsgmap(dpt); 353 } 354 355 if (sg_map == NULL) 356 return (0); 357 358 segs = sg_map->sg_vaddr; 359 physaddr = sg_map->sg_physaddr; 360 361 newcount = (PAGE_SIZE / (dpt->sgsize * sizeof(dpt_sg_t))); 362 for (i = 0; dpt->total_dccbs < dpt->max_dccbs && i < newcount; i++) { 363 int error; 364 365 error = bus_dmamap_create(dpt->buffer_dmat, /*flags*/0, 366 &next_ccb->dmamap); 367 if (error != 0) 368 break; 369 next_ccb->sg_list = segs; 370 next_ccb->sg_busaddr = htonl(physaddr); 371 next_ccb->eata_ccb.cp_dataDMA = htonl(physaddr); 372 next_ccb->eata_ccb.cp_statDMA = htonl(dpt->sp_physaddr); 373 next_ccb->eata_ccb.cp_reqDMA = 374 htonl(dptccbvtop(dpt, next_ccb) 375 + offsetof(struct dpt_ccb, sense_data)); 376 next_ccb->eata_ccb.cp_busaddr = dpt->dpt_ccb_busend; 377 next_ccb->state = DCCB_FREE; 378 next_ccb->tag = dpt->total_dccbs; 379 SLIST_INSERT_HEAD(&dpt->free_dccb_list, next_ccb, links); 380 segs += dpt->sgsize; 381 physaddr += (dpt->sgsize * sizeof(dpt_sg_t)); 382 dpt->dpt_ccb_busend += sizeof(*next_ccb); 383 next_ccb++; 384 dpt->total_dccbs++; 385 } 386 return (i); 387 } 388 389 dpt_conf_t * 390 dpt_pio_get_conf (u_int32_t base) 391 { 392 static dpt_conf_t * conf; 393 u_int16_t * p; 394 int i; 395 396 /* 397 * Allocate a dpt_conf_t 398 */ 399 if (conf == NULL) 400 conf = malloc(sizeof(dpt_conf_t), M_DEVBUF, M_INTWAIT); 401 402 /* 403 * If we have one, clean it up. 404 */ 405 bzero(conf, sizeof(dpt_conf_t)); 406 407 /* 408 * Reset the controller. 409 */ 410 outb((base + HA_WCOMMAND), EATA_CMD_RESET); 411 412 /* 413 * Wait for the controller to become ready. 414 * For some reason there can be -no- delays after calling reset 415 * before we wait on ready status. 416 */ 417 if (dpt_pio_wait(base, HA_RSTATUS, HA_SBUSY, 0)) { 418 printf("dpt: timeout waiting for controller to become ready\n"); 419 return (NULL); 420 } 421 422 if (dpt_pio_wait(base, HA_RAUXSTAT, HA_ABUSY, 0)) { 423 printf("dpt: timetout waiting for adapter ready.\n"); 424 return (NULL); 425 } 426 427 /* 428 * Send the PIO_READ_CONFIG command. 429 */ 430 outb((base + HA_WCOMMAND), EATA_CMD_PIO_READ_CONFIG); 431 432 /* 433 * Read the data into the struct. 434 */ 435 p = (u_int16_t *)conf; 436 for (i = 0; i < (sizeof(dpt_conf_t) / 2); i++) { 437 438 if (dpt_pio_wait(base, HA_RSTATUS, HA_SDRQ, 0)) { 439 printf("dpt: timeout in data read.\n"); 440 return (NULL); 441 } 442 443 (*p) = inw(base + HA_RDATA); 444 p++; 445 } 446 447 if (inb(base + HA_RSTATUS) & HA_SERROR) { 448 printf("dpt: error reading configuration data.\n"); 449 return (NULL); 450 } 451 452 #define BE_EATA_SIGNATURE 0x45415441 453 #define LE_EATA_SIGNATURE 0x41544145 454 455 /* 456 * Test to see if we have a valid card. 457 */ 458 if ((conf->signature == BE_EATA_SIGNATURE) || 459 (conf->signature == LE_EATA_SIGNATURE)) { 460 461 while (inb(base + HA_RSTATUS) & HA_SDRQ) { 462 inw(base + HA_RDATA); 463 } 464 465 return (conf); 466 } 467 return (NULL); 468 } 469 470 /* 471 * Read a configuration page into the supplied dpt_cont_t buffer. 472 */ 473 static int 474 dpt_get_conf(dpt_softc_t *dpt, dpt_ccb_t *dccb, u_int32_t dccb_busaddr, 475 u_int size, u_int page, u_int target, int extent) 476 { 477 eata_ccb_t *cp; 478 479 u_int8_t status; 480 481 int ndx; 482 int ospl; 483 int result; 484 485 cp = &dccb->eata_ccb; 486 bzero((void *)(uintptr_t)(volatile void *)dpt->sp, sizeof(*dpt->sp)); 487 488 cp->Interpret = 1; 489 cp->DataIn = 1; 490 cp->Auto_Req_Sen = 1; 491 cp->reqlen = sizeof(struct scsi_sense_data); 492 493 cp->cp_id = target; 494 cp->cp_LUN = 0; /* In the EATA packet */ 495 cp->cp_lun = 0; /* In the SCSI command */ 496 497 cp->cp_scsi_cmd = INQUIRY; 498 cp->cp_len = size; 499 500 cp->cp_extent = extent; 501 502 cp->cp_page = page; 503 cp->cp_channel = 0; /* DNC, Interpret mode is set */ 504 cp->cp_identify = 1; 505 cp->cp_datalen = htonl(size); 506 507 ospl = splcam(); 508 509 /* 510 * This could be a simple for loop, but we suspected the compiler To 511 * have optimized it a bit too much. Wait for the controller to 512 * become ready 513 */ 514 while (((status = dpt_inb(dpt, HA_RSTATUS)) != (HA_SREADY | HA_SSC) 515 && (status != (HA_SREADY | HA_SSC | HA_SERROR)) 516 && (status != (HA_SDRDY | HA_SERROR | HA_SDRQ))) 517 || (dpt_wait(dpt, HA_SBUSY, 0))) { 518 519 /* 520 * RAID Drives still Spinning up? (This should only occur if 521 * the DPT controller is in a NON PC (PCI?) platform). 522 */ 523 if (dpt_raid_busy(dpt)) { 524 printf("dpt%d WARNING: Get_conf() RSUS failed.\n", 525 dpt->unit); 526 splx(ospl); 527 return (0); 528 } 529 } 530 531 DptStat_Reset_BUSY(dpt->sp); 532 533 /* 534 * XXXX We might want to do something more clever than aborting at 535 * this point, like resetting (rebooting) the controller and trying 536 * again. 537 */ 538 if ((result = dpt_send_eata_command(dpt, cp, dccb_busaddr, 539 EATA_CMD_DMA_SEND_CP, 540 10000, 0, 0, 0)) != 0) { 541 printf("dpt%d WARNING: Get_conf() failed (%d) to send " 542 "EATA_CMD_DMA_READ_CONFIG\n", 543 dpt->unit, result); 544 splx(ospl); 545 return (0); 546 } 547 /* Wait for two seconds for a response. This can be slow */ 548 for (ndx = 0; 549 (ndx < 20000) 550 && !((status = dpt_inb(dpt, HA_RAUXSTAT)) & HA_AIRQ); 551 ndx++) { 552 DELAY(50); 553 } 554 555 /* Grab the status and clear interrupts */ 556 status = dpt_inb(dpt, HA_RSTATUS); 557 558 splx(ospl); 559 560 /* 561 * Check the status carefully. Return only if the 562 * command was successful. 563 */ 564 if (((status & HA_SERROR) == 0) 565 && (dpt->sp->hba_stat == 0) 566 && (dpt->sp->scsi_stat == 0) 567 && (dpt->sp->residue_len == 0)) 568 return (0); 569 570 if (dpt->sp->scsi_stat == SCSI_STATUS_CHECK_COND) 571 return (0); 572 573 return (1); 574 } 575 576 /* Detect Cache parameters and size */ 577 static void 578 dpt_detect_cache(dpt_softc_t *dpt, dpt_ccb_t *dccb, u_int32_t dccb_busaddr, 579 u_int8_t *buff) 580 { 581 eata_ccb_t *cp; 582 u_int8_t *param; 583 int bytes; 584 int result; 585 int ospl; 586 int ndx; 587 u_int8_t status; 588 589 /* 590 * Default setting, for best perfromance.. 591 * This is what virtually all cards default to.. 592 */ 593 dpt->cache_type = DPT_CACHE_WRITEBACK; 594 dpt->cache_size = 0; 595 596 cp = &dccb->eata_ccb; 597 bzero((void *)(uintptr_t)(volatile void *)dpt->sp, sizeof(dpt->sp)); 598 bzero(buff, 512); 599 600 /* Setup the command structure */ 601 cp->Interpret = 1; 602 cp->DataIn = 1; 603 cp->Auto_Req_Sen = 1; 604 cp->reqlen = sizeof(struct scsi_sense_data); 605 606 cp->cp_id = 0; /* who cares? The HBA will interpret.. */ 607 cp->cp_LUN = 0; /* In the EATA packet */ 608 cp->cp_lun = 0; /* In the SCSI command */ 609 cp->cp_channel = 0; 610 611 cp->cp_scsi_cmd = EATA_CMD_DMA_SEND_CP; 612 cp->cp_len = 56; 613 614 cp->cp_extent = 0; 615 cp->cp_page = 0; 616 cp->cp_identify = 1; 617 cp->cp_dispri = 1; 618 619 /* 620 * Build the EATA Command Packet structure 621 * for a Log Sense Command. 622 */ 623 cp->cp_cdb[0] = 0x4d; 624 cp->cp_cdb[1] = 0x0; 625 cp->cp_cdb[2] = 0x40 | 0x33; 626 cp->cp_cdb[7] = 1; 627 628 cp->cp_datalen = htonl(512); 629 630 ospl = splcam(); 631 result = dpt_send_eata_command(dpt, cp, dccb_busaddr, 632 EATA_CMD_DMA_SEND_CP, 633 10000, 0, 0, 0); 634 if (result != 0) { 635 printf("dpt%d WARNING: detect_cache() failed (%d) to send " 636 "EATA_CMD_DMA_SEND_CP\n", dpt->unit, result); 637 splx(ospl); 638 return; 639 } 640 /* Wait for two seconds for a response. This can be slow... */ 641 for (ndx = 0; 642 (ndx < 20000) && 643 !((status = dpt_inb(dpt, HA_RAUXSTAT)) & HA_AIRQ); 644 ndx++) { 645 DELAY(50); 646 } 647 648 /* Grab the status and clear interrupts */ 649 status = dpt_inb(dpt, HA_RSTATUS); 650 splx(ospl); 651 652 /* 653 * Sanity check 654 */ 655 if (buff[0] != 0x33) { 656 return; 657 } 658 bytes = DPT_HCP_LENGTH(buff); 659 param = DPT_HCP_FIRST(buff); 660 661 if (DPT_HCP_CODE(param) != 1) { 662 /* 663 * DPT Log Page layout error 664 */ 665 printf("dpt%d: NOTICE: Log Page (1) layout error\n", 666 dpt->unit); 667 return; 668 } 669 if (!(param[4] & 0x4)) { 670 dpt->cache_type = DPT_NO_CACHE; 671 return; 672 } 673 while (DPT_HCP_CODE(param) != 6) { 674 param = DPT_HCP_NEXT(param); 675 if ((param < buff) 676 || (param >= &buff[bytes])) { 677 return; 678 } 679 } 680 681 if (param[4] & 0x2) { 682 /* 683 * Cache disabled 684 */ 685 dpt->cache_type = DPT_NO_CACHE; 686 return; 687 } 688 689 if (param[4] & 0x4) { 690 dpt->cache_type = DPT_CACHE_WRITETHROUGH; 691 } 692 693 /* XXX This isn't correct. This log parameter only has two bytes.... */ 694 #if 0 695 dpt->cache_size = param[5] 696 | (param[6] << 8) 697 | (param[7] << 16) 698 | (param[8] << 24); 699 #endif 700 } 701 702 static void 703 dpt_poll(struct cam_sim *sim) 704 { 705 dpt_intr(cam_sim_softc(sim)); 706 } 707 708 static void 709 dptexecuteccb(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error) 710 { 711 struct dpt_ccb *dccb; 712 union ccb *ccb; 713 struct dpt_softc *dpt; 714 int s; 715 716 dccb = (struct dpt_ccb *)arg; 717 ccb = dccb->ccb; 718 dpt = (struct dpt_softc *)ccb->ccb_h.ccb_dpt_ptr; 719 720 if (error != 0) { 721 if (error != EFBIG) 722 printf("dpt%d: Unexepected error 0x%x returned from " 723 "bus_dmamap_load\n", dpt->unit, error); 724 if (ccb->ccb_h.status == CAM_REQ_INPROG) { 725 xpt_freeze_devq(ccb->ccb_h.path, /*count*/1); 726 ccb->ccb_h.status = CAM_REQ_TOO_BIG|CAM_DEV_QFRZN; 727 } 728 dptfreeccb(dpt, dccb); 729 xpt_done(ccb); 730 return; 731 } 732 733 if (nseg != 0) { 734 dpt_sg_t *sg; 735 bus_dma_segment_t *end_seg; 736 bus_dmasync_op_t op; 737 738 end_seg = dm_segs + nseg; 739 740 /* Copy the segments into our SG list */ 741 sg = dccb->sg_list; 742 while (dm_segs < end_seg) { 743 sg->seg_len = htonl(dm_segs->ds_len); 744 sg->seg_addr = htonl(dm_segs->ds_addr); 745 sg++; 746 dm_segs++; 747 } 748 749 if (nseg > 1) { 750 dccb->eata_ccb.scatter = 1; 751 dccb->eata_ccb.cp_dataDMA = dccb->sg_busaddr; 752 dccb->eata_ccb.cp_datalen = 753 htonl(nseg * sizeof(dpt_sg_t)); 754 } else { 755 dccb->eata_ccb.cp_dataDMA = dccb->sg_list[0].seg_addr; 756 dccb->eata_ccb.cp_datalen = dccb->sg_list[0].seg_len; 757 } 758 759 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) 760 op = BUS_DMASYNC_PREREAD; 761 else 762 op = BUS_DMASYNC_PREWRITE; 763 764 bus_dmamap_sync(dpt->buffer_dmat, dccb->dmamap, op); 765 766 } else { 767 dccb->eata_ccb.cp_dataDMA = 0; 768 dccb->eata_ccb.cp_datalen = 0; 769 } 770 771 s = splcam(); 772 773 /* 774 * Last time we need to check if this CCB needs to 775 * be aborted. 776 */ 777 if (ccb->ccb_h.status != CAM_REQ_INPROG) { 778 if (nseg != 0) 779 bus_dmamap_unload(dpt->buffer_dmat, dccb->dmamap); 780 dptfreeccb(dpt, dccb); 781 xpt_done(ccb); 782 splx(s); 783 return; 784 } 785 786 dccb->state |= DCCB_ACTIVE; 787 ccb->ccb_h.status |= CAM_SIM_QUEUED; 788 LIST_INSERT_HEAD(&dpt->pending_ccb_list, &ccb->ccb_h, sim_links.le); 789 ccb->ccb_h.timeout_ch = 790 timeout(dpttimeout, (caddr_t)dccb, 791 (ccb->ccb_h.timeout * hz) / 1000); 792 if (dpt_send_eata_command(dpt, &dccb->eata_ccb, 793 dccb->eata_ccb.cp_busaddr, 794 EATA_CMD_DMA_SEND_CP, 0, 0, 0, 0) != 0) { 795 ccb->ccb_h.status = CAM_NO_HBA; /* HBA dead or just busy?? */ 796 if (nseg != 0) 797 bus_dmamap_unload(dpt->buffer_dmat, dccb->dmamap); 798 dptfreeccb(dpt, dccb); 799 xpt_done(ccb); 800 } 801 802 splx(s); 803 } 804 805 static void 806 dpt_action(struct cam_sim *sim, union ccb *ccb) 807 { 808 struct dpt_softc *dpt; 809 810 CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, ("dpt_action\n")); 811 812 dpt = (struct dpt_softc *)cam_sim_softc(sim); 813 814 if ((dpt->state & DPT_HA_SHUTDOWN_ACTIVE) != 0) { 815 xpt_print_path(ccb->ccb_h.path); 816 printf("controller is shutdown. Aborting CCB.\n"); 817 ccb->ccb_h.status = CAM_NO_HBA; 818 xpt_done(ccb); 819 return; 820 } 821 822 switch (ccb->ccb_h.func_code) { 823 /* Common cases first */ 824 case XPT_SCSI_IO: /* Execute the requested I/O operation */ 825 { 826 struct ccb_scsiio *csio; 827 struct ccb_hdr *ccbh; 828 struct dpt_ccb *dccb; 829 struct eata_ccb *eccb; 830 831 csio = &ccb->csio; 832 ccbh = &ccb->ccb_h; 833 /* Max CDB length is 12 bytes */ 834 if (csio->cdb_len > 12) { 835 ccb->ccb_h.status = CAM_REQ_INVALID; 836 xpt_done(ccb); 837 return; 838 } 839 if ((dccb = dptgetccb(dpt)) == NULL) { 840 int s; 841 842 s = splcam(); 843 dpt->resource_shortage = 1; 844 splx(s); 845 xpt_freeze_simq(sim, /*count*/1); 846 ccb->ccb_h.status = CAM_REQUEUE_REQ; 847 xpt_done(ccb); 848 return; 849 } 850 eccb = &dccb->eata_ccb; 851 852 /* Link dccb and ccb so we can find one from the other */ 853 dccb->ccb = ccb; 854 ccb->ccb_h.ccb_dccb_ptr = dccb; 855 ccb->ccb_h.ccb_dpt_ptr = dpt; 856 857 /* 858 * Explicitly set all flags so that the compiler can 859 * be smart about setting them. 860 */ 861 eccb->SCSI_Reset = 0; 862 eccb->HBA_Init = 0; 863 eccb->Auto_Req_Sen = (ccb->ccb_h.flags & CAM_DIS_AUTOSENSE) 864 ? 0 : 1; 865 eccb->scatter = 0; 866 eccb->Quick = 0; 867 eccb->Interpret = 868 ccb->ccb_h.target_id == dpt->hostid[cam_sim_bus(sim)] 869 ? 1 : 0; 870 eccb->DataOut = (ccb->ccb_h.flags & CAM_DIR_OUT) ? 1 : 0; 871 eccb->DataIn = (ccb->ccb_h.flags & CAM_DIR_IN) ? 1 : 0; 872 eccb->reqlen = csio->sense_len; 873 eccb->cp_id = ccb->ccb_h.target_id; 874 eccb->cp_channel = cam_sim_bus(sim); 875 eccb->cp_LUN = ccb->ccb_h.target_lun; 876 eccb->cp_luntar = 0; 877 eccb->cp_dispri = (ccb->ccb_h.flags & CAM_DIS_DISCONNECT) 878 ? 0 : 1; 879 eccb->cp_identify = 1; 880 881 if ((ccb->ccb_h.flags & CAM_TAG_ACTION_VALID) != 0 882 && csio->tag_action != CAM_TAG_ACTION_NONE) { 883 eccb->cp_msg[0] = csio->tag_action; 884 eccb->cp_msg[1] = dccb->tag; 885 } else { 886 eccb->cp_msg[0] = 0; 887 eccb->cp_msg[1] = 0; 888 } 889 eccb->cp_msg[2] = 0; 890 891 if ((ccb->ccb_h.flags & CAM_CDB_POINTER) != 0) { 892 if ((ccb->ccb_h.flags & CAM_CDB_PHYS) == 0) { 893 bcopy(csio->cdb_io.cdb_ptr, 894 eccb->cp_cdb, csio->cdb_len); 895 } else { 896 /* I guess I could map it in... */ 897 ccb->ccb_h.status = CAM_REQ_INVALID; 898 dptfreeccb(dpt, dccb); 899 xpt_done(ccb); 900 return; 901 } 902 } else { 903 bcopy(csio->cdb_io.cdb_bytes, 904 eccb->cp_cdb, csio->cdb_len); 905 } 906 /* 907 * If we have any data to send with this command, 908 * map it into bus space. 909 */ 910 /* Only use S/G if there is a transfer */ 911 if ((ccbh->flags & CAM_DIR_MASK) != CAM_DIR_NONE) { 912 if ((ccbh->flags & CAM_SCATTER_VALID) == 0) { 913 /* 914 * We've been given a pointer 915 * to a single buffer. 916 */ 917 if ((ccbh->flags & CAM_DATA_PHYS) == 0) { 918 int s; 919 int error; 920 921 s = splsoftvm(); 922 error = 923 bus_dmamap_load(dpt->buffer_dmat, 924 dccb->dmamap, 925 csio->data_ptr, 926 csio->dxfer_len, 927 dptexecuteccb, 928 dccb, /*flags*/0); 929 if (error == EINPROGRESS) { 930 /* 931 * So as to maintain ordering, 932 * freeze the controller queue 933 * until our mapping is 934 * returned. 935 */ 936 xpt_freeze_simq(sim, 1); 937 dccb->state |= CAM_RELEASE_SIMQ; 938 } 939 splx(s); 940 } else { 941 struct bus_dma_segment seg; 942 943 /* Pointer to physical buffer */ 944 seg.ds_addr = 945 (bus_addr_t)csio->data_ptr; 946 seg.ds_len = csio->dxfer_len; 947 dptexecuteccb(dccb, &seg, 1, 0); 948 } 949 } else { 950 struct bus_dma_segment *segs; 951 952 if ((ccbh->flags & CAM_DATA_PHYS) != 0) 953 panic("dpt_action - Physical " 954 "segment pointers " 955 "unsupported"); 956 957 if ((ccbh->flags&CAM_SG_LIST_PHYS)==0) 958 panic("dpt_action - Virtual " 959 "segment addresses " 960 "unsupported"); 961 962 /* Just use the segments provided */ 963 segs = (struct bus_dma_segment *)csio->data_ptr; 964 dptexecuteccb(dccb, segs, csio->sglist_cnt, 0); 965 } 966 } else { 967 /* 968 * XXX JGibbs. 969 * Does it want them both on or both off? 970 * CAM_DIR_NONE is both on, so this code can 971 * be removed if this is also what the DPT 972 * exptects. 973 */ 974 eccb->DataOut = 0; 975 eccb->DataIn = 0; 976 dptexecuteccb(dccb, NULL, 0, 0); 977 } 978 break; 979 } 980 case XPT_RESET_DEV: /* Bus Device Reset the specified SCSI device */ 981 case XPT_ABORT: /* Abort the specified CCB */ 982 /* XXX Implement */ 983 ccb->ccb_h.status = CAM_REQ_INVALID; 984 xpt_done(ccb); 985 break; 986 case XPT_SET_TRAN_SETTINGS: 987 { 988 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL; 989 xpt_done(ccb); 990 break; 991 } 992 case XPT_GET_TRAN_SETTINGS: 993 /* Get default/user set transfer settings for the target */ 994 { 995 struct ccb_trans_settings *cts; 996 u_int target_mask; 997 998 cts = &ccb->cts; 999 target_mask = 0x01 << ccb->ccb_h.target_id; 1000 if ((cts->flags & CCB_TRANS_USER_SETTINGS) != 0) { 1001 cts->flags = CCB_TRANS_DISC_ENB|CCB_TRANS_TAG_ENB; 1002 cts->bus_width = (dpt->max_id > 7) 1003 ? MSG_EXT_WDTR_BUS_8_BIT 1004 : MSG_EXT_WDTR_BUS_16_BIT; 1005 cts->sync_period = 25; /* 10MHz */ 1006 1007 if (cts->sync_period != 0) 1008 cts->sync_offset = 15; 1009 1010 cts->valid = CCB_TRANS_SYNC_RATE_VALID 1011 | CCB_TRANS_SYNC_OFFSET_VALID 1012 | CCB_TRANS_BUS_WIDTH_VALID 1013 | CCB_TRANS_DISC_VALID 1014 | CCB_TRANS_TQ_VALID; 1015 ccb->ccb_h.status = CAM_REQ_CMP; 1016 } else { 1017 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL; 1018 } 1019 xpt_done(ccb); 1020 break; 1021 } 1022 case XPT_CALC_GEOMETRY: 1023 { 1024 struct ccb_calc_geometry *ccg; 1025 u_int32_t size_mb; 1026 u_int32_t secs_per_cylinder; 1027 int extended; 1028 1029 /* 1030 * XXX Use Adaptec translation until I find out how to 1031 * get this information from the card. 1032 */ 1033 ccg = &ccb->ccg; 1034 size_mb = ccg->volume_size 1035 / ((1024L * 1024L) / ccg->block_size); 1036 extended = 1; 1037 1038 if (size_mb > 1024 && extended) { 1039 ccg->heads = 255; 1040 ccg->secs_per_track = 63; 1041 } else { 1042 ccg->heads = 64; 1043 ccg->secs_per_track = 32; 1044 } 1045 secs_per_cylinder = ccg->heads * ccg->secs_per_track; 1046 ccg->cylinders = ccg->volume_size / secs_per_cylinder; 1047 ccb->ccb_h.status = CAM_REQ_CMP; 1048 xpt_done(ccb); 1049 break; 1050 } 1051 case XPT_RESET_BUS: /* Reset the specified SCSI bus */ 1052 { 1053 /* XXX Implement */ 1054 ccb->ccb_h.status = CAM_REQ_CMP; 1055 xpt_done(ccb); 1056 break; 1057 } 1058 case XPT_TERM_IO: /* Terminate the I/O process */ 1059 /* XXX Implement */ 1060 ccb->ccb_h.status = CAM_REQ_INVALID; 1061 xpt_done(ccb); 1062 break; 1063 case XPT_PATH_INQ: /* Path routing inquiry */ 1064 { 1065 struct ccb_pathinq *cpi = &ccb->cpi; 1066 1067 cpi->version_num = 1; 1068 cpi->hba_inquiry = PI_SDTR_ABLE|PI_TAG_ABLE; 1069 if (dpt->max_id > 7) 1070 cpi->hba_inquiry |= PI_WIDE_16; 1071 cpi->target_sprt = 0; 1072 cpi->hba_misc = 0; 1073 cpi->hba_eng_cnt = 0; 1074 cpi->max_target = dpt->max_id; 1075 cpi->max_lun = dpt->max_lun; 1076 cpi->initiator_id = dpt->hostid[cam_sim_bus(sim)]; 1077 cpi->bus_id = cam_sim_bus(sim); 1078 cpi->base_transfer_speed = 3300; 1079 strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN); 1080 strncpy(cpi->hba_vid, "DPT", HBA_IDLEN); 1081 strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN); 1082 cpi->unit_number = cam_sim_unit(sim); 1083 cpi->ccb_h.status = CAM_REQ_CMP; 1084 xpt_done(ccb); 1085 break; 1086 } 1087 default: 1088 ccb->ccb_h.status = CAM_REQ_INVALID; 1089 xpt_done(ccb); 1090 break; 1091 } 1092 } 1093 1094 /* 1095 * This routine will try to send an EATA command to the DPT HBA. 1096 * It will, by default, try 20,000 times, waiting 50us between tries. 1097 * It returns 0 on success and 1 on failure. 1098 * It is assumed to be called at splcam(). 1099 */ 1100 static int 1101 dpt_send_eata_command(dpt_softc_t *dpt, eata_ccb_t *cmd_block, 1102 u_int32_t cmd_busaddr, u_int command, u_int retries, 1103 u_int ifc, u_int code, u_int code2) 1104 { 1105 u_int loop; 1106 1107 if (!retries) 1108 retries = 20000; 1109 1110 /* 1111 * I hate this polling nonsense. Wish there was a way to tell the DPT 1112 * to go get commands at its own pace, or to interrupt when ready. 1113 * In the mean time we will measure how many itterations it really 1114 * takes. 1115 */ 1116 for (loop = 0; loop < retries; loop++) { 1117 if ((dpt_inb(dpt, HA_RAUXSTAT) & HA_ABUSY) == 0) 1118 break; 1119 else 1120 DELAY(50); 1121 } 1122 1123 if (loop < retries) { 1124 #ifdef DPT_MEASURE_PERFORMANCE 1125 if (loop > dpt->performance.max_eata_tries) 1126 dpt->performance.max_eata_tries = loop; 1127 1128 if (loop < dpt->performance.min_eata_tries) 1129 dpt->performance.min_eata_tries = loop; 1130 #endif 1131 } else { 1132 #ifdef DPT_MEASURE_PERFORMANCE 1133 ++dpt->performance.command_too_busy; 1134 #endif 1135 return (1); 1136 } 1137 1138 /* The controller is alive, advance the wedge timer */ 1139 #ifdef DPT_RESET_HBA 1140 dpt->last_contact = microtime_now; 1141 #endif 1142 1143 if (cmd_block == NULL) 1144 cmd_busaddr = 0; 1145 #if (BYTE_ORDER == BIG_ENDIAN) 1146 else { 1147 cmd_busaddr = ((cmd_busaddr >> 24) & 0xFF) 1148 | ((cmd_busaddr >> 16) & 0xFF) 1149 | ((cmd_busaddr >> 8) & 0xFF) 1150 | (cmd_busaddr & 0xFF); 1151 } 1152 #endif 1153 /* And now the address */ 1154 dpt_outl(dpt, HA_WDMAADDR, cmd_busaddr); 1155 1156 if (command == EATA_CMD_IMMEDIATE) { 1157 if (cmd_block == NULL) { 1158 dpt_outb(dpt, HA_WCODE2, code2); 1159 dpt_outb(dpt, HA_WCODE, code); 1160 } 1161 dpt_outb(dpt, HA_WIFC, ifc); 1162 } 1163 dpt_outb(dpt, HA_WCOMMAND, command); 1164 1165 return (0); 1166 } 1167 1168 1169 /* ==================== Exported Function definitions =======================*/ 1170 dpt_softc_t * 1171 dpt_alloc(device_t dev, bus_space_tag_t tag, bus_space_handle_t bsh) 1172 { 1173 dpt_softc_t *dpt = device_get_softc(dev); 1174 int i; 1175 1176 bzero(dpt, sizeof(dpt_softc_t)); 1177 dpt->tag = tag; 1178 dpt->bsh = bsh; 1179 dpt->unit = device_get_unit(dev); 1180 SLIST_INIT(&dpt->free_dccb_list); 1181 LIST_INIT(&dpt->pending_ccb_list); 1182 TAILQ_INSERT_TAIL(&dpt_softcs, dpt, links); 1183 for (i = 0; i < MAX_CHANNELS; i++) 1184 dpt->resetlevel[i] = DPT_HA_OK; 1185 1186 #ifdef DPT_MEASURE_PERFORMANCE 1187 dpt_reset_performance(dpt); 1188 #endif /* DPT_MEASURE_PERFORMANCE */ 1189 return (dpt); 1190 } 1191 1192 void 1193 dpt_free(struct dpt_softc *dpt) 1194 { 1195 switch (dpt->init_level) { 1196 default: 1197 case 5: 1198 bus_dmamap_unload(dpt->dccb_dmat, dpt->dccb_dmamap); 1199 case 4: 1200 bus_dmamem_free(dpt->dccb_dmat, dpt->dpt_dccbs, 1201 dpt->dccb_dmamap); 1202 bus_dmamap_destroy(dpt->dccb_dmat, dpt->dccb_dmamap); 1203 case 3: 1204 bus_dma_tag_destroy(dpt->dccb_dmat); 1205 case 2: 1206 bus_dma_tag_destroy(dpt->buffer_dmat); 1207 case 1: 1208 { 1209 struct sg_map_node *sg_map; 1210 1211 while ((sg_map = SLIST_FIRST(&dpt->sg_maps)) != NULL) { 1212 SLIST_REMOVE_HEAD(&dpt->sg_maps, links); 1213 bus_dmamap_unload(dpt->sg_dmat, 1214 sg_map->sg_dmamap); 1215 bus_dmamem_free(dpt->sg_dmat, sg_map->sg_vaddr, 1216 sg_map->sg_dmamap); 1217 free(sg_map, M_DEVBUF); 1218 } 1219 bus_dma_tag_destroy(dpt->sg_dmat); 1220 } 1221 case 0: 1222 break; 1223 } 1224 TAILQ_REMOVE(&dpt_softcs, dpt, links); 1225 } 1226 1227 static u_int8_t string_sizes[] = 1228 { 1229 sizeof(((dpt_inq_t*)NULL)->vendor), 1230 sizeof(((dpt_inq_t*)NULL)->modelNum), 1231 sizeof(((dpt_inq_t*)NULL)->firmware), 1232 sizeof(((dpt_inq_t*)NULL)->protocol), 1233 }; 1234 1235 int 1236 dpt_init(struct dpt_softc *dpt) 1237 { 1238 dpt_conf_t conf; 1239 struct sg_map_node *sg_map; 1240 dpt_ccb_t *dccb; 1241 u_int8_t *strp; 1242 int index; 1243 int i; 1244 int retval; 1245 1246 dpt->init_level = 0; 1247 SLIST_INIT(&dpt->sg_maps); 1248 1249 #ifdef DPT_RESET_BOARD 1250 printf("dpt%d: resetting HBA\n", dpt->unit); 1251 dpt_outb(dpt, HA_WCOMMAND, EATA_CMD_RESET); 1252 DELAY(750000); 1253 /* XXX Shouldn't we poll a status register or something??? */ 1254 #endif 1255 /* DMA tag for our S/G structures. We allocate in page sized chunks */ 1256 if (bus_dma_tag_create(dpt->parent_dmat, /*alignment*/1, /*boundary*/0, 1257 /*lowaddr*/BUS_SPACE_MAXADDR, 1258 /*highaddr*/BUS_SPACE_MAXADDR, 1259 /*filter*/NULL, /*filterarg*/NULL, 1260 PAGE_SIZE, /*nsegments*/1, 1261 /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT, 1262 /*flags*/0, &dpt->sg_dmat) != 0) { 1263 goto error_exit; 1264 } 1265 1266 dpt->init_level++; 1267 1268 /* 1269 * We allocate our DPT ccbs as a contiguous array of bus dma'able 1270 * memory. To get the allocation size, we need to know how many 1271 * ccbs the card supports. This requires a ccb. We solve this 1272 * chicken and egg problem by allocating some re-usable S/G space 1273 * up front, and treating it as our status packet, CCB, and target 1274 * memory space for these commands. 1275 */ 1276 sg_map = dptallocsgmap(dpt); 1277 if (sg_map == NULL) 1278 goto error_exit; 1279 1280 dpt->sp = (volatile dpt_sp_t *)sg_map->sg_vaddr; 1281 dccb = (struct dpt_ccb *)(uintptr_t)(volatile void *)&dpt->sp[1]; 1282 bzero(dccb, sizeof(*dccb)); 1283 dpt->sp_physaddr = sg_map->sg_physaddr; 1284 dccb->eata_ccb.cp_dataDMA = 1285 htonl(sg_map->sg_physaddr + sizeof(dpt_sp_t) + sizeof(*dccb)); 1286 dccb->eata_ccb.cp_busaddr = ~0; 1287 dccb->eata_ccb.cp_statDMA = htonl(dpt->sp_physaddr); 1288 dccb->eata_ccb.cp_reqDMA = htonl(dpt->sp_physaddr + sizeof(*dccb) 1289 + offsetof(struct dpt_ccb, sense_data)); 1290 1291 /* Okay. Fetch our config */ 1292 bzero(&dccb[1], sizeof(conf)); /* data area */ 1293 retval = dpt_get_conf(dpt, dccb, sg_map->sg_physaddr + sizeof(dpt_sp_t), 1294 sizeof(conf), 0xc1, 7, 1); 1295 1296 if (retval != 0) { 1297 printf("dpt%d: Failed to get board configuration\n", dpt->unit); 1298 return (retval); 1299 } 1300 bcopy(&dccb[1], &conf, sizeof(conf)); 1301 1302 bzero(&dccb[1], sizeof(dpt->board_data)); 1303 retval = dpt_get_conf(dpt, dccb, sg_map->sg_physaddr + sizeof(dpt_sp_t), 1304 sizeof(dpt->board_data), 0, conf.scsi_id0, 0); 1305 if (retval != 0) { 1306 printf("dpt%d: Failed to get inquiry information\n", dpt->unit); 1307 return (retval); 1308 } 1309 bcopy(&dccb[1], &dpt->board_data, sizeof(dpt->board_data)); 1310 1311 dpt_detect_cache(dpt, dccb, sg_map->sg_physaddr + sizeof(dpt_sp_t), 1312 (u_int8_t *)&dccb[1]); 1313 1314 switch (ntohl(conf.splen)) { 1315 case DPT_EATA_REVA: 1316 dpt->EATA_revision = 'a'; 1317 break; 1318 case DPT_EATA_REVB: 1319 dpt->EATA_revision = 'b'; 1320 break; 1321 case DPT_EATA_REVC: 1322 dpt->EATA_revision = 'c'; 1323 break; 1324 case DPT_EATA_REVZ: 1325 dpt->EATA_revision = 'z'; 1326 break; 1327 default: 1328 dpt->EATA_revision = '?'; 1329 } 1330 1331 dpt->max_id = conf.MAX_ID; 1332 dpt->max_lun = conf.MAX_LUN; 1333 dpt->irq = conf.IRQ; 1334 dpt->dma_channel = (8 - conf.DMA_channel) & 7; 1335 dpt->channels = conf.MAX_CHAN + 1; 1336 dpt->state |= DPT_HA_OK; 1337 if (conf.SECOND) 1338 dpt->primary = FALSE; 1339 else 1340 dpt->primary = TRUE; 1341 1342 dpt->more_support = conf.MORE_support; 1343 1344 if (strncmp(dpt->board_data.firmware, "07G0", 4) >= 0) 1345 dpt->immediate_support = 1; 1346 else 1347 dpt->immediate_support = 0; 1348 1349 dpt->broken_INQUIRY = FALSE; 1350 1351 dpt->cplen = ntohl(conf.cplen); 1352 dpt->cppadlen = ntohs(conf.cppadlen); 1353 dpt->max_dccbs = ntohs(conf.queuesiz); 1354 1355 if (dpt->max_dccbs > 256) { 1356 printf("dpt%d: Max CCBs reduced from %d to " 1357 "256 due to tag algorithm\n", dpt->unit, dpt->max_dccbs); 1358 dpt->max_dccbs = 256; 1359 } 1360 1361 dpt->hostid[0] = conf.scsi_id0; 1362 dpt->hostid[1] = conf.scsi_id1; 1363 dpt->hostid[2] = conf.scsi_id2; 1364 1365 if (conf.SG_64K) 1366 dpt->sgsize = 8192; 1367 else 1368 dpt->sgsize = ntohs(conf.SGsiz); 1369 1370 /* We can only get 64k buffers, so don't bother to waste space. */ 1371 if (dpt->sgsize < 17 || dpt->sgsize > 32) 1372 dpt->sgsize = 32; 1373 1374 if (dpt->sgsize > dpt_max_segs) 1375 dpt->sgsize = dpt_max_segs; 1376 1377 /* DMA tag for mapping buffers into device visible space. */ 1378 if (bus_dma_tag_create(dpt->parent_dmat, /*alignment*/1, /*boundary*/0, 1379 /*lowaddr*/BUS_SPACE_MAXADDR, 1380 /*highaddr*/BUS_SPACE_MAXADDR, 1381 /*filter*/NULL, /*filterarg*/NULL, 1382 /*maxsize*/MAXBSIZE, /*nsegments*/dpt->sgsize, 1383 /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT, 1384 /*flags*/BUS_DMA_ALLOCNOW, 1385 &dpt->buffer_dmat) != 0) { 1386 printf("dpt: bus_dma_tag_create(...,dpt->buffer_dmat) failed\n"); 1387 goto error_exit; 1388 } 1389 1390 dpt->init_level++; 1391 1392 /* DMA tag for our ccb structures and interrupt status packet */ 1393 if (bus_dma_tag_create(dpt->parent_dmat, /*alignment*/1, /*boundary*/0, 1394 /*lowaddr*/BUS_SPACE_MAXADDR, 1395 /*highaddr*/BUS_SPACE_MAXADDR, 1396 /*filter*/NULL, /*filterarg*/NULL, 1397 (dpt->max_dccbs * sizeof(struct dpt_ccb)) 1398 + sizeof(dpt_sp_t), 1399 /*nsegments*/1, 1400 /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT, 1401 /*flags*/0, &dpt->dccb_dmat) != 0) { 1402 printf("dpt: bus_dma_tag_create(...,dpt->dccb_dmat) failed\n"); 1403 goto error_exit; 1404 } 1405 1406 dpt->init_level++; 1407 1408 /* Allocation for our ccbs and interrupt status packet */ 1409 if (bus_dmamem_alloc(dpt->dccb_dmat, (void **)&dpt->dpt_dccbs, 1410 BUS_DMA_NOWAIT, &dpt->dccb_dmamap) != 0) { 1411 printf("dpt: bus_dmamem_alloc(dpt->dccb_dmat,...) failed\n"); 1412 goto error_exit; 1413 } 1414 1415 dpt->init_level++; 1416 1417 /* And permanently map them */ 1418 bus_dmamap_load(dpt->dccb_dmat, dpt->dccb_dmamap, 1419 dpt->dpt_dccbs, 1420 (dpt->max_dccbs * sizeof(struct dpt_ccb)) 1421 + sizeof(dpt_sp_t), 1422 dptmapmem, &dpt->dpt_ccb_busbase, /*flags*/0); 1423 1424 /* Clear them out. */ 1425 bzero(dpt->dpt_dccbs, 1426 (dpt->max_dccbs * sizeof(struct dpt_ccb)) + sizeof(dpt_sp_t)); 1427 1428 dpt->dpt_ccb_busend = dpt->dpt_ccb_busbase; 1429 1430 dpt->sp = (dpt_sp_t*)&dpt->dpt_dccbs[dpt->max_dccbs]; 1431 dpt->sp_physaddr = dpt->dpt_ccb_busbase 1432 + (dpt->max_dccbs * sizeof(dpt_ccb_t)); 1433 dpt->init_level++; 1434 1435 /* Allocate our first batch of ccbs */ 1436 if (dptallocccbs(dpt) == 0) { 1437 printf("dpt: dptallocccbs(dpt) == 0\n"); 1438 return (2); 1439 } 1440 1441 /* Prepare for Target Mode */ 1442 dpt->target_mode_enabled = 1; 1443 1444 /* Nuke excess spaces from inquiry information */ 1445 strp = dpt->board_data.vendor; 1446 for (i = 0; i < sizeof(string_sizes); i++) { 1447 index = string_sizes[i] - 1; 1448 while (index && (strp[index] == ' ')) 1449 strp[index--] = '\0'; 1450 strp += string_sizes[i]; 1451 } 1452 1453 printf("dpt%d: %.8s %.16s FW Rev. %.4s, ", 1454 dpt->unit, dpt->board_data.vendor, 1455 dpt->board_data.modelNum, dpt->board_data.firmware); 1456 1457 printf("%d channel%s, ", dpt->channels, dpt->channels > 1 ? "s" : ""); 1458 1459 if (dpt->cache_type != DPT_NO_CACHE 1460 && dpt->cache_size != 0) { 1461 printf("%s Cache, ", 1462 dpt->cache_type == DPT_CACHE_WRITETHROUGH 1463 ? "Write-Through" : "Write-Back"); 1464 } 1465 1466 printf("%d CCBs\n", dpt->max_dccbs); 1467 return (0); 1468 1469 error_exit: 1470 return (1); 1471 } 1472 1473 int 1474 dpt_attach(dpt_softc_t *dpt) 1475 { 1476 struct cam_devq *devq; 1477 int i; 1478 1479 /* 1480 * Create the device queue for our SIM. 1481 */ 1482 devq = cam_simq_alloc(dpt->max_dccbs); 1483 if (devq == NULL) 1484 return (0); 1485 1486 for (i = 0; i < dpt->channels; i++) { 1487 /* 1488 * Construct our SIM entry 1489 */ 1490 dpt->sims[i] = cam_sim_alloc(dpt_action, dpt_poll, "dpt", 1491 dpt, dpt->unit, /*untagged*/2, 1492 /*tagged*/dpt->max_dccbs, devq); 1493 if (xpt_bus_register(dpt->sims[i], i) != CAM_SUCCESS) { 1494 cam_sim_free(dpt->sims[i]); 1495 break; 1496 } 1497 1498 if (xpt_create_path(&dpt->paths[i], /*periph*/NULL, 1499 cam_sim_path(dpt->sims[i]), 1500 CAM_TARGET_WILDCARD, 1501 CAM_LUN_WILDCARD) != CAM_REQ_CMP) { 1502 xpt_bus_deregister(cam_sim_path(dpt->sims[i])); 1503 cam_sim_free(dpt->sims[i]); 1504 break; 1505 } 1506 1507 } 1508 cam_simq_release(devq); 1509 if (i > 0) 1510 EVENTHANDLER_REGISTER(shutdown_final, dptshutdown, 1511 dpt, SHUTDOWN_PRI_DEFAULT); 1512 return (i); 1513 } 1514 1515 1516 /* 1517 * This is the interrupt handler for the DPT driver. 1518 */ 1519 void 1520 dpt_intr(void *arg) 1521 { 1522 dpt_softc_t *dpt; 1523 dpt_ccb_t *dccb; 1524 union ccb *ccb; 1525 u_int status; 1526 u_int aux_status; 1527 u_int hba_stat; 1528 u_int scsi_stat; 1529 u_int32_t residue_len; /* Number of bytes not transferred */ 1530 1531 dpt = (dpt_softc_t *)arg; 1532 1533 /* First order of business is to check if this interrupt is for us */ 1534 while (((aux_status = dpt_inb(dpt, HA_RAUXSTAT)) & HA_AIRQ) != 0) { 1535 1536 /* 1537 * What we want to do now, is to capture the status, all of it, 1538 * move it where it belongs, wake up whoever sleeps waiting to 1539 * process this result, and get out of here. 1540 */ 1541 if (dpt->sp->ccb_busaddr < dpt->dpt_ccb_busbase 1542 || dpt->sp->ccb_busaddr >= dpt->dpt_ccb_busend) { 1543 printf("Encountered bogus status packet\n"); 1544 status = dpt_inb(dpt, HA_RSTATUS); 1545 return; 1546 } 1547 1548 dccb = dptccbptov(dpt, dpt->sp->ccb_busaddr); 1549 1550 dpt->sp->ccb_busaddr = ~0; 1551 1552 /* Ignore status packets with EOC not set */ 1553 if (dpt->sp->EOC == 0) { 1554 printf("dpt%d ERROR: Request %d received with " 1555 "clear EOC.\n Marking as LOST.\n", 1556 dpt->unit, dccb->transaction_id); 1557 1558 #ifdef DPT_HANDLE_TIMEOUTS 1559 dccb->state |= DPT_CCB_STATE_MARKED_LOST; 1560 #endif 1561 /* This CLEARS the interrupt! */ 1562 status = dpt_inb(dpt, HA_RSTATUS); 1563 continue; 1564 } 1565 dpt->sp->EOC = 0; 1566 1567 /* 1568 * Double buffer the status information so the hardware can 1569 * work on updating the status packet while we decifer the 1570 * one we were just interrupted for. 1571 * According to Mark Salyzyn, we only need few pieces of it. 1572 */ 1573 hba_stat = dpt->sp->hba_stat; 1574 scsi_stat = dpt->sp->scsi_stat; 1575 residue_len = dpt->sp->residue_len; 1576 1577 /* Clear interrupts, check for error */ 1578 if ((status = dpt_inb(dpt, HA_RSTATUS)) & HA_SERROR) { 1579 /* 1580 * Error Condition. Check for magic cookie. Exit 1581 * this test on earliest sign of non-reset condition 1582 */ 1583 1584 /* Check that this is not a board reset interrupt */ 1585 if (dpt_just_reset(dpt)) { 1586 printf("dpt%d: HBA rebooted.\n" 1587 " All transactions should be " 1588 "resubmitted\n", 1589 dpt->unit); 1590 1591 printf("dpt%d: >>---->> This is incomplete, " 1592 "fix me.... <<----<<", dpt->unit); 1593 panic("DPT Rebooted"); 1594 1595 } 1596 } 1597 /* Process CCB */ 1598 ccb = dccb->ccb; 1599 untimeout(dpttimeout, dccb, ccb->ccb_h.timeout_ch); 1600 if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) { 1601 bus_dmasync_op_t op; 1602 1603 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) 1604 op = BUS_DMASYNC_POSTREAD; 1605 else 1606 op = BUS_DMASYNC_POSTWRITE; 1607 bus_dmamap_sync(dpt->buffer_dmat, dccb->dmamap, op); 1608 bus_dmamap_unload(dpt->buffer_dmat, dccb->dmamap); 1609 } 1610 1611 /* Common Case inline... */ 1612 if (hba_stat == HA_NO_ERROR) { 1613 ccb->csio.scsi_status = scsi_stat; 1614 ccb->ccb_h.status = 0; 1615 switch (scsi_stat) { 1616 case SCSI_STATUS_OK: 1617 ccb->ccb_h.status |= CAM_REQ_CMP; 1618 break; 1619 case SCSI_STATUS_CHECK_COND: 1620 case SCSI_STATUS_CMD_TERMINATED: 1621 bcopy(&dccb->sense_data, &ccb->csio.sense_data, 1622 ccb->csio.sense_len); 1623 ccb->ccb_h.status |= CAM_AUTOSNS_VALID; 1624 /* FALLTHROUGH */ 1625 default: 1626 ccb->ccb_h.status |= CAM_SCSI_STATUS_ERROR; 1627 /* XXX Freeze DevQ */ 1628 break; 1629 } 1630 ccb->csio.resid = residue_len; 1631 dptfreeccb(dpt, dccb); 1632 xpt_done(ccb); 1633 } else { 1634 dptprocesserror(dpt, dccb, ccb, hba_stat, scsi_stat, 1635 residue_len); 1636 } 1637 } 1638 } 1639 1640 static void 1641 dptprocesserror(dpt_softc_t *dpt, dpt_ccb_t *dccb, union ccb *ccb, 1642 u_int hba_stat, u_int scsi_stat, u_int32_t resid) 1643 { 1644 ccb->csio.resid = resid; 1645 switch (hba_stat) { 1646 case HA_ERR_SEL_TO: 1647 ccb->ccb_h.status = CAM_SEL_TIMEOUT; 1648 break; 1649 case HA_ERR_CMD_TO: 1650 ccb->ccb_h.status = CAM_CMD_TIMEOUT; 1651 break; 1652 case HA_SCSIBUS_RESET: 1653 case HA_HBA_POWER_UP: /* Similar effect to a bus reset??? */ 1654 ccb->ccb_h.status = CAM_SCSI_BUS_RESET; 1655 break; 1656 case HA_CP_ABORTED: 1657 case HA_CP_RESET: /* XXX ??? */ 1658 case HA_CP_ABORT_NA: /* XXX ??? */ 1659 case HA_CP_RESET_NA: /* XXX ??? */ 1660 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_INPROG) 1661 ccb->ccb_h.status = CAM_REQ_ABORTED; 1662 break; 1663 case HA_PCI_PARITY: 1664 case HA_PCI_MABORT: 1665 case HA_PCI_TABORT: 1666 case HA_PCI_STABORT: 1667 case HA_BUS_PARITY: 1668 case HA_PARITY_ERR: 1669 case HA_ECC_ERR: 1670 ccb->ccb_h.status = CAM_UNCOR_PARITY; 1671 break; 1672 case HA_UNX_MSGRJCT: 1673 ccb->ccb_h.status = CAM_MSG_REJECT_REC; 1674 break; 1675 case HA_UNX_BUSPHASE: 1676 ccb->ccb_h.status = CAM_SEQUENCE_FAIL; 1677 break; 1678 case HA_UNX_BUS_FREE: 1679 ccb->ccb_h.status = CAM_UNEXP_BUSFREE; 1680 break; 1681 case HA_SCSI_HUNG: 1682 case HA_RESET_STUCK: 1683 /* 1684 * Dead??? Can the controller get unstuck 1685 * from these conditions 1686 */ 1687 ccb->ccb_h.status = CAM_NO_HBA; 1688 break; 1689 case HA_RSENSE_FAIL: 1690 ccb->ccb_h.status = CAM_AUTOSENSE_FAIL; 1691 break; 1692 default: 1693 printf("dpt%d: Undocumented Error %x\n", dpt->unit, hba_stat); 1694 printf("Please mail this message to shimon@simon-shapiro.org\n"); 1695 ccb->ccb_h.status = CAM_REQ_CMP_ERR; 1696 break; 1697 } 1698 dptfreeccb(dpt, dccb); 1699 xpt_done(ccb); 1700 } 1701 1702 static void 1703 dpttimeout(void *arg) 1704 { 1705 struct dpt_ccb *dccb; 1706 union ccb *ccb; 1707 struct dpt_softc *dpt; 1708 int s; 1709 1710 dccb = (struct dpt_ccb *)arg; 1711 ccb = dccb->ccb; 1712 dpt = (struct dpt_softc *)ccb->ccb_h.ccb_dpt_ptr; 1713 xpt_print_path(ccb->ccb_h.path); 1714 printf("CCB %p - timed out\n", (void *)dccb); 1715 1716 s = splcam(); 1717 1718 /* 1719 * Try to clear any pending jobs. FreeBSD will loose interrupts, 1720 * leaving the controller suspended, and commands timed-out. 1721 * By calling the interrupt handler, any command thus stuck will be 1722 * completed. 1723 */ 1724 dpt_intr(dpt); 1725 1726 if ((dccb->state & DCCB_ACTIVE) == 0) { 1727 xpt_print_path(ccb->ccb_h.path); 1728 printf("CCB %p - timed out CCB already completed\n", 1729 (void *)dccb); 1730 splx(s); 1731 return; 1732 } 1733 1734 /* Abort this particular command. Leave all others running */ 1735 dpt_send_immediate(dpt, &dccb->eata_ccb, dccb->eata_ccb.cp_busaddr, 1736 /*retries*/20000, EATA_SPECIFIC_ABORT, 0, 0); 1737 ccb->ccb_h.status = CAM_CMD_TIMEOUT; 1738 splx(s); 1739 } 1740 1741 /* 1742 * Shutdown the controller and ensure that the cache is completely flushed. 1743 * Called from the shutdown_final event after all disk access has completed. 1744 */ 1745 static void 1746 dptshutdown(void *arg, int howto) 1747 { 1748 dpt_softc_t *dpt; 1749 1750 dpt = (dpt_softc_t *)arg; 1751 1752 printf("dpt%d: Shutting down (mode %x) HBA. Please wait...\n", 1753 dpt->unit, howto); 1754 1755 /* 1756 * What we do for a shutdown, is give the DPT early power loss warning 1757 */ 1758 dpt_send_immediate(dpt, NULL, 0, EATA_POWER_OFF_WARN, 0, 0, 0); 1759 DELAY(1000 * 1000 * 5); 1760 printf("dpt%d: Controller was warned of shutdown and is now " 1761 "disabled\n", dpt->unit); 1762 } 1763 1764 /*============================================================================*/ 1765 1766 #if 0 1767 #ifdef DPT_RESET_HBA 1768 1769 /* 1770 ** Function name : dpt_reset_hba 1771 ** 1772 ** Description : Reset the HBA and properly discard all pending work 1773 ** Input : Softc 1774 ** Output : Nothing 1775 */ 1776 static void 1777 dpt_reset_hba(dpt_softc_t *dpt) 1778 { 1779 eata_ccb_t *ccb; 1780 int ospl; 1781 dpt_ccb_t dccb, *dccbp; 1782 int result; 1783 struct scsi_xfer *xs; 1784 1785 /* Prepare a control block. The SCSI command part is immaterial */ 1786 dccb.xs = NULL; 1787 dccb.flags = 0; 1788 dccb.state = DPT_CCB_STATE_NEW; 1789 dccb.std_callback = NULL; 1790 dccb.wrbuff_callback = NULL; 1791 1792 ccb = &dccb.eata_ccb; 1793 ccb->CP_OpCode = EATA_CMD_RESET; 1794 ccb->SCSI_Reset = 0; 1795 ccb->HBA_Init = 1; 1796 ccb->Auto_Req_Sen = 1; 1797 ccb->cp_id = 0; /* Should be ignored */ 1798 ccb->DataIn = 1; 1799 ccb->DataOut = 0; 1800 ccb->Interpret = 1; 1801 ccb->reqlen = htonl(sizeof(struct scsi_sense_data)); 1802 ccb->cp_statDMA = htonl(vtophys(&ccb->cp_statDMA)); 1803 ccb->cp_reqDMA = htonl(vtophys(&ccb->cp_reqDMA)); 1804 ccb->cp_viraddr = (u_int32_t) & ccb; 1805 1806 ccb->cp_msg[0] = HA_IDENTIFY_MSG | HA_DISCO_RECO; 1807 ccb->cp_scsi_cmd = 0; /* Should be ignored */ 1808 1809 /* Lock up the submitted queue. We are very persistant here */ 1810 ospl = splcam(); 1811 while (dpt->queue_status & DPT_SUBMITTED_QUEUE_ACTIVE) { 1812 DELAY(100); 1813 } 1814 1815 dpt->queue_status |= DPT_SUBMITTED_QUEUE_ACTIVE; 1816 splx(ospl); 1817 1818 /* Send the RESET message */ 1819 if ((result = dpt_send_eata_command(dpt, &dccb.eata_ccb, 1820 EATA_CMD_RESET, 0, 0, 0, 0)) != 0) { 1821 printf("dpt%d: Failed to send the RESET message.\n" 1822 " Trying cold boot (ouch!)\n", dpt->unit); 1823 1824 1825 if ((result = dpt_send_eata_command(dpt, &dccb.eata_ccb, 1826 EATA_COLD_BOOT, 0, 0, 1827 0, 0)) != 0) { 1828 panic("dpt%d: Faild to cold boot the HBA\n", 1829 dpt->unit); 1830 } 1831 #ifdef DPT_MEASURE_PERFORMANCE 1832 dpt->performance.cold_boots++; 1833 #endif /* DPT_MEASURE_PERFORMANCE */ 1834 } 1835 1836 #ifdef DPT_MEASURE_PERFORMANCE 1837 dpt->performance.warm_starts++; 1838 #endif /* DPT_MEASURE_PERFORMANCE */ 1839 1840 printf("dpt%d: Aborting pending requests. O/S should re-submit\n", 1841 dpt->unit); 1842 1843 while ((dccbp = TAILQ_FIRST(&dpt->completed_ccbs)) != NULL) { 1844 struct scsi_xfer *xs = dccbp->xs; 1845 1846 /* Not all transactions have xs structs */ 1847 if (xs != NULL) { 1848 /* Tell the kernel proper this did not complete well */ 1849 xs->error |= XS_SELTIMEOUT; 1850 xs->flags |= SCSI_ITSDONE; 1851 scsi_done(xs); 1852 } 1853 1854 dpt_Qremove_submitted(dpt, dccbp); 1855 1856 /* Remember, Callbacks are NOT in the standard queue */ 1857 if (dccbp->std_callback != NULL) { 1858 (dccbp->std_callback)(dpt, dccbp->eata_ccb.cp_channel, 1859 dccbp); 1860 } else { 1861 ospl = splcam(); 1862 dpt_Qpush_free(dpt, dccbp); 1863 splx(ospl); 1864 } 1865 } 1866 1867 printf("dpt%d: reset done aborting all pending commands\n", dpt->unit); 1868 dpt->queue_status &= ~DPT_SUBMITTED_QUEUE_ACTIVE; 1869 } 1870 1871 #endif /* DPT_RESET_HBA */ 1872 1873 /* 1874 * Build a Command Block for target mode READ/WRITE BUFFER, 1875 * with the ``sync'' bit ON. 1876 * 1877 * Although the length and offset are 24 bit fields in the command, they cannot 1878 * exceed 8192 bytes, so we take them as short integers andcheck their range. 1879 * If they are sensless, we round them to zero offset, maximum length and 1880 * complain. 1881 */ 1882 1883 static void 1884 dpt_target_ccb(dpt_softc_t * dpt, int bus, u_int8_t target, u_int8_t lun, 1885 dpt_ccb_t * ccb, int mode, u_int8_t command, 1886 u_int16_t length, u_int16_t offset) 1887 { 1888 eata_ccb_t *cp; 1889 int ospl; 1890 1891 if ((length + offset) > DPT_MAX_TARGET_MODE_BUFFER_SIZE) { 1892 printf("dpt%d: Length of %d, and offset of %d are wrong\n", 1893 dpt->unit, length, offset); 1894 length = DPT_MAX_TARGET_MODE_BUFFER_SIZE; 1895 offset = 0; 1896 } 1897 ccb->xs = NULL; 1898 ccb->flags = 0; 1899 ccb->state = DPT_CCB_STATE_NEW; 1900 ccb->std_callback = (ccb_callback) dpt_target_done; 1901 ccb->wrbuff_callback = NULL; 1902 1903 cp = &ccb->eata_ccb; 1904 cp->CP_OpCode = EATA_CMD_DMA_SEND_CP; 1905 cp->SCSI_Reset = 0; 1906 cp->HBA_Init = 0; 1907 cp->Auto_Req_Sen = 1; 1908 cp->cp_id = target; 1909 cp->DataIn = 1; 1910 cp->DataOut = 0; 1911 cp->Interpret = 0; 1912 cp->reqlen = htonl(sizeof(struct scsi_sense_data)); 1913 cp->cp_statDMA = htonl(vtophys(&cp->cp_statDMA)); 1914 cp->cp_reqDMA = htonl(vtophys(&cp->cp_reqDMA)); 1915 cp->cp_viraddr = (u_int32_t) & ccb; 1916 1917 cp->cp_msg[0] = HA_IDENTIFY_MSG | HA_DISCO_RECO; 1918 1919 cp->cp_scsi_cmd = command; 1920 cp->cp_cdb[1] = (u_int8_t) (mode & SCSI_TM_MODE_MASK); 1921 cp->cp_lun = lun; /* Order is important here! */ 1922 cp->cp_cdb[2] = 0x00; /* Buffer Id, only 1 :-( */ 1923 cp->cp_cdb[3] = (length >> 16) & 0xFF; /* Buffer offset MSB */ 1924 cp->cp_cdb[4] = (length >> 8) & 0xFF; 1925 cp->cp_cdb[5] = length & 0xFF; 1926 cp->cp_cdb[6] = (length >> 16) & 0xFF; /* Length MSB */ 1927 cp->cp_cdb[7] = (length >> 8) & 0xFF; 1928 cp->cp_cdb[8] = length & 0xFF; /* Length LSB */ 1929 cp->cp_cdb[9] = 0; /* No sync, no match bits */ 1930 1931 /* 1932 * This could be optimized to live in dpt_register_buffer. 1933 * We keep it here, just in case the kernel decides to reallocate pages 1934 */ 1935 if (dpt_scatter_gather(dpt, ccb, DPT_RW_BUFFER_SIZE, 1936 dpt->rw_buffer[bus][target][lun])) { 1937 printf("dpt%d: Failed to setup Scatter/Gather for " 1938 "Target-Mode buffer\n", dpt->unit); 1939 } 1940 } 1941 1942 /* Setup a target mode READ command */ 1943 1944 static void 1945 dpt_set_target(int redo, dpt_softc_t * dpt, 1946 u_int8_t bus, u_int8_t target, u_int8_t lun, int mode, 1947 u_int16_t length, u_int16_t offset, dpt_ccb_t * ccb) 1948 { 1949 int ospl; 1950 1951 if (dpt->target_mode_enabled) { 1952 ospl = splcam(); 1953 1954 if (!redo) 1955 dpt_target_ccb(dpt, bus, target, lun, ccb, mode, 1956 SCSI_TM_READ_BUFFER, length, offset); 1957 1958 ccb->transaction_id = ++dpt->commands_processed; 1959 1960 #ifdef DPT_MEASURE_PERFORMANCE 1961 dpt->performance.command_count[ccb->eata_ccb.cp_scsi_cmd]++; 1962 ccb->command_started = microtime_now; 1963 #endif 1964 dpt_Qadd_waiting(dpt, ccb); 1965 dpt_sched_queue(dpt); 1966 1967 splx(ospl); 1968 } else { 1969 printf("dpt%d: Target Mode Request, but Target Mode is OFF\n", 1970 dpt->unit); 1971 } 1972 } 1973 1974 /* 1975 * Schedule a buffer to be sent to another target. 1976 * The work will be scheduled and the callback provided will be called when 1977 * the work is actually done. 1978 * 1979 * Please NOTE: ``Anyone'' can send a buffer, but only registered clients 1980 * get notified of receipt of buffers. 1981 */ 1982 1983 int 1984 dpt_send_buffer(int unit, u_int8_t channel, u_int8_t target, u_int8_t lun, 1985 u_int8_t mode, u_int16_t length, u_int16_t offset, void *data, 1986 buff_wr_done callback) 1987 { 1988 dpt_softc_t *dpt; 1989 dpt_ccb_t *ccb = NULL; 1990 int ospl; 1991 1992 /* This is an external call. Be a bit paranoid */ 1993 for (dpt = TAILQ_FIRST(&dpt_softc_list); 1994 dpt != NULL; 1995 dpt = TAILQ_NEXT(dpt, links)) { 1996 if (dpt->unit == unit) 1997 goto valid_unit; 1998 } 1999 2000 return (INVALID_UNIT); 2001 2002 valid_unit: 2003 2004 if (dpt->target_mode_enabled) { 2005 if ((channel >= dpt->channels) || (target > dpt->max_id) || 2006 (lun > dpt->max_lun)) { 2007 return (INVALID_SENDER); 2008 } 2009 if ((dpt->rw_buffer[channel][target][lun] == NULL) || 2010 (dpt->buffer_receiver[channel][target][lun] == NULL)) 2011 return (NOT_REGISTERED); 2012 2013 ospl = splsoftcam(); 2014 /* Process the free list */ 2015 if ((TAILQ_EMPTY(&dpt->free_ccbs)) && dpt_alloc_freelist(dpt)) { 2016 printf("dpt%d ERROR: Cannot allocate any more free CCB's.\n" 2017 " Please try later\n", 2018 dpt->unit); 2019 splx(ospl); 2020 return (NO_RESOURCES); 2021 } 2022 /* Now grab the newest CCB */ 2023 if ((ccb = dpt_Qpop_free(dpt)) == NULL) { 2024 splx(ospl); 2025 panic("dpt%d: Got a NULL CCB from pop_free()\n", dpt->unit); 2026 } 2027 splx(ospl); 2028 2029 bcopy(dpt->rw_buffer[channel][target][lun] + offset, data, length); 2030 dpt_target_ccb(dpt, channel, target, lun, ccb, mode, 2031 SCSI_TM_WRITE_BUFFER, 2032 length, offset); 2033 ccb->std_callback = (ccb_callback) callback; /* Potential trouble */ 2034 2035 ospl = splcam(); 2036 ccb->transaction_id = ++dpt->commands_processed; 2037 2038 #ifdef DPT_MEASURE_PERFORMANCE 2039 dpt->performance.command_count[ccb->eata_ccb.cp_scsi_cmd]++; 2040 ccb->command_started = microtime_now; 2041 #endif 2042 dpt_Qadd_waiting(dpt, ccb); 2043 dpt_sched_queue(dpt); 2044 2045 splx(ospl); 2046 return (0); 2047 } 2048 return (DRIVER_DOWN); 2049 } 2050 2051 static void 2052 dpt_target_done(dpt_softc_t * dpt, int bus, dpt_ccb_t * ccb) 2053 { 2054 int ospl; 2055 eata_ccb_t *cp; 2056 2057 cp = &ccb->eata_ccb; 2058 2059 /* 2060 * Remove the CCB from the waiting queue. 2061 * We do NOT put it back on the free, etc., queues as it is a special 2062 * ccb, owned by the dpt_softc of this unit. 2063 */ 2064 ospl = splsoftcam(); 2065 dpt_Qremove_completed(dpt, ccb); 2066 splx(ospl); 2067 2068 #define br_channel (ccb->eata_ccb.cp_channel) 2069 #define br_target (ccb->eata_ccb.cp_id) 2070 #define br_lun (ccb->eata_ccb.cp_LUN) 2071 #define br_index [br_channel][br_target][br_lun] 2072 #define read_buffer_callback (dpt->buffer_receiver br_index ) 2073 #define read_buffer (dpt->rw_buffer[br_channel][br_target][br_lun]) 2074 #define cb(offset) (ccb->eata_ccb.cp_cdb[offset]) 2075 #define br_offset ((cb(3) << 16) | (cb(4) << 8) | cb(5)) 2076 #define br_length ((cb(6) << 16) | (cb(7) << 8) | cb(8)) 2077 2078 /* Different reasons for being here, you know... */ 2079 switch (ccb->eata_ccb.cp_scsi_cmd) { 2080 case SCSI_TM_READ_BUFFER: 2081 if (read_buffer_callback != NULL) { 2082 /* This is a buffer generated by a kernel process */ 2083 read_buffer_callback(dpt->unit, br_channel, 2084 br_target, br_lun, 2085 read_buffer, 2086 br_offset, br_length); 2087 } else { 2088 /* 2089 * This is a buffer waited for by a user (sleeping) 2090 * command 2091 */ 2092 wakeup(ccb); 2093 } 2094 2095 /* We ALWAYS re-issue the same command; args are don't-care */ 2096 dpt_set_target(1, 0, 0, 0, 0, 0, 0, 0, 0); 2097 break; 2098 2099 case SCSI_TM_WRITE_BUFFER: 2100 (ccb->wrbuff_callback) (dpt->unit, br_channel, br_target, 2101 br_offset, br_length, 2102 br_lun, ccb->status_packet.hba_stat); 2103 break; 2104 default: 2105 printf("dpt%d: %s is an unsupported command for target mode\n", 2106 dpt->unit, scsi_cmd_name(ccb->eata_ccb.cp_scsi_cmd)); 2107 } 2108 ospl = splsoftcam(); 2109 dpt->target_ccb[br_channel][br_target][br_lun] = NULL; 2110 dpt_Qpush_free(dpt, ccb); 2111 splx(ospl); 2112 } 2113 2114 2115 /* 2116 * Use this function to register a client for a buffer read target operation. 2117 * The function you register will be called every time a buffer is received 2118 * by the target mode code. 2119 */ 2120 dpt_rb_t 2121 dpt_register_buffer(int unit, u_int8_t channel, u_int8_t target, u_int8_t lun, 2122 u_int8_t mode, u_int16_t length, u_int16_t offset, 2123 dpt_rec_buff callback, dpt_rb_op_t op) 2124 { 2125 dpt_softc_t *dpt; 2126 dpt_ccb_t *ccb = NULL; 2127 int ospl; 2128 2129 for (dpt = TAILQ_FIRST(&dpt_softc_list); 2130 dpt != NULL; 2131 dpt = TAILQ_NEXT(dpt, links)) { 2132 if (dpt->unit == unit) 2133 goto valid_unit; 2134 } 2135 2136 return (INVALID_UNIT); 2137 2138 valid_unit: 2139 2140 if (dpt->state & DPT_HA_SHUTDOWN_ACTIVE) 2141 return (DRIVER_DOWN); 2142 2143 if ((channel > (dpt->channels - 1)) || (target > (dpt->max_id - 1)) || 2144 (lun > (dpt->max_lun - 1))) 2145 return (INVALID_SENDER); 2146 2147 if (dpt->buffer_receiver[channel][target][lun] == NULL) { 2148 if (op == REGISTER_BUFFER) { 2149 /* Assign the requested callback */ 2150 dpt->buffer_receiver[channel][target][lun] = callback; 2151 /* Get a CCB */ 2152 ospl = splsoftcam(); 2153 2154 /* Process the free list */ 2155 if ((TAILQ_EMPTY(&dpt->free_ccbs)) && dpt_alloc_freelist(dpt)) { 2156 printf("dpt%d ERROR: Cannot allocate any more free CCB's.\n" 2157 " Please try later\n", 2158 dpt->unit); 2159 splx(ospl); 2160 return (NO_RESOURCES); 2161 } 2162 /* Now grab the newest CCB */ 2163 if ((ccb = dpt_Qpop_free(dpt)) == NULL) { 2164 splx(ospl); 2165 panic("dpt%d: Got a NULL CCB from pop_free()\n", 2166 dpt->unit); 2167 } 2168 splx(ospl); 2169 2170 /* Clean up the leftover of the previous tenant */ 2171 ccb->status = DPT_CCB_STATE_NEW; 2172 dpt->target_ccb[channel][target][lun] = ccb; 2173 2174 dpt->rw_buffer[channel][target][lun] = 2175 malloc(DPT_RW_BUFFER_SIZE, M_DEVBUF, M_INTWAIT); 2176 dpt_set_target(0, dpt, channel, target, lun, mode, 2177 length, offset, ccb); 2178 return (SUCCESSFULLY_REGISTERED); 2179 } else 2180 return (NOT_REGISTERED); 2181 } else { 2182 if (op == REGISTER_BUFFER) { 2183 if (dpt->buffer_receiver[channel][target][lun] == callback) 2184 return (ALREADY_REGISTERED); 2185 else 2186 return (REGISTERED_TO_ANOTHER); 2187 } else { 2188 if (dpt->buffer_receiver[channel][target][lun] == callback) { 2189 dpt->buffer_receiver[channel][target][lun] = NULL; 2190 ospl = splsoftcam(); 2191 dpt_Qpush_free(dpt, ccb); 2192 splx(ospl); 2193 free(dpt->rw_buffer[channel][target][lun], M_DEVBUF); 2194 return (SUCCESSFULLY_REGISTERED); 2195 } else 2196 return (INVALID_CALLBACK); 2197 } 2198 2199 } 2200 } 2201 2202 /* Return the state of the blinking DPT LED's */ 2203 u_int8_t 2204 dpt_blinking_led(dpt_softc_t * dpt) 2205 { 2206 int ndx; 2207 int ospl; 2208 u_int32_t state; 2209 u_int32_t previous; 2210 u_int8_t result; 2211 2212 ospl = splcam(); 2213 2214 result = 0; 2215 2216 for (ndx = 0, state = 0, previous = 0; 2217 (ndx < 10) && (state != previous); 2218 ndx++) { 2219 previous = state; 2220 state = dpt_inl(dpt, 1); 2221 } 2222 2223 if ((state == previous) && (state == DPT_BLINK_INDICATOR)) 2224 result = dpt_inb(dpt, 5); 2225 2226 splx(ospl); 2227 return (result); 2228 } 2229 2230 /* 2231 * Execute a command which did not come from the kernel's SCSI layer. 2232 * The only way to map user commands to bus and target is to comply with the 2233 * standard DPT wire-down scheme: 2234 */ 2235 int 2236 dpt_user_cmd(dpt_softc_t * dpt, eata_pt_t * user_cmd, 2237 caddr_t cmdarg, int minor_no) 2238 { 2239 dpt_ccb_t *ccb; 2240 void *data; 2241 int channel, target, lun; 2242 int huh; 2243 int result; 2244 int ospl; 2245 int submitted; 2246 2247 data = NULL; 2248 channel = minor2hba(minor_no); 2249 target = minor2target(minor_no); 2250 lun = minor2lun(minor_no); 2251 2252 if ((channel > (dpt->channels - 1)) 2253 || (target > dpt->max_id) 2254 || (lun > dpt->max_lun)) 2255 return (ENXIO); 2256 2257 if (target == dpt->sc_scsi_link[channel].adapter_targ) { 2258 /* This one is for the controller itself */ 2259 if ((user_cmd->eataID[0] != 'E') 2260 || (user_cmd->eataID[1] != 'A') 2261 || (user_cmd->eataID[2] != 'T') 2262 || (user_cmd->eataID[3] != 'A')) { 2263 return (ENXIO); 2264 } 2265 } 2266 /* Get a DPT CCB, so we can prepare a command */ 2267 ospl = splsoftcam(); 2268 2269 /* Process the free list */ 2270 if ((TAILQ_EMPTY(&dpt->free_ccbs)) && dpt_alloc_freelist(dpt)) { 2271 printf("dpt%d ERROR: Cannot allocate any more free CCB's.\n" 2272 " Please try later\n", 2273 dpt->unit); 2274 splx(ospl); 2275 return (EFAULT); 2276 } 2277 /* Now grab the newest CCB */ 2278 if ((ccb = dpt_Qpop_free(dpt)) == NULL) { 2279 splx(ospl); 2280 panic("dpt%d: Got a NULL CCB from pop_free()\n", dpt->unit); 2281 } else { 2282 splx(ospl); 2283 /* Clean up the leftover of the previous tenant */ 2284 ccb->status = DPT_CCB_STATE_NEW; 2285 } 2286 2287 bcopy((caddr_t) & user_cmd->command_packet, (caddr_t) & ccb->eata_ccb, 2288 sizeof(eata_ccb_t)); 2289 2290 /* We do not want to do user specified scatter/gather. Why?? */ 2291 if (ccb->eata_ccb.scatter == 1) 2292 return (EINVAL); 2293 2294 ccb->eata_ccb.Auto_Req_Sen = 1; 2295 ccb->eata_ccb.reqlen = htonl(sizeof(struct scsi_sense_data)); 2296 ccb->eata_ccb.cp_datalen = htonl(sizeof(ccb->eata_ccb.cp_datalen)); 2297 ccb->eata_ccb.cp_dataDMA = htonl(vtophys(ccb->eata_ccb.cp_dataDMA)); 2298 ccb->eata_ccb.cp_statDMA = htonl(vtophys(&ccb->eata_ccb.cp_statDMA)); 2299 ccb->eata_ccb.cp_reqDMA = htonl(vtophys(&ccb->eata_ccb.cp_reqDMA)); 2300 ccb->eata_ccb.cp_viraddr = (u_int32_t) & ccb; 2301 2302 if (ccb->eata_ccb.DataIn || ccb->eata_ccb.DataOut) { 2303 /* Data I/O is involved in this command. Alocate buffer */ 2304 if (ccb->eata_ccb.cp_datalen > PAGE_SIZE) { 2305 data = contigmalloc(ccb->eata_ccb.cp_datalen, 2306 M_TEMP, M_WAITOK, 0, ~0, 2307 ccb->eata_ccb.cp_datalen, 2308 0x10000); 2309 } else { 2310 data = malloc(ccb->eata_ccb.cp_datalen, M_TEMP, 2311 M_WAITOK); 2312 } 2313 2314 if (data == NULL) { 2315 printf("dpt%d: Cannot allocate %d bytes " 2316 "for EATA command\n", dpt->unit, 2317 ccb->eata_ccb.cp_datalen); 2318 return (EFAULT); 2319 } 2320 #define usr_cmd_DMA (caddr_t)user_cmd->command_packet.cp_dataDMA 2321 if (ccb->eata_ccb.DataIn == 1) { 2322 if (copyin(usr_cmd_DMA, 2323 data, ccb->eata_ccb.cp_datalen) == -1) 2324 return (EFAULT); 2325 } 2326 } else { 2327 /* No data I/O involved here. Make sure the DPT knows that */ 2328 ccb->eata_ccb.cp_datalen = 0; 2329 data = NULL; 2330 } 2331 2332 if (ccb->eata_ccb.FWNEST == 1) 2333 ccb->eata_ccb.FWNEST = 0; 2334 2335 if (ccb->eata_ccb.cp_datalen != 0) { 2336 if (dpt_scatter_gather(dpt, ccb, ccb->eata_ccb.cp_datalen, 2337 data) != 0) { 2338 if (data != NULL) 2339 free(data, M_TEMP); 2340 return (EFAULT); 2341 } 2342 } 2343 /** 2344 * We are required to quiet a SCSI bus. 2345 * since we do not queue comands on a bus basis, 2346 * we wait for ALL commands on a controller to complete. 2347 * In the mean time, sched_queue() will not schedule new commands. 2348 */ 2349 if ((ccb->eata_ccb.cp_cdb[0] == MULTIFUNCTION_CMD) 2350 && (ccb->eata_ccb.cp_cdb[2] == BUS_QUIET)) { 2351 /* We wait for ALL traffic for this HBa to subside */ 2352 ospl = splsoftcam(); 2353 dpt->state |= DPT_HA_QUIET; 2354 splx(ospl); 2355 2356 while ((submitted = dpt->submitted_ccbs_count) != 0) { 2357 huh = tsleep((void *) dpt, PCATCH, "dptqt", 100 * hz); 2358 switch (huh) { 2359 case 0: 2360 /* Wakeup call received */ 2361 break; 2362 case EWOULDBLOCK: 2363 /* Timer Expired */ 2364 break; 2365 default: 2366 /* anything else */ 2367 break; 2368 } 2369 } 2370 } 2371 /* Resume normal operation */ 2372 if ((ccb->eata_ccb.cp_cdb[0] == MULTIFUNCTION_CMD) 2373 && (ccb->eata_ccb.cp_cdb[2] == BUS_UNQUIET)) { 2374 ospl = splsoftcam(); 2375 dpt->state &= ~DPT_HA_QUIET; 2376 splx(ospl); 2377 } 2378 /** 2379 * Schedule the command and submit it. 2380 * We bypass dpt_sched_queue, as it will block on DPT_HA_QUIET 2381 */ 2382 ccb->xs = NULL; 2383 ccb->flags = 0; 2384 ccb->eata_ccb.Auto_Req_Sen = 1; /* We always want this feature */ 2385 2386 ccb->transaction_id = ++dpt->commands_processed; 2387 ccb->std_callback = (ccb_callback) dpt_user_cmd_done; 2388 ccb->result = (u_int32_t) & cmdarg; 2389 ccb->data = data; 2390 2391 #ifdef DPT_MEASURE_PERFORMANCE 2392 ++dpt->performance.command_count[ccb->eata_ccb.cp_scsi_cmd]; 2393 ccb->command_started = microtime_now; 2394 #endif 2395 ospl = splcam(); 2396 dpt_Qadd_waiting(dpt, ccb); 2397 splx(ospl); 2398 2399 dpt_sched_queue(dpt); 2400 2401 /* Wait for the command to complete */ 2402 (void) tsleep((void *) ccb, PCATCH, "dptucw", 100 * hz); 2403 2404 /* Free allocated memory */ 2405 if (data != NULL) 2406 free(data, M_TEMP); 2407 2408 return (0); 2409 } 2410 2411 static void 2412 dpt_user_cmd_done(dpt_softc_t * dpt, int bus, dpt_ccb_t * ccb) 2413 { 2414 int ospl = splsoftcam(); 2415 u_int32_t result; 2416 caddr_t cmd_arg; 2417 2418 /** 2419 * If Auto Request Sense is on, copyout the sense struct 2420 */ 2421 #define usr_pckt_DMA (caddr_t)(intptr_t)ntohl(ccb->eata_ccb.cp_reqDMA) 2422 #define usr_pckt_len ntohl(ccb->eata_ccb.cp_datalen) 2423 if (ccb->eata_ccb.Auto_Req_Sen == 1) { 2424 if (copyout((caddr_t) & ccb->sense_data, usr_pckt_DMA, 2425 sizeof(struct scsi_sense_data))) { 2426 ccb->result = EFAULT; 2427 dpt_Qpush_free(dpt, ccb); 2428 splx(ospl); 2429 wakeup(ccb); 2430 return; 2431 } 2432 } 2433 /* If DataIn is on, copyout the data */ 2434 if ((ccb->eata_ccb.DataIn == 1) 2435 && (ccb->status_packet.hba_stat == HA_NO_ERROR)) { 2436 if (copyout(ccb->data, usr_pckt_DMA, usr_pckt_len)) { 2437 dpt_Qpush_free(dpt, ccb); 2438 ccb->result = EFAULT; 2439 2440 splx(ospl); 2441 wakeup(ccb); 2442 return; 2443 } 2444 } 2445 /* Copyout the status */ 2446 result = ccb->status_packet.hba_stat; 2447 cmd_arg = (caddr_t) ccb->result; 2448 2449 if (copyout((caddr_t) & result, cmd_arg, sizeof(result))) { 2450 dpt_Qpush_free(dpt, ccb); 2451 ccb->result = EFAULT; 2452 splx(ospl); 2453 wakeup(ccb); 2454 return; 2455 } 2456 /* Put the CCB back in the freelist */ 2457 ccb->state |= DPT_CCB_STATE_COMPLETED; 2458 dpt_Qpush_free(dpt, ccb); 2459 2460 /* Free allocated memory */ 2461 splx(ospl); 2462 return; 2463 } 2464 2465 #ifdef DPT_HANDLE_TIMEOUTS 2466 /** 2467 * This function walks down the SUBMITTED queue. 2468 * Every request that is too old gets aborted and marked. 2469 * Since the DPT will complete (interrupt) immediately (what does that mean?), 2470 * We just walk the list, aborting old commands and marking them as such. 2471 * The dpt_complete function will get rid of the that were interrupted in the 2472 * normal manner. 2473 * 2474 * This function needs to run at splcam(), as it interacts with the submitted 2475 * queue, as well as the completed and free queues. Just like dpt_intr() does. 2476 * To run it at any ISPL other than that of dpt_intr(), will mean that dpt_intr 2477 * willbe able to pre-empt it, grab a transaction in progress (towards 2478 * destruction) and operate on it. The state of this transaction will be not 2479 * very clear. 2480 * The only other option, is to lock it only as long as necessary but have 2481 * dpt_intr() spin-wait on it. In a UP environment this makes no sense and in 2482 * a SMP environment, the advantage is dubvious for a function that runs once 2483 * every ten seconds for few microseconds and, on systems with healthy 2484 * hardware, does not do anything anyway. 2485 */ 2486 2487 static void 2488 dpt_handle_timeouts(dpt_softc_t * dpt) 2489 { 2490 dpt_ccb_t *ccb; 2491 int ospl; 2492 2493 ospl = splcam(); 2494 2495 if (dpt->state & DPT_HA_TIMEOUTS_ACTIVE) { 2496 printf("dpt%d WARNING: Timeout Handling Collision\n", 2497 dpt->unit); 2498 splx(ospl); 2499 return; 2500 } 2501 dpt->state |= DPT_HA_TIMEOUTS_ACTIVE; 2502 2503 /* Loop through the entire submitted queue, looking for lost souls */ 2504 for (ccb = TAILQ_FIRST(&dpt->submitted_ccbs); 2505 ccb != NULL; 2506 ccb = TAILQ_NEXT(ccb, links)) { 2507 struct scsi_xfer *xs; 2508 u_int32_t age, max_age; 2509 2510 xs = ccb->xs; 2511 age = dpt_time_delta(ccb->command_started, microtime_now); 2512 2513 #define TenSec 10000000 2514 2515 if (xs == NULL) { /* Local, non-kernel call */ 2516 max_age = TenSec; 2517 } else { 2518 max_age = (((xs->timeout * (dpt->submitted_ccbs_count 2519 + DPT_TIMEOUT_FACTOR)) 2520 > TenSec) 2521 ? (xs->timeout * (dpt->submitted_ccbs_count 2522 + DPT_TIMEOUT_FACTOR)) 2523 : TenSec); 2524 } 2525 2526 /* 2527 * If a transaction is marked lost and is TWICE as old as we 2528 * care, then, and only then do we destroy it! 2529 */ 2530 if (ccb->state & DPT_CCB_STATE_MARKED_LOST) { 2531 /* Remember who is next */ 2532 if (age > (max_age * 2)) { 2533 dpt_Qremove_submitted(dpt, ccb); 2534 ccb->state &= ~DPT_CCB_STATE_MARKED_LOST; 2535 ccb->state |= DPT_CCB_STATE_ABORTED; 2536 #define cmd_name scsi_cmd_name(ccb->eata_ccb.cp_scsi_cmd) 2537 if (ccb->retries++ > DPT_RETRIES) { 2538 printf("dpt%d ERROR: Destroying stale " 2539 "%d (%s)\n" 2540 " on " 2541 "c%db%dt%du%d (%d/%d)\n", 2542 dpt->unit, ccb->transaction_id, 2543 cmd_name, 2544 dpt->unit, 2545 ccb->eata_ccb.cp_channel, 2546 ccb->eata_ccb.cp_id, 2547 ccb->eata_ccb.cp_LUN, age, 2548 ccb->retries); 2549 #define send_ccb &ccb->eata_ccb 2550 #define ESA EATA_SPECIFIC_ABORT 2551 (void) dpt_send_immediate(dpt, 2552 send_ccb, 2553 ESA, 2554 0, 0); 2555 dpt_Qpush_free(dpt, ccb); 2556 2557 /* The SCSI layer should re-try */ 2558 xs->error |= XS_TIMEOUT; 2559 xs->flags |= SCSI_ITSDONE; 2560 scsi_done(xs); 2561 } else { 2562 printf("dpt%d ERROR: Stale %d (%s) on " 2563 "c%db%dt%du%d (%d)\n" 2564 " gets another " 2565 "chance(%d/%d)\n", 2566 dpt->unit, ccb->transaction_id, 2567 cmd_name, 2568 dpt->unit, 2569 ccb->eata_ccb.cp_channel, 2570 ccb->eata_ccb.cp_id, 2571 ccb->eata_ccb.cp_LUN, 2572 age, ccb->retries, DPT_RETRIES); 2573 2574 dpt_Qpush_waiting(dpt, ccb); 2575 dpt_sched_queue(dpt); 2576 } 2577 } 2578 } else { 2579 /* 2580 * This is a transaction that is not to be destroyed 2581 * (yet) But it is too old for our liking. We wait as 2582 * long as the upper layer thinks. Not really, we 2583 * multiply that by the number of commands in the 2584 * submitted queue + 1. 2585 */ 2586 if (!(ccb->state & DPT_CCB_STATE_MARKED_LOST) && 2587 (age != ~0) && (age > max_age)) { 2588 printf("dpt%d ERROR: Marking %d (%s) on " 2589 "c%db%dt%du%d \n" 2590 " as late after %dusec\n", 2591 dpt->unit, ccb->transaction_id, 2592 cmd_name, 2593 dpt->unit, ccb->eata_ccb.cp_channel, 2594 ccb->eata_ccb.cp_id, 2595 ccb->eata_ccb.cp_LUN, age); 2596 ccb->state |= DPT_CCB_STATE_MARKED_LOST; 2597 } 2598 } 2599 } 2600 2601 dpt->state &= ~DPT_HA_TIMEOUTS_ACTIVE; 2602 splx(ospl); 2603 } 2604 2605 static void 2606 dpt_timeout(void *arg) 2607 { 2608 dpt_softc_t *dpt = (dpt_softc_t *) arg; 2609 2610 if (!(dpt->state & DPT_HA_TIMEOUTS_ACTIVE)) 2611 dpt_handle_timeouts(dpt); 2612 2613 timeout(dpt_timeout, (caddr_t) dpt, hz * 10); 2614 } 2615 2616 #endif /* DPT_HANDLE_TIMEOUTS */ 2617 2618 #endif 2619