1 /*- 2 * Copyright (c) 2000 Michael Smith 3 * Copyright (c) 2000 BSDi 4 * 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 AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 * 27 * $FreeBSD: src/sys/dev/twe/twe_freebsd.c,v 1.2.2.5 2002/03/07 09:57:02 msmith Exp $ 28 * $DragonFly: src/sys/dev/raid/twe/twe_freebsd.c,v 1.4 2003/07/22 17:03:31 dillon Exp $ 29 */ 30 31 /* 32 * FreeBSD-specific code. 33 */ 34 35 #include <sys/param.h> 36 #include <sys/cons.h> 37 #include <machine/bus.h> 38 #include <machine/clock.h> 39 #include <machine/md_var.h> 40 #include <vm/vm.h> 41 #include <vm/pmap.h> 42 #include <dev/twe/twe_compat.h> 43 #include <dev/twe/twereg.h> 44 #include <dev/twe/tweio.h> 45 #include <dev/twe/twevar.h> 46 #include <dev/twe/twe_tables.h> 47 48 #include <sys/devicestat.h> 49 50 static devclass_t twe_devclass; 51 52 #ifdef TWE_DEBUG 53 static u_int32_t twed_bio_in; 54 #define TWED_BIO_IN twed_bio_in++ 55 static u_int32_t twed_bio_out; 56 #define TWED_BIO_OUT twed_bio_out++ 57 #else 58 #define TWED_BIO_IN 59 #define TWED_BIO_OUT 60 #endif 61 62 /******************************************************************************** 63 ******************************************************************************** 64 Control device interface 65 ******************************************************************************** 66 ********************************************************************************/ 67 68 static d_open_t twe_open; 69 static d_close_t twe_close; 70 static d_ioctl_t twe_ioctl_wrapper; 71 72 #define TWE_CDEV_MAJOR 146 73 74 static struct cdevsw twe_cdevsw = { 75 /* name */ "twe", 76 /* cmaj */ TWE_CDEV_MAJOR, 77 /* flags */ 0, 78 /* port */ NULL, 79 /* autoq */ 0, 80 81 twe_open, 82 twe_close, 83 noread, 84 nowrite, 85 twe_ioctl_wrapper, 86 nopoll, 87 nommap, 88 nostrategy, 89 nodump, 90 nopsize, 91 }; 92 93 /******************************************************************************** 94 * Accept an open operation on the control device. 95 */ 96 static int 97 twe_open(dev_t dev, int flags, int fmt, d_thread_t *td) 98 { 99 int unit = minor(dev); 100 struct twe_softc *sc = devclass_get_softc(twe_devclass, unit); 101 102 sc->twe_state |= TWE_STATE_OPEN; 103 return(0); 104 } 105 106 /******************************************************************************** 107 * Accept the last close on the control device. 108 */ 109 static int 110 twe_close(dev_t dev, int flags, int fmt, d_thread_t *td) 111 { 112 int unit = minor(dev); 113 struct twe_softc *sc = devclass_get_softc(twe_devclass, unit); 114 115 sc->twe_state &= ~TWE_STATE_OPEN; 116 return (0); 117 } 118 119 /******************************************************************************** 120 * Handle controller-specific control operations. 121 */ 122 static int 123 twe_ioctl_wrapper(dev_t dev, u_long cmd, caddr_t addr, int32_t flag, d_thread_t *td) 124 { 125 struct twe_softc *sc = (struct twe_softc *)dev->si_drv1; 126 127 return(twe_ioctl(sc, cmd, addr)); 128 } 129 130 /******************************************************************************** 131 ******************************************************************************** 132 PCI device interface 133 ******************************************************************************** 134 ********************************************************************************/ 135 136 static int twe_probe(device_t dev); 137 static int twe_attach(device_t dev); 138 static void twe_free(struct twe_softc *sc); 139 static int twe_detach(device_t dev); 140 static int twe_shutdown(device_t dev); 141 static int twe_suspend(device_t dev); 142 static int twe_resume(device_t dev); 143 static void twe_pci_intr(void *arg); 144 static void twe_intrhook(void *arg); 145 146 static device_method_t twe_methods[] = { 147 /* Device interface */ 148 DEVMETHOD(device_probe, twe_probe), 149 DEVMETHOD(device_attach, twe_attach), 150 DEVMETHOD(device_detach, twe_detach), 151 DEVMETHOD(device_shutdown, twe_shutdown), 152 DEVMETHOD(device_suspend, twe_suspend), 153 DEVMETHOD(device_resume, twe_resume), 154 155 DEVMETHOD(bus_print_child, bus_generic_print_child), 156 DEVMETHOD(bus_driver_added, bus_generic_driver_added), 157 { 0, 0 } 158 }; 159 160 static driver_t twe_pci_driver = { 161 "twe", 162 twe_methods, 163 sizeof(struct twe_softc) 164 }; 165 166 #ifdef TWE_OVERRIDE 167 DRIVER_MODULE(Xtwe, pci, twe_pci_driver, twe_devclass, 0, 0); 168 #else 169 DRIVER_MODULE(twe, pci, twe_pci_driver, twe_devclass, 0, 0); 170 #endif 171 172 /******************************************************************************** 173 * Match a 3ware Escalade ATA RAID controller. 174 */ 175 static int 176 twe_probe(device_t dev) 177 { 178 179 debug_called(4); 180 181 if ((pci_get_vendor(dev) == TWE_VENDOR_ID) && 182 ((pci_get_device(dev) == TWE_DEVICE_ID) || 183 (pci_get_device(dev) == TWE_DEVICE_ID_ASIC))) { 184 device_set_desc(dev, TWE_DEVICE_NAME); 185 #ifdef TWE_OVERRIDE 186 return(0); 187 #else 188 return(-10); 189 #endif 190 } 191 return(ENXIO); 192 } 193 194 /******************************************************************************** 195 * Allocate resources, initialise the controller. 196 */ 197 static int 198 twe_attach(device_t dev) 199 { 200 struct twe_softc *sc; 201 int rid, error; 202 u_int32_t command; 203 204 debug_called(4); 205 206 /* 207 * Initialise the softc structure. 208 */ 209 sc = device_get_softc(dev); 210 sc->twe_dev = dev; 211 212 /* 213 * Make sure we are going to be able to talk to this board. 214 */ 215 command = pci_read_config(dev, PCIR_COMMAND, 2); 216 if ((command & PCIM_CMD_PORTEN) == 0) { 217 twe_printf(sc, "register window not available\n"); 218 return(ENXIO); 219 } 220 /* 221 * Force the busmaster enable bit on, in case the BIOS forgot. 222 */ 223 command |= PCIM_CMD_BUSMASTEREN; 224 pci_write_config(dev, PCIR_COMMAND, command, 2); 225 226 /* 227 * Allocate the PCI register window. 228 */ 229 rid = TWE_IO_CONFIG_REG; 230 if ((sc->twe_io = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, 1, RF_ACTIVE)) == NULL) { 231 twe_printf(sc, "can't allocate register window\n"); 232 twe_free(sc); 233 return(ENXIO); 234 } 235 sc->twe_btag = rman_get_bustag(sc->twe_io); 236 sc->twe_bhandle = rman_get_bushandle(sc->twe_io); 237 238 /* 239 * Allocate the parent bus DMA tag appropriate for PCI. 240 */ 241 if (bus_dma_tag_create(NULL, /* parent */ 242 1, 0, /* alignment, boundary */ 243 BUS_SPACE_MAXADDR_32BIT, /* lowaddr */ 244 BUS_SPACE_MAXADDR, /* highaddr */ 245 NULL, NULL, /* filter, filterarg */ 246 MAXBSIZE, TWE_MAX_SGL_LENGTH, /* maxsize, nsegments */ 247 BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */ 248 BUS_DMA_ALLOCNOW, /* flags */ 249 &sc->twe_parent_dmat)) { 250 twe_printf(sc, "can't allocate parent DMA tag\n"); 251 twe_free(sc); 252 return(ENOMEM); 253 } 254 255 /* 256 * Allocate and connect our interrupt. 257 */ 258 rid = 0; 259 if ((sc->twe_irq = bus_alloc_resource(sc->twe_dev, SYS_RES_IRQ, &rid, 0, ~0, 1, RF_SHAREABLE | RF_ACTIVE)) == NULL) { 260 twe_printf(sc, "can't allocate interrupt\n"); 261 twe_free(sc); 262 return(ENXIO); 263 } 264 if (bus_setup_intr(sc->twe_dev, sc->twe_irq, INTR_TYPE_BIO | INTR_ENTROPY, twe_pci_intr, sc, &sc->twe_intr)) { 265 twe_printf(sc, "can't set up interrupt\n"); 266 twe_free(sc); 267 return(ENXIO); 268 } 269 270 /* 271 * Create DMA tag for mapping objects into controller-addressable space. 272 */ 273 if (bus_dma_tag_create(sc->twe_parent_dmat, /* parent */ 274 1, 0, /* alignment, boundary */ 275 BUS_SPACE_MAXADDR, /* lowaddr */ 276 BUS_SPACE_MAXADDR, /* highaddr */ 277 NULL, NULL, /* filter, filterarg */ 278 MAXBSIZE, TWE_MAX_SGL_LENGTH,/* maxsize, nsegments */ 279 BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */ 280 0, /* flags */ 281 &sc->twe_buffer_dmat)) { 282 twe_printf(sc, "can't allocate data buffer DMA tag\n"); 283 twe_free(sc); 284 return(ENOMEM); 285 } 286 287 /* 288 * Initialise the controller and driver core. 289 */ 290 if ((error = twe_setup(sc))) 291 return(error); 292 293 /* 294 * Print some information about the controller and configuration. 295 */ 296 twe_describe_controller(sc); 297 298 /* 299 * Create the control device. 300 */ 301 sc->twe_dev_t = make_dev(&twe_cdevsw, device_get_unit(sc->twe_dev), UID_ROOT, GID_OPERATOR, 302 S_IRUSR | S_IWUSR, "twe%d", device_get_unit(sc->twe_dev)); 303 sc->twe_dev_t->si_drv1 = sc; 304 /* 305 * Schedule ourselves to bring the controller up once interrupts are available. 306 * This isn't strictly necessary, since we disable interrupts while probing the 307 * controller, but it is more in keeping with common practice for other disk 308 * devices. 309 */ 310 sc->twe_ich.ich_func = twe_intrhook; 311 sc->twe_ich.ich_arg = sc; 312 if (config_intrhook_establish(&sc->twe_ich) != 0) { 313 twe_printf(sc, "can't establish configuration hook\n"); 314 twe_free(sc); 315 return(ENXIO); 316 } 317 318 return(0); 319 } 320 321 /******************************************************************************** 322 * Free all of the resources associated with (sc). 323 * 324 * Should not be called if the controller is active. 325 */ 326 static void 327 twe_free(struct twe_softc *sc) 328 { 329 struct twe_request *tr; 330 331 debug_called(4); 332 333 /* throw away any command buffers */ 334 while ((tr = twe_dequeue_free(sc)) != NULL) 335 twe_free_request(tr); 336 337 /* destroy the data-transfer DMA tag */ 338 if (sc->twe_buffer_dmat) 339 bus_dma_tag_destroy(sc->twe_buffer_dmat); 340 341 /* disconnect the interrupt handler */ 342 if (sc->twe_intr) 343 bus_teardown_intr(sc->twe_dev, sc->twe_irq, sc->twe_intr); 344 if (sc->twe_irq != NULL) 345 bus_release_resource(sc->twe_dev, SYS_RES_IRQ, 0, sc->twe_irq); 346 347 /* destroy the parent DMA tag */ 348 if (sc->twe_parent_dmat) 349 bus_dma_tag_destroy(sc->twe_parent_dmat); 350 351 /* release the register window mapping */ 352 if (sc->twe_io != NULL) 353 bus_release_resource(sc->twe_dev, SYS_RES_IOPORT, TWE_IO_CONFIG_REG, sc->twe_io); 354 355 /* destroy control device */ 356 if (sc->twe_dev_t != (dev_t)NULL) 357 destroy_dev(sc->twe_dev_t); 358 } 359 360 /******************************************************************************** 361 * Disconnect from the controller completely, in preparation for unload. 362 */ 363 static int 364 twe_detach(device_t dev) 365 { 366 struct twe_softc *sc = device_get_softc(dev); 367 int s, error; 368 369 debug_called(4); 370 371 error = EBUSY; 372 s = splbio(); 373 if (sc->twe_state & TWE_STATE_OPEN) 374 goto out; 375 376 /* 377 * Shut the controller down. 378 */ 379 if ((error = twe_shutdown(dev))) 380 goto out; 381 382 twe_free(sc); 383 384 error = 0; 385 out: 386 splx(s); 387 return(error); 388 } 389 390 /******************************************************************************** 391 * Bring the controller down to a dormant state and detach all child devices. 392 * 393 * Note that we can assume that the bioq on the controller is empty, as we won't 394 * allow shutdown if any device is open. 395 */ 396 static int 397 twe_shutdown(device_t dev) 398 { 399 struct twe_softc *sc = device_get_softc(dev); 400 int i, s, error; 401 402 debug_called(4); 403 404 s = splbio(); 405 error = 0; 406 407 /* 408 * Delete all our child devices. 409 */ 410 for (i = 0; i < TWE_MAX_UNITS; i++) { 411 if (sc->twe_drive[i].td_disk != 0) { 412 if ((error = device_delete_child(sc->twe_dev, sc->twe_drive[i].td_disk)) != 0) 413 goto out; 414 sc->twe_drive[i].td_disk = 0; 415 } 416 } 417 418 /* 419 * Bring the controller down. 420 */ 421 twe_deinit(sc); 422 423 out: 424 splx(s); 425 return(error); 426 } 427 428 /******************************************************************************** 429 * Bring the controller to a quiescent state, ready for system suspend. 430 */ 431 static int 432 twe_suspend(device_t dev) 433 { 434 struct twe_softc *sc = device_get_softc(dev); 435 int s; 436 437 debug_called(4); 438 439 s = splbio(); 440 sc->twe_state |= TWE_STATE_SUSPEND; 441 442 twe_disable_interrupts(sc); 443 splx(s); 444 445 return(0); 446 } 447 448 /******************************************************************************** 449 * Bring the controller back to a state ready for operation. 450 */ 451 static int 452 twe_resume(device_t dev) 453 { 454 struct twe_softc *sc = device_get_softc(dev); 455 456 debug_called(4); 457 458 sc->twe_state &= ~TWE_STATE_SUSPEND; 459 twe_enable_interrupts(sc); 460 461 return(0); 462 } 463 464 /******************************************************************************* 465 * Take an interrupt, or be poked by other code to look for interrupt-worthy 466 * status. 467 */ 468 static void 469 twe_pci_intr(void *arg) 470 { 471 twe_intr((struct twe_softc *)arg); 472 } 473 474 /******************************************************************************** 475 * Delayed-startup hook 476 */ 477 static void 478 twe_intrhook(void *arg) 479 { 480 struct twe_softc *sc = (struct twe_softc *)arg; 481 482 /* pull ourselves off the intrhook chain */ 483 config_intrhook_disestablish(&sc->twe_ich); 484 485 /* call core startup routine */ 486 twe_init(sc); 487 } 488 489 /******************************************************************************** 490 * Given a detected drive, attach it to the bio interface. 491 * 492 * This is called from twe_init. 493 */ 494 void 495 twe_attach_drive(struct twe_softc *sc, struct twe_drive *dr) 496 { 497 char buf[80]; 498 int error; 499 500 dr->td_disk = device_add_child(sc->twe_dev, NULL, -1); 501 if (dr->td_disk == NULL) { 502 twe_printf(sc, "device_add_child failed\n"); 503 return; 504 } 505 device_set_ivars(dr->td_disk, dr); 506 507 /* 508 * XXX It would make sense to test the online/initialising bits, but they seem to be 509 * always set... 510 */ 511 sprintf(buf, "%s, %s", twe_describe_code(twe_table_unittype, dr->td_type), 512 twe_describe_code(twe_table_unitstate, dr->td_state & TWE_PARAM_UNITSTATUS_MASK)); 513 device_set_desc_copy(dr->td_disk, buf); 514 515 if ((error = bus_generic_attach(sc->twe_dev)) != 0) 516 twe_printf(sc, "bus_generic_attach returned %d\n", error); 517 } 518 519 /******************************************************************************** 520 * Clear a PCI parity error. 521 */ 522 void 523 twe_clear_pci_parity_error(struct twe_softc *sc) 524 { 525 TWE_CONTROL(sc, TWE_CONTROL_CLEAR_PARITY_ERROR); 526 pci_write_config(sc->twe_dev, PCIR_STATUS, TWE_PCI_CLEAR_PARITY_ERROR, 2); 527 } 528 529 /******************************************************************************** 530 * Clear a PCI abort. 531 */ 532 void 533 twe_clear_pci_abort(struct twe_softc *sc) 534 { 535 TWE_CONTROL(sc, TWE_CONTROL_CLEAR_PCI_ABORT); 536 pci_write_config(sc->twe_dev, PCIR_STATUS, TWE_PCI_CLEAR_PCI_ABORT, 2); 537 } 538 539 /******************************************************************************** 540 ******************************************************************************** 541 Disk device 542 ******************************************************************************** 543 ********************************************************************************/ 544 545 /* 546 * Disk device softc 547 */ 548 struct twed_softc 549 { 550 device_t twed_dev; 551 dev_t twed_dev_t; 552 struct twe_softc *twed_controller; /* parent device softc */ 553 struct twe_drive *twed_drive; /* drive data in parent softc */ 554 struct disk twed_disk; /* generic disk handle */ 555 struct devstat twed_stats; /* accounting */ 556 struct disklabel twed_label; /* synthetic label */ 557 int twed_flags; 558 #define TWED_OPEN (1<<0) /* drive is open (can't shut down) */ 559 }; 560 561 /* 562 * Disk device bus interface 563 */ 564 static int twed_probe(device_t dev); 565 static int twed_attach(device_t dev); 566 static int twed_detach(device_t dev); 567 568 static device_method_t twed_methods[] = { 569 DEVMETHOD(device_probe, twed_probe), 570 DEVMETHOD(device_attach, twed_attach), 571 DEVMETHOD(device_detach, twed_detach), 572 { 0, 0 } 573 }; 574 575 static driver_t twed_driver = { 576 "twed", 577 twed_methods, 578 sizeof(struct twed_softc) 579 }; 580 581 static devclass_t twed_devclass; 582 #ifdef TWE_OVERRIDE 583 DRIVER_MODULE(Xtwed, Xtwe, twed_driver, twed_devclass, 0, 0); 584 #else 585 DRIVER_MODULE(twed, twe, twed_driver, twed_devclass, 0, 0); 586 #endif 587 588 /* 589 * Disk device control interface. 590 */ 591 static d_open_t twed_open; 592 static d_close_t twed_close; 593 static d_strategy_t twed_strategy; 594 static d_dump_t twed_dump; 595 596 #define TWED_CDEV_MAJOR 147 597 598 static struct cdevsw twed_cdevsw = { 599 "twed", 600 TWED_CDEV_MAJOR, 601 D_DISK, 602 /* port */ NULL, 603 /* autoq */ 0, 604 twed_open, 605 twed_close, 606 physread, 607 physwrite, 608 noioctl, 609 nopoll, 610 nommap, 611 twed_strategy, 612 twed_dump, 613 nopsize 614 }; 615 616 /******************************************************************************** 617 * Handle open from generic layer. 618 * 619 * Note that this is typically only called by the diskslice code, and not 620 * for opens on subdevices (eg. slices, partitions). 621 */ 622 static int 623 twed_open(dev_t dev, int flags, int fmt, d_thread_t *td) 624 { 625 struct twed_softc *sc = (struct twed_softc *)dev->si_drv1; 626 struct disklabel *label; 627 628 debug_called(4); 629 630 if (sc == NULL) 631 return (ENXIO); 632 633 /* check that the controller is up and running */ 634 if (sc->twed_controller->twe_state & TWE_STATE_SHUTDOWN) 635 return(ENXIO); 636 637 /* build synthetic label */ 638 label = &sc->twed_disk.d_label; 639 bzero(label, sizeof(*label)); 640 label->d_type = DTYPE_ESDI; 641 label->d_secsize = TWE_BLOCK_SIZE; 642 label->d_nsectors = sc->twed_drive->td_sectors; 643 label->d_ntracks = sc->twed_drive->td_heads; 644 label->d_ncylinders = sc->twed_drive->td_cylinders; 645 label->d_secpercyl = sc->twed_drive->td_sectors * sc->twed_drive->td_heads; 646 label->d_secperunit = sc->twed_drive->td_size; 647 648 sc->twed_flags |= TWED_OPEN; 649 return (0); 650 } 651 652 /******************************************************************************** 653 * Handle last close of the disk device. 654 */ 655 static int 656 twed_close(dev_t dev, int flags, int fmt, d_thread_t *td) 657 { 658 struct twed_softc *sc = (struct twed_softc *)dev->si_drv1; 659 660 debug_called(4); 661 662 if (sc == NULL) 663 return (ENXIO); 664 665 sc->twed_flags &= ~TWED_OPEN; 666 return (0); 667 } 668 669 /******************************************************************************** 670 * Handle an I/O request. 671 */ 672 static void 673 twed_strategy(twe_bio *bp) 674 { 675 struct twed_softc *sc = (struct twed_softc *)TWE_BIO_SOFTC(bp); 676 677 debug_called(4); 678 679 TWED_BIO_IN; 680 681 /* bogus disk? */ 682 if (sc == NULL) { 683 TWE_BIO_SET_ERROR(bp, EINVAL); 684 printf("twe: bio for invalid disk!\n"); 685 TWE_BIO_DONE(bp); 686 TWED_BIO_OUT; 687 return; 688 } 689 690 /* perform accounting */ 691 TWE_BIO_STATS_START(bp); 692 693 /* queue the bio on the controller */ 694 twe_enqueue_bio(sc->twed_controller, bp); 695 696 /* poke the controller to start I/O */ 697 twe_startio(sc->twed_controller); 698 return; 699 } 700 701 /******************************************************************************** 702 * System crashdump support 703 */ 704 int 705 twed_dump(dev_t dev) 706 { 707 struct twed_softc *twed_sc = (struct twed_softc *)dev->si_drv1; 708 struct twe_softc *twe_sc = (struct twe_softc *)twed_sc->twed_controller; 709 u_int count, blkno, secsize; 710 vm_offset_t addr = 0; 711 long blkcnt; 712 int dumppages = MAXDUMPPGS; 713 int error; 714 int i; 715 716 if ((error = disk_dumpcheck(dev, &count, &blkno, &secsize))) 717 return(error); 718 719 if (!twed_sc || !twe_sc) 720 return(ENXIO); 721 722 blkcnt = howmany(PAGE_SIZE, secsize); 723 724 while (count > 0) { 725 caddr_t va = NULL; 726 727 if ((count / blkcnt) < dumppages) 728 dumppages = count / blkcnt; 729 730 for (i = 0; i < dumppages; ++i) { 731 vm_offset_t a = addr + (i * PAGE_SIZE); 732 if (is_physical_memory(a)) 733 va = pmap_kenter_temporary(trunc_page(a), i); 734 else 735 va = pmap_kenter_temporary(trunc_page(0), i); 736 } 737 738 if ((error = twe_dump_blocks(twe_sc, twed_sc->twed_drive->td_unit, blkno, va, 739 (PAGE_SIZE * dumppages) / TWE_BLOCK_SIZE)) != 0) 740 return(error); 741 742 743 if (dumpstatus(addr, (off_t)count * DEV_BSIZE) < 0) 744 return(EINTR); 745 746 blkno += blkcnt * dumppages; 747 count -= blkcnt * dumppages; 748 addr += PAGE_SIZE * dumppages; 749 } 750 return(0); 751 } 752 753 /******************************************************************************** 754 * Handle completion of an I/O request. 755 */ 756 void 757 twed_intr(twe_bio *bp) 758 { 759 debug_called(4); 760 761 /* if no error, transfer completed */ 762 if (!TWE_BIO_HAS_ERROR(bp)) 763 TWE_BIO_RESID(bp) = 0; 764 765 TWE_BIO_STATS_END(bp); 766 TWE_BIO_DONE(bp); 767 TWED_BIO_OUT; 768 } 769 770 /******************************************************************************** 771 * Default probe stub. 772 */ 773 static int 774 twed_probe(device_t dev) 775 { 776 return (0); 777 } 778 779 /******************************************************************************** 780 * Attach a unit to the controller. 781 */ 782 static int 783 twed_attach(device_t dev) 784 { 785 struct twed_softc *sc; 786 device_t parent; 787 dev_t dsk; 788 789 debug_called(4); 790 791 /* initialise our softc */ 792 sc = device_get_softc(dev); 793 parent = device_get_parent(dev); 794 sc->twed_controller = (struct twe_softc *)device_get_softc(parent); 795 sc->twed_drive = device_get_ivars(dev); 796 sc->twed_dev = dev; 797 798 /* report the drive */ 799 twed_printf(sc, "%uMB (%u sectors)\n", 800 sc->twed_drive->td_size / ((1024 * 1024) / TWE_BLOCK_SIZE), 801 sc->twed_drive->td_size); 802 803 devstat_add_entry(&sc->twed_stats, "twed", device_get_unit(dev), TWE_BLOCK_SIZE, 804 DEVSTAT_NO_ORDERED_TAGS, 805 DEVSTAT_TYPE_STORARRAY | DEVSTAT_TYPE_IF_OTHER, 806 DEVSTAT_PRIORITY_ARRAY); 807 808 /* attach a generic disk device to ourselves */ 809 dsk = disk_create(device_get_unit(dev), &sc->twed_disk, 0, &twed_cdevsw); 810 dsk->si_drv1 = sc; 811 dsk->si_drv2 = &sc->twed_drive->td_unit; 812 sc->twed_dev_t = dsk; 813 814 /* set the maximum I/O size to the theoretical maximum allowed by the S/G list size */ 815 dsk->si_iosize_max = (TWE_MAX_SGL_LENGTH - 1) * PAGE_SIZE; 816 817 return (0); 818 } 819 820 /******************************************************************************** 821 * Disconnect ourselves from the system. 822 */ 823 static int 824 twed_detach(device_t dev) 825 { 826 struct twed_softc *sc = (struct twed_softc *)device_get_softc(dev); 827 828 debug_called(4); 829 830 if (sc->twed_flags & TWED_OPEN) 831 return(EBUSY); 832 833 devstat_remove_entry(&sc->twed_stats); 834 disk_destroy(&sc->twed_disk); 835 836 return(0); 837 } 838 839 /******************************************************************************** 840 ******************************************************************************** 841 Misc 842 ******************************************************************************** 843 ********************************************************************************/ 844 845 static void twe_setup_data_dmamap(void *arg, bus_dma_segment_t *segs, int nsegments, int error); 846 static void twe_setup_request_dmamap(void *arg, bus_dma_segment_t *segs, int nsegments, int error); 847 848 /******************************************************************************** 849 * Allocate a command buffer 850 */ 851 MALLOC_DEFINE(TWE_MALLOC_CLASS, "twe commands", "twe commands"); 852 853 struct twe_request * 854 twe_allocate_request(struct twe_softc *sc) 855 { 856 struct twe_request *tr; 857 858 if ((tr = malloc(sizeof(struct twe_request), TWE_MALLOC_CLASS, M_NOWAIT)) == NULL) 859 return(NULL); 860 bzero(tr, sizeof(*tr)); 861 tr->tr_sc = sc; 862 if (bus_dmamap_create(sc->twe_buffer_dmat, 0, &tr->tr_cmdmap)) { 863 twe_free_request(tr); 864 return(NULL); 865 } 866 if (bus_dmamap_create(sc->twe_buffer_dmat, 0, &tr->tr_dmamap)) { 867 bus_dmamap_destroy(sc->twe_buffer_dmat, tr->tr_cmdmap); 868 twe_free_request(tr); 869 return(NULL); 870 } 871 return(tr); 872 } 873 874 /******************************************************************************** 875 * Permanently discard a command buffer. 876 */ 877 void 878 twe_free_request(struct twe_request *tr) 879 { 880 struct twe_softc *sc = tr->tr_sc; 881 882 debug_called(4); 883 884 bus_dmamap_destroy(sc->twe_buffer_dmat, tr->tr_cmdmap); 885 bus_dmamap_destroy(sc->twe_buffer_dmat, tr->tr_dmamap); 886 free(tr, TWE_MALLOC_CLASS); 887 } 888 889 /******************************************************************************** 890 * Map/unmap (tr)'s command and data in the controller's addressable space. 891 * 892 * These routines ensure that the data which the controller is going to try to 893 * access is actually visible to the controller, in a machine-independant 894 * fashion. Due to a hardware limitation, I/O buffers must be 512-byte aligned 895 * and we take care of that here as well. 896 */ 897 static void 898 twe_setup_data_dmamap(void *arg, bus_dma_segment_t *segs, int nsegments, int error) 899 { 900 struct twe_request *tr = (struct twe_request *)arg; 901 TWE_Command *cmd = &tr->tr_command; 902 int i; 903 904 debug_called(4); 905 906 /* save base of first segment in command (applicable if there only one segment) */ 907 tr->tr_dataphys = segs[0].ds_addr; 908 909 /* correct command size for s/g list size */ 910 tr->tr_command.generic.size += 2 * nsegments; 911 912 /* 913 * Due to the fact that parameter and I/O commands have the scatter/gather list in 914 * different places, we need to determine which sort of command this actually is 915 * before we can populate it correctly. 916 */ 917 switch(cmd->generic.opcode) { 918 case TWE_OP_GET_PARAM: 919 case TWE_OP_SET_PARAM: 920 cmd->generic.sgl_offset = 2; 921 for (i = 0; i < nsegments; i++) { 922 cmd->param.sgl[i].address = segs[i].ds_addr; 923 cmd->param.sgl[i].length = segs[i].ds_len; 924 } 925 for (; i < TWE_MAX_SGL_LENGTH; i++) { /* XXX necessary? */ 926 cmd->param.sgl[i].address = 0; 927 cmd->param.sgl[i].length = 0; 928 } 929 break; 930 case TWE_OP_READ: 931 case TWE_OP_WRITE: 932 cmd->generic.sgl_offset = 3; 933 for (i = 0; i < nsegments; i++) { 934 cmd->io.sgl[i].address = segs[i].ds_addr; 935 cmd->io.sgl[i].length = segs[i].ds_len; 936 } 937 for (; i < TWE_MAX_SGL_LENGTH; i++) { /* XXX necessary? */ 938 cmd->io.sgl[i].address = 0; 939 cmd->io.sgl[i].length = 0; 940 } 941 break; 942 default: 943 /* no s/g list, nothing to do */ 944 } 945 } 946 947 static void 948 twe_setup_request_dmamap(void *arg, bus_dma_segment_t *segs, int nsegments, int error) 949 { 950 struct twe_request *tr = (struct twe_request *)arg; 951 952 debug_called(4); 953 954 /* command can't cross a page boundary */ 955 tr->tr_cmdphys = segs[0].ds_addr; 956 } 957 958 void 959 twe_map_request(struct twe_request *tr) 960 { 961 struct twe_softc *sc = tr->tr_sc; 962 963 debug_called(4); 964 965 966 /* 967 * Map the command into bus space. 968 */ 969 bus_dmamap_load(sc->twe_buffer_dmat, tr->tr_cmdmap, &tr->tr_command, sizeof(tr->tr_command), 970 twe_setup_request_dmamap, tr, 0); 971 bus_dmamap_sync(sc->twe_buffer_dmat, tr->tr_cmdmap, BUS_DMASYNC_PREWRITE); 972 973 /* 974 * If the command involves data, map that too. 975 */ 976 if (tr->tr_data != NULL) { 977 978 /* 979 * Data must be 64-byte aligned; allocate a fixup buffer if it's not. 980 */ 981 if (((vm_offset_t)tr->tr_data % TWE_ALIGNMENT) != 0) { 982 tr->tr_realdata = tr->tr_data; /* save pointer to 'real' data */ 983 tr->tr_flags |= TWE_CMD_ALIGNBUF; 984 tr->tr_data = malloc(tr->tr_length, TWE_MALLOC_CLASS, M_NOWAIT); /* XXX check result here */ 985 } 986 987 /* 988 * Map the data buffer into bus space and build the s/g list. 989 */ 990 bus_dmamap_load(sc->twe_buffer_dmat, tr->tr_dmamap, tr->tr_data, tr->tr_length, 991 twe_setup_data_dmamap, tr, 0); 992 if (tr->tr_flags & TWE_CMD_DATAIN) 993 bus_dmamap_sync(sc->twe_buffer_dmat, tr->tr_dmamap, BUS_DMASYNC_PREREAD); 994 if (tr->tr_flags & TWE_CMD_DATAOUT) { 995 /* if we're using an alignment buffer, and we're writing data, copy the real data out */ 996 if (tr->tr_flags & TWE_CMD_ALIGNBUF) 997 bcopy(tr->tr_realdata, tr->tr_data, tr->tr_length); 998 bus_dmamap_sync(sc->twe_buffer_dmat, tr->tr_dmamap, BUS_DMASYNC_PREWRITE); 999 } 1000 } 1001 } 1002 1003 void 1004 twe_unmap_request(struct twe_request *tr) 1005 { 1006 struct twe_softc *sc = tr->tr_sc; 1007 1008 debug_called(4); 1009 1010 /* 1011 * Unmap the command from bus space. 1012 */ 1013 bus_dmamap_sync(sc->twe_buffer_dmat, tr->tr_cmdmap, BUS_DMASYNC_POSTWRITE); 1014 bus_dmamap_unload(sc->twe_buffer_dmat, tr->tr_cmdmap); 1015 1016 /* 1017 * If the command involved data, unmap that too. 1018 */ 1019 if (tr->tr_data != NULL) { 1020 1021 if (tr->tr_flags & TWE_CMD_DATAIN) { 1022 bus_dmamap_sync(sc->twe_buffer_dmat, tr->tr_dmamap, BUS_DMASYNC_POSTREAD); 1023 /* if we're using an alignment buffer, and we're reading data, copy the real data in */ 1024 if (tr->tr_flags & TWE_CMD_ALIGNBUF) 1025 bcopy(tr->tr_data, tr->tr_realdata, tr->tr_length); 1026 } 1027 if (tr->tr_flags & TWE_CMD_DATAOUT) 1028 bus_dmamap_sync(sc->twe_buffer_dmat, tr->tr_dmamap, BUS_DMASYNC_POSTWRITE); 1029 1030 bus_dmamap_unload(sc->twe_buffer_dmat, tr->tr_dmamap); 1031 } 1032 1033 /* free alignment buffer if it was used */ 1034 if (tr->tr_flags & TWE_CMD_ALIGNBUF) { 1035 free(tr->tr_data, TWE_MALLOC_CLASS); 1036 tr->tr_data = tr->tr_realdata; /* restore 'real' data pointer */ 1037 } 1038 } 1039 1040 #ifdef TWE_DEBUG 1041 /******************************************************************************** 1042 * Print current controller status, call from DDB. 1043 */ 1044 void 1045 twe_report(void) 1046 { 1047 struct twe_softc *sc; 1048 int i, s; 1049 1050 s = splbio(); 1051 for (i = 0; (sc = devclass_get_softc(twe_devclass, i)) != NULL; i++) 1052 twe_print_controller(sc); 1053 printf("twed: total bio count in %u out %u\n", twed_bio_in, twed_bio_out); 1054 splx(s); 1055 } 1056 #endif 1057