twe_freebsd.c revision 239244
1/*- 2 * Copyright (c) 2000 Michael Smith 3 * Copyright (c) 2003 Paul Saab 4 * Copyright (c) 2003 Vinod Kashyap 5 * Copyright (c) 2000 BSDi 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 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 21 * FOR 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#include <sys/cdefs.h> 31__FBSDID("$FreeBSD: head/sys/dev/twe/twe_freebsd.c 239244 2012-08-13 21:29:34Z jhb $"); 32 33/* 34 * FreeBSD-specific code. 35 */ 36 37#include <dev/twe/twe_compat.h> 38#include <dev/twe/twereg.h> 39#include <dev/twe/tweio.h> 40#include <dev/twe/twevar.h> 41#include <dev/twe/twe_tables.h> 42 43#include <vm/vm.h> 44 45static devclass_t twe_devclass; 46 47#ifdef TWE_DEBUG 48static u_int32_t twed_bio_in; 49#define TWED_BIO_IN twed_bio_in++ 50static u_int32_t twed_bio_out; 51#define TWED_BIO_OUT twed_bio_out++ 52#else 53#define TWED_BIO_IN 54#define TWED_BIO_OUT 55#endif 56 57static void twe_setup_data_dmamap(void *arg, bus_dma_segment_t *segs, int nsegments, int error); 58static void twe_setup_request_dmamap(void *arg, bus_dma_segment_t *segs, int nsegments, int error); 59 60/******************************************************************************** 61 ******************************************************************************** 62 Control device interface 63 ******************************************************************************** 64 ********************************************************************************/ 65 66static d_open_t twe_open; 67static d_close_t twe_close; 68static d_ioctl_t twe_ioctl_wrapper; 69 70static struct cdevsw twe_cdevsw = { 71 .d_version = D_VERSION, 72 .d_open = twe_open, 73 .d_close = twe_close, 74 .d_ioctl = twe_ioctl_wrapper, 75 .d_name = "twe", 76}; 77 78/******************************************************************************** 79 * Accept an open operation on the control device. 80 */ 81static int 82twe_open(struct cdev *dev, int flags, int fmt, struct thread *td) 83{ 84 struct twe_softc *sc = (struct twe_softc *)dev->si_drv1; 85 86 TWE_IO_LOCK(sc); 87 if (sc->twe_state & TWE_STATE_DETACHING) { 88 TWE_IO_UNLOCK(sc); 89 return (ENXIO); 90 } 91 sc->twe_state |= TWE_STATE_OPEN; 92 TWE_IO_UNLOCK(sc); 93 return(0); 94} 95 96/******************************************************************************** 97 * Accept the last close on the control device. 98 */ 99static int 100twe_close(struct cdev *dev, int flags, int fmt, struct thread *td) 101{ 102 struct twe_softc *sc = (struct twe_softc *)dev->si_drv1; 103 104 TWE_IO_LOCK(sc); 105 sc->twe_state &= ~TWE_STATE_OPEN; 106 TWE_IO_UNLOCK(sc); 107 return (0); 108} 109 110/******************************************************************************** 111 * Handle controller-specific control operations. 112 */ 113static int 114twe_ioctl_wrapper(struct cdev *dev, u_long cmd, caddr_t addr, int32_t flag, struct thread *td) 115{ 116 struct twe_softc *sc = (struct twe_softc *)dev->si_drv1; 117 118 return(twe_ioctl(sc, cmd, addr)); 119} 120 121/******************************************************************************** 122 ******************************************************************************** 123 PCI device interface 124 ******************************************************************************** 125 ********************************************************************************/ 126 127static int twe_probe(device_t dev); 128static int twe_attach(device_t dev); 129static void twe_free(struct twe_softc *sc); 130static int twe_detach(device_t dev); 131static int twe_shutdown(device_t dev); 132static int twe_suspend(device_t dev); 133static int twe_resume(device_t dev); 134static void twe_pci_intr(void *arg); 135static void twe_intrhook(void *arg); 136 137static device_method_t twe_methods[] = { 138 /* Device interface */ 139 DEVMETHOD(device_probe, twe_probe), 140 DEVMETHOD(device_attach, twe_attach), 141 DEVMETHOD(device_detach, twe_detach), 142 DEVMETHOD(device_shutdown, twe_shutdown), 143 DEVMETHOD(device_suspend, twe_suspend), 144 DEVMETHOD(device_resume, twe_resume), 145 146 DEVMETHOD_END 147}; 148 149static driver_t twe_pci_driver = { 150 "twe", 151 twe_methods, 152 sizeof(struct twe_softc) 153}; 154 155DRIVER_MODULE(twe, pci, twe_pci_driver, twe_devclass, 0, 0); 156 157/******************************************************************************** 158 * Match a 3ware Escalade ATA RAID controller. 159 */ 160static int 161twe_probe(device_t dev) 162{ 163 164 debug_called(4); 165 166 if ((pci_get_vendor(dev) == TWE_VENDOR_ID) && 167 ((pci_get_device(dev) == TWE_DEVICE_ID) || 168 (pci_get_device(dev) == TWE_DEVICE_ID_ASIC))) { 169 device_set_desc_copy(dev, TWE_DEVICE_NAME ". Driver version " TWE_DRIVER_VERSION_STRING); 170 return(BUS_PROBE_DEFAULT); 171 } 172 return(ENXIO); 173} 174 175/******************************************************************************** 176 * Allocate resources, initialise the controller. 177 */ 178static int 179twe_attach(device_t dev) 180{ 181 struct twe_softc *sc; 182 struct sysctl_oid *sysctl_tree; 183 int rid, error; 184 185 debug_called(4); 186 187 /* 188 * Initialise the softc structure. 189 */ 190 sc = device_get_softc(dev); 191 sc->twe_dev = dev; 192 mtx_init(&sc->twe_io_lock, "twe I/O", NULL, MTX_DEF); 193 sx_init(&sc->twe_config_lock, "twe config"); 194 195 /* 196 * XXX: This sysctl tree must stay at hw.tweX rather than using 197 * the device_get_sysctl_tree() created by new-bus because 198 * existing 3rd party binary tools such as tw_cli and 3dm2 use the 199 * existence of this sysctl node to discover controllers. 200 */ 201 sysctl_tree = SYSCTL_ADD_NODE(device_get_sysctl_ctx(dev), 202 SYSCTL_STATIC_CHILDREN(_hw), OID_AUTO, 203 device_get_nameunit(dev), CTLFLAG_RD, 0, ""); 204 if (sysctl_tree == NULL) { 205 twe_printf(sc, "cannot add sysctl tree node\n"); 206 return (ENXIO); 207 } 208 SYSCTL_ADD_STRING(device_get_sysctl_ctx(dev), SYSCTL_CHILDREN(sysctl_tree), 209 OID_AUTO, "driver_version", CTLFLAG_RD, TWE_DRIVER_VERSION_STRING, 0, 210 "TWE driver version"); 211 212 /* 213 * Force the busmaster enable bit on, in case the BIOS forgot. 214 */ 215 pci_enable_busmaster(dev); 216 217 /* 218 * Allocate the PCI register window. 219 */ 220 rid = TWE_IO_CONFIG_REG; 221 if ((sc->twe_io = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid, 222 RF_ACTIVE)) == NULL) { 223 twe_printf(sc, "can't allocate register window\n"); 224 twe_free(sc); 225 return(ENXIO); 226 } 227 228 /* 229 * Allocate the parent bus DMA tag appropriate for PCI. 230 */ 231 if (bus_dma_tag_create(bus_get_dma_tag(dev), /* PCI parent */ 232 1, 0, /* alignment, boundary */ 233 BUS_SPACE_MAXADDR_32BIT, /* lowaddr */ 234 BUS_SPACE_MAXADDR, /* highaddr */ 235 NULL, NULL, /* filter, filterarg */ 236 MAXBSIZE, TWE_MAX_SGL_LENGTH, /* maxsize, nsegments */ 237 BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */ 238 0, /* flags */ 239 NULL, /* lockfunc */ 240 NULL, /* lockarg */ 241 &sc->twe_parent_dmat)) { 242 twe_printf(sc, "can't allocate parent DMA tag\n"); 243 twe_free(sc); 244 return(ENOMEM); 245 } 246 247 /* 248 * Allocate and connect our interrupt. 249 */ 250 rid = 0; 251 if ((sc->twe_irq = bus_alloc_resource_any(sc->twe_dev, SYS_RES_IRQ, 252 &rid, RF_SHAREABLE | RF_ACTIVE)) == NULL) { 253 twe_printf(sc, "can't allocate interrupt\n"); 254 twe_free(sc); 255 return(ENXIO); 256 } 257 if (bus_setup_intr(sc->twe_dev, sc->twe_irq, INTR_TYPE_BIO | INTR_ENTROPY | INTR_MPSAFE, 258 NULL, twe_pci_intr, sc, &sc->twe_intr)) { 259 twe_printf(sc, "can't set up interrupt\n"); 260 twe_free(sc); 261 return(ENXIO); 262 } 263 264 /* 265 * Create DMA tag for mapping command's into controller-addressable space. 266 */ 267 if (bus_dma_tag_create(sc->twe_parent_dmat, /* parent */ 268 1, 0, /* alignment, boundary */ 269 BUS_SPACE_MAXADDR_32BIT, /* lowaddr */ 270 BUS_SPACE_MAXADDR, /* highaddr */ 271 NULL, NULL, /* filter, filterarg */ 272 sizeof(TWE_Command) * 273 TWE_Q_LENGTH, 1, /* maxsize, nsegments */ 274 BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */ 275 0, /* flags */ 276 NULL, /* lockfunc */ 277 NULL, /* lockarg */ 278 &sc->twe_cmd_dmat)) { 279 twe_printf(sc, "can't allocate data buffer DMA tag\n"); 280 twe_free(sc); 281 return(ENOMEM); 282 } 283 /* 284 * Allocate memory and make it available for DMA. 285 */ 286 if (bus_dmamem_alloc(sc->twe_cmd_dmat, (void **)&sc->twe_cmd, 287 BUS_DMA_NOWAIT, &sc->twe_cmdmap)) { 288 twe_printf(sc, "can't allocate command memory\n"); 289 return(ENOMEM); 290 } 291 bus_dmamap_load(sc->twe_cmd_dmat, sc->twe_cmdmap, sc->twe_cmd, 292 sizeof(TWE_Command) * TWE_Q_LENGTH, 293 twe_setup_request_dmamap, sc, 0); 294 bzero(sc->twe_cmd, sizeof(TWE_Command) * TWE_Q_LENGTH); 295 296 /* 297 * Create DMA tag for mapping objects into controller-addressable space. 298 */ 299 if (bus_dma_tag_create(sc->twe_parent_dmat, /* parent */ 300 1, 0, /* alignment, boundary */ 301 BUS_SPACE_MAXADDR_32BIT, /* lowaddr */ 302 BUS_SPACE_MAXADDR, /* highaddr */ 303 NULL, NULL, /* filter, filterarg */ 304 MAXBSIZE, TWE_MAX_SGL_LENGTH,/* maxsize, nsegments */ 305 BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */ 306 BUS_DMA_ALLOCNOW, /* flags */ 307 busdma_lock_mutex, /* lockfunc */ 308 &sc->twe_io_lock, /* lockarg */ 309 &sc->twe_buffer_dmat)) { 310 twe_printf(sc, "can't allocate data buffer DMA tag\n"); 311 twe_free(sc); 312 return(ENOMEM); 313 } 314 315 /* 316 * Create DMA tag for mapping objects into controller-addressable space. 317 */ 318 if (bus_dma_tag_create(sc->twe_parent_dmat, /* parent */ 319 1, 0, /* alignment, boundary */ 320 BUS_SPACE_MAXADDR_32BIT, /* lowaddr */ 321 BUS_SPACE_MAXADDR, /* highaddr */ 322 NULL, NULL, /* filter, filterarg */ 323 MAXBSIZE, 1, /* maxsize, nsegments */ 324 BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */ 325 0, /* flags */ 326 NULL, /* lockfunc */ 327 NULL, /* lockarg */ 328 &sc->twe_immediate_dmat)) { 329 twe_printf(sc, "can't allocate data buffer DMA tag\n"); 330 twe_free(sc); 331 return(ENOMEM); 332 } 333 /* 334 * Allocate memory for requests which cannot sleep or support continuation. 335 */ 336 if (bus_dmamem_alloc(sc->twe_immediate_dmat, (void **)&sc->twe_immediate, 337 BUS_DMA_NOWAIT, &sc->twe_immediate_map)) { 338 twe_printf(sc, "can't allocate memory for immediate requests\n"); 339 return(ENOMEM); 340 } 341 342 /* 343 * Initialise the controller and driver core. 344 */ 345 if ((error = twe_setup(sc))) { 346 twe_free(sc); 347 return(error); 348 } 349 350 /* 351 * Print some information about the controller and configuration. 352 */ 353 twe_describe_controller(sc); 354 355 /* 356 * Create the control device. 357 */ 358 sc->twe_dev_t = make_dev(&twe_cdevsw, device_get_unit(sc->twe_dev), UID_ROOT, GID_OPERATOR, 359 S_IRUSR | S_IWUSR, "twe%d", device_get_unit(sc->twe_dev)); 360 sc->twe_dev_t->si_drv1 = sc; 361 /* 362 * Schedule ourselves to bring the controller up once interrupts are available. 363 * This isn't strictly necessary, since we disable interrupts while probing the 364 * controller, but it is more in keeping with common practice for other disk 365 * devices. 366 */ 367 sc->twe_ich.ich_func = twe_intrhook; 368 sc->twe_ich.ich_arg = sc; 369 if (config_intrhook_establish(&sc->twe_ich) != 0) { 370 twe_printf(sc, "can't establish configuration hook\n"); 371 twe_free(sc); 372 return(ENXIO); 373 } 374 375 return(0); 376} 377 378/******************************************************************************** 379 * Free all of the resources associated with (sc). 380 * 381 * Should not be called if the controller is active. 382 */ 383static void 384twe_free(struct twe_softc *sc) 385{ 386 struct twe_request *tr; 387 388 debug_called(4); 389 390 /* throw away any command buffers */ 391 while ((tr = twe_dequeue_free(sc)) != NULL) 392 twe_free_request(tr); 393 394 if (sc->twe_cmd != NULL) { 395 bus_dmamap_unload(sc->twe_cmd_dmat, sc->twe_cmdmap); 396 bus_dmamem_free(sc->twe_cmd_dmat, sc->twe_cmd, sc->twe_cmdmap); 397 } 398 399 if (sc->twe_immediate != NULL) { 400 bus_dmamap_unload(sc->twe_immediate_dmat, sc->twe_immediate_map); 401 bus_dmamem_free(sc->twe_immediate_dmat, sc->twe_immediate, 402 sc->twe_immediate_map); 403 } 404 405 if (sc->twe_immediate_dmat) 406 bus_dma_tag_destroy(sc->twe_immediate_dmat); 407 408 /* destroy the data-transfer DMA tag */ 409 if (sc->twe_buffer_dmat) 410 bus_dma_tag_destroy(sc->twe_buffer_dmat); 411 412 /* disconnect the interrupt handler */ 413 if (sc->twe_intr) 414 bus_teardown_intr(sc->twe_dev, sc->twe_irq, sc->twe_intr); 415 if (sc->twe_irq != NULL) 416 bus_release_resource(sc->twe_dev, SYS_RES_IRQ, 0, sc->twe_irq); 417 418 /* destroy the parent DMA tag */ 419 if (sc->twe_parent_dmat) 420 bus_dma_tag_destroy(sc->twe_parent_dmat); 421 422 /* release the register window mapping */ 423 if (sc->twe_io != NULL) 424 bus_release_resource(sc->twe_dev, SYS_RES_IOPORT, TWE_IO_CONFIG_REG, sc->twe_io); 425 426 /* destroy control device */ 427 if (sc->twe_dev_t != (struct cdev *)NULL) 428 destroy_dev(sc->twe_dev_t); 429 430 sx_destroy(&sc->twe_config_lock); 431 mtx_destroy(&sc->twe_io_lock); 432} 433 434/******************************************************************************** 435 * Disconnect from the controller completely, in preparation for unload. 436 */ 437static int 438twe_detach(device_t dev) 439{ 440 struct twe_softc *sc = device_get_softc(dev); 441 442 debug_called(4); 443 444 TWE_IO_LOCK(sc); 445 if (sc->twe_state & TWE_STATE_OPEN) { 446 TWE_IO_UNLOCK(sc); 447 return (EBUSY); 448 } 449 sc->twe_state |= TWE_STATE_DETACHING; 450 TWE_IO_UNLOCK(sc); 451 452 /* 453 * Shut the controller down. 454 */ 455 if (twe_shutdown(dev)) { 456 TWE_IO_LOCK(sc); 457 sc->twe_state &= ~TWE_STATE_DETACHING; 458 TWE_IO_UNLOCK(sc); 459 return (EBUSY); 460 } 461 462 twe_free(sc); 463 464 return(0); 465} 466 467/******************************************************************************** 468 * Bring the controller down to a dormant state and detach all child devices. 469 * 470 * Note that we can assume that the bioq on the controller is empty, as we won't 471 * allow shutdown if any device is open. 472 */ 473static int 474twe_shutdown(device_t dev) 475{ 476 struct twe_softc *sc = device_get_softc(dev); 477 int i, error = 0; 478 479 debug_called(4); 480 481 /* 482 * Delete all our child devices. 483 */ 484 TWE_CONFIG_LOCK(sc); 485 for (i = 0; i < TWE_MAX_UNITS; i++) { 486 if (sc->twe_drive[i].td_disk != 0) { 487 if ((error = twe_detach_drive(sc, i)) != 0) { 488 TWE_CONFIG_UNLOCK(sc); 489 return (error); 490 } 491 } 492 } 493 TWE_CONFIG_UNLOCK(sc); 494 495 /* 496 * Bring the controller down. 497 */ 498 TWE_IO_LOCK(sc); 499 twe_deinit(sc); 500 TWE_IO_UNLOCK(sc); 501 502 return(0); 503} 504 505/******************************************************************************** 506 * Bring the controller to a quiescent state, ready for system suspend. 507 */ 508static int 509twe_suspend(device_t dev) 510{ 511 struct twe_softc *sc = device_get_softc(dev); 512 513 debug_called(4); 514 515 TWE_IO_LOCK(sc); 516 sc->twe_state |= TWE_STATE_SUSPEND; 517 518 twe_disable_interrupts(sc); 519 TWE_IO_UNLOCK(sc); 520 521 return(0); 522} 523 524/******************************************************************************** 525 * Bring the controller back to a state ready for operation. 526 */ 527static int 528twe_resume(device_t dev) 529{ 530 struct twe_softc *sc = device_get_softc(dev); 531 532 debug_called(4); 533 534 TWE_IO_LOCK(sc); 535 sc->twe_state &= ~TWE_STATE_SUSPEND; 536 twe_enable_interrupts(sc); 537 TWE_IO_UNLOCK(sc); 538 539 return(0); 540} 541 542/******************************************************************************* 543 * Take an interrupt, or be poked by other code to look for interrupt-worthy 544 * status. 545 */ 546static void 547twe_pci_intr(void *arg) 548{ 549 struct twe_softc *sc = arg; 550 551 TWE_IO_LOCK(sc); 552 twe_intr(sc); 553 TWE_IO_UNLOCK(sc); 554} 555 556/******************************************************************************** 557 * Delayed-startup hook 558 */ 559static void 560twe_intrhook(void *arg) 561{ 562 struct twe_softc *sc = (struct twe_softc *)arg; 563 564 /* pull ourselves off the intrhook chain */ 565 config_intrhook_disestablish(&sc->twe_ich); 566 567 /* call core startup routine */ 568 twe_init(sc); 569} 570 571/******************************************************************************** 572 * Given a detected drive, attach it to the bio interface. 573 * 574 * This is called from twe_add_unit. 575 */ 576int 577twe_attach_drive(struct twe_softc *sc, struct twe_drive *dr) 578{ 579 char buf[80]; 580 int error; 581 582 mtx_lock(&Giant); 583 dr->td_disk = device_add_child(sc->twe_dev, NULL, -1); 584 if (dr->td_disk == NULL) { 585 mtx_unlock(&Giant); 586 twe_printf(sc, "Cannot add unit\n"); 587 return (EIO); 588 } 589 device_set_ivars(dr->td_disk, dr); 590 591 /* 592 * XXX It would make sense to test the online/initialising bits, but they seem to be 593 * always set... 594 */ 595 sprintf(buf, "Unit %d, %s, %s", 596 dr->td_twe_unit, 597 twe_describe_code(twe_table_unittype, dr->td_type), 598 twe_describe_code(twe_table_unitstate, dr->td_state & TWE_PARAM_UNITSTATUS_MASK)); 599 device_set_desc_copy(dr->td_disk, buf); 600 601 error = device_probe_and_attach(dr->td_disk); 602 mtx_unlock(&Giant); 603 if (error != 0) { 604 twe_printf(sc, "Cannot attach unit to controller. error = %d\n", error); 605 return (EIO); 606 } 607 return (0); 608} 609 610/******************************************************************************** 611 * Detach the specified unit if it exsists 612 * 613 * This is called from twe_del_unit. 614 */ 615int 616twe_detach_drive(struct twe_softc *sc, int unit) 617{ 618 int error = 0; 619 620 TWE_CONFIG_ASSERT_LOCKED(sc); 621 mtx_lock(&Giant); 622 error = device_delete_child(sc->twe_dev, sc->twe_drive[unit].td_disk); 623 mtx_unlock(&Giant); 624 if (error != 0) { 625 twe_printf(sc, "failed to delete unit %d\n", unit); 626 return(error); 627 } 628 bzero(&sc->twe_drive[unit], sizeof(sc->twe_drive[unit])); 629 return(error); 630} 631 632/******************************************************************************** 633 * Clear a PCI parity error. 634 */ 635void 636twe_clear_pci_parity_error(struct twe_softc *sc) 637{ 638 TWE_CONTROL(sc, TWE_CONTROL_CLEAR_PARITY_ERROR); 639 pci_write_config(sc->twe_dev, PCIR_STATUS, TWE_PCI_CLEAR_PARITY_ERROR, 2); 640} 641 642/******************************************************************************** 643 * Clear a PCI abort. 644 */ 645void 646twe_clear_pci_abort(struct twe_softc *sc) 647{ 648 TWE_CONTROL(sc, TWE_CONTROL_CLEAR_PCI_ABORT); 649 pci_write_config(sc->twe_dev, PCIR_STATUS, TWE_PCI_CLEAR_PCI_ABORT, 2); 650} 651 652/******************************************************************************** 653 ******************************************************************************** 654 Disk device 655 ******************************************************************************** 656 ********************************************************************************/ 657 658/* 659 * Disk device softc 660 */ 661struct twed_softc 662{ 663 device_t twed_dev; 664 struct twe_softc *twed_controller; /* parent device softc */ 665 struct twe_drive *twed_drive; /* drive data in parent softc */ 666 struct disk *twed_disk; /* generic disk handle */ 667}; 668 669/* 670 * Disk device bus interface 671 */ 672static int twed_probe(device_t dev); 673static int twed_attach(device_t dev); 674static int twed_detach(device_t dev); 675 676static device_method_t twed_methods[] = { 677 DEVMETHOD(device_probe, twed_probe), 678 DEVMETHOD(device_attach, twed_attach), 679 DEVMETHOD(device_detach, twed_detach), 680 { 0, 0 } 681}; 682 683static driver_t twed_driver = { 684 "twed", 685 twed_methods, 686 sizeof(struct twed_softc) 687}; 688 689static devclass_t twed_devclass; 690DRIVER_MODULE(twed, twe, twed_driver, twed_devclass, 0, 0); 691 692/* 693 * Disk device control interface. 694 */ 695 696/******************************************************************************** 697 * Handle open from generic layer. 698 * 699 * Note that this is typically only called by the diskslice code, and not 700 * for opens on subdevices (eg. slices, partitions). 701 */ 702static int 703twed_open(struct disk *dp) 704{ 705 struct twed_softc *sc = (struct twed_softc *)dp->d_drv1; 706 707 debug_called(4); 708 709 if (sc == NULL) 710 return (ENXIO); 711 712 /* check that the controller is up and running */ 713 if (sc->twed_controller->twe_state & TWE_STATE_SHUTDOWN) 714 return(ENXIO); 715 716 return (0); 717} 718 719/******************************************************************************** 720 * Handle an I/O request. 721 */ 722static void 723twed_strategy(twe_bio *bp) 724{ 725 struct twed_softc *sc = (struct twed_softc *)TWE_BIO_SOFTC(bp); 726 727 debug_called(4); 728 729 bp->bio_driver1 = &sc->twed_drive->td_twe_unit; 730 TWED_BIO_IN; 731 732 /* bogus disk? */ 733 if (sc == NULL || sc->twed_drive->td_disk == NULL) { 734 TWE_BIO_SET_ERROR(bp, EINVAL); 735 printf("twe: bio for invalid disk!\n"); 736 TWE_BIO_DONE(bp); 737 TWED_BIO_OUT; 738 return; 739 } 740 741 /* perform accounting */ 742 TWE_BIO_STATS_START(bp); 743 744 /* queue the bio on the controller */ 745 TWE_IO_LOCK(sc->twed_controller); 746 twe_enqueue_bio(sc->twed_controller, bp); 747 748 /* poke the controller to start I/O */ 749 twe_startio(sc->twed_controller); 750 TWE_IO_UNLOCK(sc->twed_controller); 751 return; 752} 753 754/******************************************************************************** 755 * System crashdump support 756 */ 757static int 758twed_dump(void *arg, void *virtual, vm_offset_t physical, off_t offset, size_t length) 759{ 760 struct twed_softc *twed_sc; 761 struct twe_softc *twe_sc; 762 int error; 763 struct disk *dp; 764 765 dp = arg; 766 twed_sc = (struct twed_softc *)dp->d_drv1; 767 if (twed_sc == NULL) 768 return(ENXIO); 769 twe_sc = (struct twe_softc *)twed_sc->twed_controller; 770 771 if (length > 0) { 772 if ((error = twe_dump_blocks(twe_sc, twed_sc->twed_drive->td_twe_unit, offset / TWE_BLOCK_SIZE, virtual, length / TWE_BLOCK_SIZE)) != 0) 773 return(error); 774 } 775 return(0); 776} 777 778/******************************************************************************** 779 * Handle completion of an I/O request. 780 */ 781void 782twed_intr(twe_bio *bp) 783{ 784 debug_called(4); 785 786 /* if no error, transfer completed */ 787 if (!TWE_BIO_HAS_ERROR(bp)) 788 TWE_BIO_RESID(bp) = 0; 789 790 TWE_BIO_STATS_END(bp); 791 TWE_BIO_DONE(bp); 792 TWED_BIO_OUT; 793} 794 795/******************************************************************************** 796 * Default probe stub. 797 */ 798static int 799twed_probe(device_t dev) 800{ 801 return (0); 802} 803 804/******************************************************************************** 805 * Attach a unit to the controller. 806 */ 807static int 808twed_attach(device_t dev) 809{ 810 struct twed_softc *sc; 811 device_t parent; 812 813 debug_called(4); 814 815 /* initialise our softc */ 816 sc = device_get_softc(dev); 817 parent = device_get_parent(dev); 818 sc->twed_controller = (struct twe_softc *)device_get_softc(parent); 819 sc->twed_drive = device_get_ivars(dev); 820 sc->twed_dev = dev; 821 822 /* report the drive */ 823 twed_printf(sc, "%uMB (%u sectors)\n", 824 sc->twed_drive->td_size / ((1024 * 1024) / TWE_BLOCK_SIZE), 825 sc->twed_drive->td_size); 826 827 /* attach a generic disk device to ourselves */ 828 829 sc->twed_drive->td_sys_unit = device_get_unit(dev); 830 831 sc->twed_disk = disk_alloc(); 832 sc->twed_disk->d_open = twed_open; 833 sc->twed_disk->d_strategy = twed_strategy; 834 sc->twed_disk->d_dump = (dumper_t *)twed_dump; 835 sc->twed_disk->d_name = "twed"; 836 sc->twed_disk->d_drv1 = sc; 837 sc->twed_disk->d_maxsize = (TWE_MAX_SGL_LENGTH - 1) * PAGE_SIZE; 838 sc->twed_disk->d_sectorsize = TWE_BLOCK_SIZE; 839 sc->twed_disk->d_mediasize = TWE_BLOCK_SIZE * (off_t)sc->twed_drive->td_size; 840 if (sc->twed_drive->td_type == TWE_UD_CONFIG_RAID0 || 841 sc->twed_drive->td_type == TWE_UD_CONFIG_RAID5 || 842 sc->twed_drive->td_type == TWE_UD_CONFIG_RAID10) { 843 sc->twed_disk->d_stripesize = 844 TWE_BLOCK_SIZE << sc->twed_drive->td_stripe; 845 sc->twed_disk->d_stripeoffset = 0; 846 } 847 sc->twed_disk->d_fwsectors = sc->twed_drive->td_sectors; 848 sc->twed_disk->d_fwheads = sc->twed_drive->td_heads; 849 sc->twed_disk->d_unit = sc->twed_drive->td_sys_unit; 850 851 disk_create(sc->twed_disk, DISK_VERSION); 852 853 /* set the maximum I/O size to the theoretical maximum allowed by the S/G list size */ 854 855 return (0); 856} 857 858/******************************************************************************** 859 * Disconnect ourselves from the system. 860 */ 861static int 862twed_detach(device_t dev) 863{ 864 struct twed_softc *sc = (struct twed_softc *)device_get_softc(dev); 865 866 debug_called(4); 867 868 if (sc->twed_disk->d_flags & DISKFLAG_OPEN) 869 return(EBUSY); 870 871 disk_destroy(sc->twed_disk); 872 873 return(0); 874} 875 876/******************************************************************************** 877 ******************************************************************************** 878 Misc 879 ******************************************************************************** 880 ********************************************************************************/ 881 882/******************************************************************************** 883 * Allocate a command buffer 884 */ 885static MALLOC_DEFINE(TWE_MALLOC_CLASS, "twe_commands", "twe commands"); 886 887struct twe_request * 888twe_allocate_request(struct twe_softc *sc, int tag) 889{ 890 struct twe_request *tr; 891 892 tr = malloc(sizeof(struct twe_request), TWE_MALLOC_CLASS, M_WAITOK | M_ZERO); 893 tr->tr_sc = sc; 894 tr->tr_tag = tag; 895 if (bus_dmamap_create(sc->twe_buffer_dmat, 0, &tr->tr_dmamap)) { 896 twe_free_request(tr); 897 twe_printf(sc, "unable to allocate dmamap for tag %d\n", tag); 898 return(NULL); 899 } 900 return(tr); 901} 902 903/******************************************************************************** 904 * Permanently discard a command buffer. 905 */ 906void 907twe_free_request(struct twe_request *tr) 908{ 909 struct twe_softc *sc = tr->tr_sc; 910 911 debug_called(4); 912 913 bus_dmamap_destroy(sc->twe_buffer_dmat, tr->tr_dmamap); 914 free(tr, TWE_MALLOC_CLASS); 915} 916 917/******************************************************************************** 918 * Map/unmap (tr)'s command and data in the controller's addressable space. 919 * 920 * These routines ensure that the data which the controller is going to try to 921 * access is actually visible to the controller, in a machine-independant 922 * fashion. Due to a hardware limitation, I/O buffers must be 512-byte aligned 923 * and we take care of that here as well. 924 */ 925static void 926twe_fillin_sgl(TWE_SG_Entry *sgl, bus_dma_segment_t *segs, int nsegments, int max_sgl) 927{ 928 int i; 929 930 for (i = 0; i < nsegments; i++) { 931 sgl[i].address = segs[i].ds_addr; 932 sgl[i].length = segs[i].ds_len; 933 } 934 for (; i < max_sgl; i++) { /* XXX necessary? */ 935 sgl[i].address = 0; 936 sgl[i].length = 0; 937 } 938} 939 940static void 941twe_setup_data_dmamap(void *arg, bus_dma_segment_t *segs, int nsegments, int error) 942{ 943 struct twe_request *tr = (struct twe_request *)arg; 944 struct twe_softc *sc = tr->tr_sc; 945 TWE_Command *cmd = TWE_FIND_COMMAND(tr); 946 947 debug_called(4); 948 949 if (tr->tr_flags & TWE_CMD_MAPPED) 950 panic("already mapped command"); 951 952 tr->tr_flags |= TWE_CMD_MAPPED; 953 954 if (tr->tr_flags & TWE_CMD_IN_PROGRESS) 955 sc->twe_state &= ~TWE_STATE_FRZN; 956 /* save base of first segment in command (applicable if there only one segment) */ 957 tr->tr_dataphys = segs[0].ds_addr; 958 959 /* correct command size for s/g list size */ 960 cmd->generic.size += 2 * nsegments; 961 962 /* 963 * Due to the fact that parameter and I/O commands have the scatter/gather list in 964 * different places, we need to determine which sort of command this actually is 965 * before we can populate it correctly. 966 */ 967 switch(cmd->generic.opcode) { 968 case TWE_OP_GET_PARAM: 969 case TWE_OP_SET_PARAM: 970 cmd->generic.sgl_offset = 2; 971 twe_fillin_sgl(&cmd->param.sgl[0], segs, nsegments, TWE_MAX_SGL_LENGTH); 972 break; 973 case TWE_OP_READ: 974 case TWE_OP_WRITE: 975 cmd->generic.sgl_offset = 3; 976 twe_fillin_sgl(&cmd->io.sgl[0], segs, nsegments, TWE_MAX_SGL_LENGTH); 977 break; 978 case TWE_OP_ATA_PASSTHROUGH: 979 cmd->generic.sgl_offset = 5; 980 twe_fillin_sgl(&cmd->ata.sgl[0], segs, nsegments, TWE_MAX_ATA_SGL_LENGTH); 981 break; 982 default: 983 /* 984 * Fall back to what the linux driver does. 985 * Do this because the API may send an opcode 986 * the driver knows nothing about and this will 987 * at least stop PCIABRT's from hosing us. 988 */ 989 switch (cmd->generic.sgl_offset) { 990 case 2: 991 twe_fillin_sgl(&cmd->param.sgl[0], segs, nsegments, TWE_MAX_SGL_LENGTH); 992 break; 993 case 3: 994 twe_fillin_sgl(&cmd->io.sgl[0], segs, nsegments, TWE_MAX_SGL_LENGTH); 995 break; 996 case 5: 997 twe_fillin_sgl(&cmd->ata.sgl[0], segs, nsegments, TWE_MAX_ATA_SGL_LENGTH); 998 break; 999 } 1000 } 1001 1002 if (tr->tr_flags & TWE_CMD_DATAIN) { 1003 if (tr->tr_flags & TWE_CMD_IMMEDIATE) { 1004 bus_dmamap_sync(sc->twe_immediate_dmat, sc->twe_immediate_map, 1005 BUS_DMASYNC_PREREAD); 1006 } else { 1007 bus_dmamap_sync(sc->twe_buffer_dmat, tr->tr_dmamap, 1008 BUS_DMASYNC_PREREAD); 1009 } 1010 } 1011 1012 if (tr->tr_flags & TWE_CMD_DATAOUT) { 1013 /* 1014 * if we're using an alignment buffer, and we're writing data 1015 * copy the real data out 1016 */ 1017 if (tr->tr_flags & TWE_CMD_ALIGNBUF) 1018 bcopy(tr->tr_realdata, tr->tr_data, tr->tr_length); 1019 1020 if (tr->tr_flags & TWE_CMD_IMMEDIATE) { 1021 bus_dmamap_sync(sc->twe_immediate_dmat, sc->twe_immediate_map, 1022 BUS_DMASYNC_PREWRITE); 1023 } else { 1024 bus_dmamap_sync(sc->twe_buffer_dmat, tr->tr_dmamap, 1025 BUS_DMASYNC_PREWRITE); 1026 } 1027 } 1028 1029 if (twe_start(tr) == EBUSY) { 1030 tr->tr_sc->twe_state |= TWE_STATE_CTLR_BUSY; 1031 twe_requeue_ready(tr); 1032 } 1033} 1034 1035static void 1036twe_setup_request_dmamap(void *arg, bus_dma_segment_t *segs, int nsegments, int error) 1037{ 1038 struct twe_softc *sc = (struct twe_softc *)arg; 1039 1040 debug_called(4); 1041 1042 /* command can't cross a page boundary */ 1043 sc->twe_cmdphys = segs[0].ds_addr; 1044} 1045 1046int 1047twe_map_request(struct twe_request *tr) 1048{ 1049 struct twe_softc *sc = tr->tr_sc; 1050 int error = 0; 1051 1052 debug_called(4); 1053 1054 if (!dumping) 1055 TWE_IO_ASSERT_LOCKED(sc); 1056 if (sc->twe_state & (TWE_STATE_CTLR_BUSY | TWE_STATE_FRZN)) { 1057 twe_requeue_ready(tr); 1058 return (EBUSY); 1059 } 1060 1061 bus_dmamap_sync(sc->twe_cmd_dmat, sc->twe_cmdmap, BUS_DMASYNC_PREWRITE); 1062 1063 /* 1064 * If the command involves data, map that too. 1065 */ 1066 if (tr->tr_data != NULL && ((tr->tr_flags & TWE_CMD_MAPPED) == 0)) { 1067 1068 /* 1069 * Data must be 64-byte aligned; allocate a fixup buffer if it's not. 1070 */ 1071 if (((vm_offset_t)tr->tr_data % TWE_ALIGNMENT) != 0) { 1072 tr->tr_realdata = tr->tr_data; /* save pointer to 'real' data */ 1073 tr->tr_flags |= TWE_CMD_ALIGNBUF; 1074 tr->tr_data = malloc(tr->tr_length, TWE_MALLOC_CLASS, M_NOWAIT); 1075 if (tr->tr_data == NULL) { 1076 twe_printf(sc, "%s: malloc failed\n", __func__); 1077 tr->tr_data = tr->tr_realdata; /* restore original data pointer */ 1078 return(ENOMEM); 1079 } 1080 } 1081 1082 /* 1083 * Map the data buffer into bus space and build the s/g list. 1084 */ 1085 if (tr->tr_flags & TWE_CMD_IMMEDIATE) { 1086 error = bus_dmamap_load(sc->twe_immediate_dmat, sc->twe_immediate_map, sc->twe_immediate, 1087 tr->tr_length, twe_setup_data_dmamap, tr, BUS_DMA_NOWAIT); 1088 } else { 1089 error = bus_dmamap_load(sc->twe_buffer_dmat, tr->tr_dmamap, tr->tr_data, tr->tr_length, 1090 twe_setup_data_dmamap, tr, 0); 1091 } 1092 if (error == EINPROGRESS) { 1093 tr->tr_flags |= TWE_CMD_IN_PROGRESS; 1094 sc->twe_state |= TWE_STATE_FRZN; 1095 error = 0; 1096 } 1097 } else 1098 if ((error = twe_start(tr)) == EBUSY) { 1099 sc->twe_state |= TWE_STATE_CTLR_BUSY; 1100 twe_requeue_ready(tr); 1101 } 1102 1103 return(error); 1104} 1105 1106void 1107twe_unmap_request(struct twe_request *tr) 1108{ 1109 struct twe_softc *sc = tr->tr_sc; 1110 1111 debug_called(4); 1112 1113 if (!dumping) 1114 TWE_IO_ASSERT_LOCKED(sc); 1115 bus_dmamap_sync(sc->twe_cmd_dmat, sc->twe_cmdmap, BUS_DMASYNC_POSTWRITE); 1116 1117 /* 1118 * If the command involved data, unmap that too. 1119 */ 1120 if (tr->tr_data != NULL) { 1121 if (tr->tr_flags & TWE_CMD_DATAIN) { 1122 if (tr->tr_flags & TWE_CMD_IMMEDIATE) { 1123 bus_dmamap_sync(sc->twe_immediate_dmat, sc->twe_immediate_map, 1124 BUS_DMASYNC_POSTREAD); 1125 } else { 1126 bus_dmamap_sync(sc->twe_buffer_dmat, tr->tr_dmamap, 1127 BUS_DMASYNC_POSTREAD); 1128 } 1129 1130 /* if we're using an alignment buffer, and we're reading data, copy the real data in */ 1131 if (tr->tr_flags & TWE_CMD_ALIGNBUF) 1132 bcopy(tr->tr_data, tr->tr_realdata, tr->tr_length); 1133 } 1134 if (tr->tr_flags & TWE_CMD_DATAOUT) { 1135 if (tr->tr_flags & TWE_CMD_IMMEDIATE) { 1136 bus_dmamap_sync(sc->twe_immediate_dmat, sc->twe_immediate_map, 1137 BUS_DMASYNC_POSTWRITE); 1138 } else { 1139 bus_dmamap_sync(sc->twe_buffer_dmat, tr->tr_dmamap, 1140 BUS_DMASYNC_POSTWRITE); 1141 } 1142 } 1143 1144 if (tr->tr_flags & TWE_CMD_IMMEDIATE) { 1145 bus_dmamap_unload(sc->twe_immediate_dmat, sc->twe_immediate_map); 1146 } else { 1147 bus_dmamap_unload(sc->twe_buffer_dmat, tr->tr_dmamap); 1148 } 1149 } 1150 1151 /* free alignment buffer if it was used */ 1152 if (tr->tr_flags & TWE_CMD_ALIGNBUF) { 1153 free(tr->tr_data, TWE_MALLOC_CLASS); 1154 tr->tr_data = tr->tr_realdata; /* restore 'real' data pointer */ 1155 } 1156} 1157 1158#ifdef TWE_DEBUG 1159void twe_report(void); 1160/******************************************************************************** 1161 * Print current controller status, call from DDB. 1162 */ 1163void 1164twe_report(void) 1165{ 1166 struct twe_softc *sc; 1167 int i; 1168 1169 for (i = 0; (sc = devclass_get_softc(twe_devclass, i)) != NULL; i++) 1170 twe_print_controller(sc); 1171 printf("twed: total bio count in %u out %u\n", twed_bio_in, twed_bio_out); 1172} 1173#endif 1174