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.6 2003/09/22 21:45:22 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 "twe_compat.h" 43 #include "twereg.h" 44 #include "tweio.h" 45 #include "twevar.h" 46 #include "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 * Malloc space for 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 int aligned_size; 858 859 /* 860 * TWE requires requests to be 512-byte aligned. Depend on malloc() 861 * guarenteeing alignment for power-of-2 requests. Note that the old 862 * (FreeBSD-4.x) malloc code aligned all requests, but the new slab 863 * allocator only guarentees same-size alignment for power-of-2 requests. 864 */ 865 aligned_size = (sizeof(struct twe_request) + TWE_ALIGNMASK) & 866 ~TWE_ALIGNMASK; 867 if ((tr = malloc(aligned_size, TWE_MALLOC_CLASS, M_NOWAIT)) == NULL) 868 return(NULL); 869 bzero(tr, sizeof(*tr)); 870 tr->tr_sc = sc; 871 if (bus_dmamap_create(sc->twe_buffer_dmat, 0, &tr->tr_cmdmap)) { 872 twe_free_request(tr); 873 return(NULL); 874 } 875 if (bus_dmamap_create(sc->twe_buffer_dmat, 0, &tr->tr_dmamap)) { 876 bus_dmamap_destroy(sc->twe_buffer_dmat, tr->tr_cmdmap); 877 twe_free_request(tr); 878 return(NULL); 879 } 880 return(tr); 881 } 882 883 /******************************************************************************** 884 * Permanently discard a command buffer. 885 */ 886 void 887 twe_free_request(struct twe_request *tr) 888 { 889 struct twe_softc *sc = tr->tr_sc; 890 891 debug_called(4); 892 893 bus_dmamap_destroy(sc->twe_buffer_dmat, tr->tr_cmdmap); 894 bus_dmamap_destroy(sc->twe_buffer_dmat, tr->tr_dmamap); 895 free(tr, TWE_MALLOC_CLASS); 896 } 897 898 /******************************************************************************** 899 * Map/unmap (tr)'s command and data in the controller's addressable space. 900 * 901 * These routines ensure that the data which the controller is going to try to 902 * access is actually visible to the controller, in a machine-independant 903 * fashion. Due to a hardware limitation, I/O buffers must be 512-byte aligned 904 * and we take care of that here as well. 905 */ 906 static void 907 twe_setup_data_dmamap(void *arg, bus_dma_segment_t *segs, int nsegments, int error) 908 { 909 struct twe_request *tr = (struct twe_request *)arg; 910 TWE_Command *cmd = &tr->tr_command; 911 int i; 912 913 debug_called(4); 914 915 /* save base of first segment in command (applicable if there only one segment) */ 916 tr->tr_dataphys = segs[0].ds_addr; 917 918 /* correct command size for s/g list size */ 919 tr->tr_command.generic.size += 2 * nsegments; 920 921 /* 922 * Due to the fact that parameter and I/O commands have the scatter/gather list in 923 * different places, we need to determine which sort of command this actually is 924 * before we can populate it correctly. 925 */ 926 switch(cmd->generic.opcode) { 927 case TWE_OP_GET_PARAM: 928 case TWE_OP_SET_PARAM: 929 cmd->generic.sgl_offset = 2; 930 for (i = 0; i < nsegments; i++) { 931 cmd->param.sgl[i].address = segs[i].ds_addr; 932 cmd->param.sgl[i].length = segs[i].ds_len; 933 } 934 for (; i < TWE_MAX_SGL_LENGTH; i++) { /* XXX necessary? */ 935 cmd->param.sgl[i].address = 0; 936 cmd->param.sgl[i].length = 0; 937 } 938 break; 939 case TWE_OP_READ: 940 case TWE_OP_WRITE: 941 cmd->generic.sgl_offset = 3; 942 for (i = 0; i < nsegments; i++) { 943 cmd->io.sgl[i].address = segs[i].ds_addr; 944 cmd->io.sgl[i].length = segs[i].ds_len; 945 } 946 for (; i < TWE_MAX_SGL_LENGTH; i++) { /* XXX necessary? */ 947 cmd->io.sgl[i].address = 0; 948 cmd->io.sgl[i].length = 0; 949 } 950 break; 951 default: 952 /* no s/g list, nothing to do */ 953 } 954 } 955 956 static void 957 twe_setup_request_dmamap(void *arg, bus_dma_segment_t *segs, int nsegments, int error) 958 { 959 struct twe_request *tr = (struct twe_request *)arg; 960 961 debug_called(4); 962 963 /* command can't cross a page boundary */ 964 tr->tr_cmdphys = segs[0].ds_addr; 965 } 966 967 void 968 twe_map_request(struct twe_request *tr) 969 { 970 struct twe_softc *sc = tr->tr_sc; 971 972 debug_called(4); 973 974 975 /* 976 * Map the command into bus space. 977 */ 978 bus_dmamap_load(sc->twe_buffer_dmat, tr->tr_cmdmap, &tr->tr_command, sizeof(tr->tr_command), 979 twe_setup_request_dmamap, tr, 0); 980 bus_dmamap_sync(sc->twe_buffer_dmat, tr->tr_cmdmap, BUS_DMASYNC_PREWRITE); 981 982 /* 983 * If the command involves data, map that too. 984 */ 985 if (tr->tr_data != NULL) { 986 987 /* 988 * Data must be 512-byte aligned; allocate a fixup buffer if it's not. 989 */ 990 if (((vm_offset_t)tr->tr_data % TWE_ALIGNMENT) != 0) { 991 int aligned_size; 992 993 aligned_size = (tr->tr_length + TWE_ALIGNMASK) & ~TWE_ALIGNMASK; 994 tr->tr_realdata = tr->tr_data; /* save pointer to 'real' data */ 995 tr->tr_flags |= TWE_CMD_ALIGNBUF; 996 tr->tr_data = malloc(aligned_size, TWE_MALLOC_CLASS, M_NOWAIT); /* XXX check result here */ 997 } 998 999 /* 1000 * Map the data buffer into bus space and build the s/g list. 1001 */ 1002 bus_dmamap_load(sc->twe_buffer_dmat, tr->tr_dmamap, tr->tr_data, tr->tr_length, 1003 twe_setup_data_dmamap, tr, 0); 1004 if (tr->tr_flags & TWE_CMD_DATAIN) 1005 bus_dmamap_sync(sc->twe_buffer_dmat, tr->tr_dmamap, BUS_DMASYNC_PREREAD); 1006 if (tr->tr_flags & TWE_CMD_DATAOUT) { 1007 /* if we're using an alignment buffer, and we're writing data, copy the real data out */ 1008 if (tr->tr_flags & TWE_CMD_ALIGNBUF) 1009 bcopy(tr->tr_realdata, tr->tr_data, tr->tr_length); 1010 bus_dmamap_sync(sc->twe_buffer_dmat, tr->tr_dmamap, BUS_DMASYNC_PREWRITE); 1011 } 1012 } 1013 } 1014 1015 void 1016 twe_unmap_request(struct twe_request *tr) 1017 { 1018 struct twe_softc *sc = tr->tr_sc; 1019 1020 debug_called(4); 1021 1022 /* 1023 * Unmap the command from bus space. 1024 */ 1025 bus_dmamap_sync(sc->twe_buffer_dmat, tr->tr_cmdmap, BUS_DMASYNC_POSTWRITE); 1026 bus_dmamap_unload(sc->twe_buffer_dmat, tr->tr_cmdmap); 1027 1028 /* 1029 * If the command involved data, unmap that too. 1030 */ 1031 if (tr->tr_data != NULL) { 1032 1033 if (tr->tr_flags & TWE_CMD_DATAIN) { 1034 bus_dmamap_sync(sc->twe_buffer_dmat, tr->tr_dmamap, BUS_DMASYNC_POSTREAD); 1035 /* if we're using an alignment buffer, and we're reading data, copy the real data in */ 1036 if (tr->tr_flags & TWE_CMD_ALIGNBUF) 1037 bcopy(tr->tr_data, tr->tr_realdata, tr->tr_length); 1038 } 1039 if (tr->tr_flags & TWE_CMD_DATAOUT) 1040 bus_dmamap_sync(sc->twe_buffer_dmat, tr->tr_dmamap, BUS_DMASYNC_POSTWRITE); 1041 1042 bus_dmamap_unload(sc->twe_buffer_dmat, tr->tr_dmamap); 1043 } 1044 1045 /* free alignment buffer if it was used */ 1046 if (tr->tr_flags & TWE_CMD_ALIGNBUF) { 1047 free(tr->tr_data, TWE_MALLOC_CLASS); 1048 tr->tr_data = tr->tr_realdata; /* restore 'real' data pointer */ 1049 } 1050 } 1051 1052 #ifdef TWE_DEBUG 1053 /******************************************************************************** 1054 * Print current controller status, call from DDB. 1055 */ 1056 void 1057 twe_report(void) 1058 { 1059 struct twe_softc *sc; 1060 int i, s; 1061 1062 s = splbio(); 1063 for (i = 0; (sc = devclass_get_softc(twe_devclass, i)) != NULL; i++) 1064 twe_print_controller(sc); 1065 printf("twed: total bio count in %u out %u\n", twed_bio_in, twed_bio_out); 1066 splx(s); 1067 } 1068 #endif 1069