28 */ 29 30/* 31 * Driver for the AMI MegaRaid family of controllers. 32 */ 33 34#include <sys/param.h> 35#include <sys/systm.h> 36#include <sys/malloc.h> 37#include <sys/kernel.h> 38 39#include <dev/amr/amr_compat.h> 40#include <sys/bus.h> 41#include <sys/conf.h> 42#include <sys/devicestat.h> 43#include <sys/disk.h> 44#include <sys/stat.h> 45 46#include <machine/bus_memio.h> 47#include <machine/bus_pio.h> 48#include <machine/bus.h> 49#include <machine/resource.h> 50#include <machine/clock.h> 51#include <sys/rman.h> 52 53#include <pci/pcireg.h> 54#include <pci/pcivar.h> 55 56#include <dev/amr/amrio.h> 57#include <dev/amr/amrreg.h> 58#include <dev/amr/amrvar.h> 59#define AMR_DEFINE_TABLES 60#include <dev/amr/amr_tables.h> 61 62#define AMR_CDEV_MAJOR 132 63 64static d_open_t amr_open; 65static d_close_t amr_close; 66static d_ioctl_t amr_ioctl; 67 68static struct cdevsw amr_cdevsw = { 69 /* open */ amr_open, 70 /* close */ amr_close, 71 /* read */ noread, 72 /* write */ nowrite, 73 /* ioctl */ amr_ioctl, 74 /* poll */ nopoll, 75 /* mmap */ nommap, 76 /* strategy */ nostrategy, 77 /* name */ "amr", 78 /* maj */ AMR_CDEV_MAJOR, 79 /* dump */ nodump, 80 /* psize */ nopsize, 81 /* flags */ 0, 82 /* bmaj */ 254 /* XXX magic no-bdev */ 83}; 84 85/* 86 * Initialisation, bus interface. 87 */ 88static void amr_startup(void *arg); 89 90/* 91 * Command wrappers 92 */ 93static int amr_query_controller(struct amr_softc *sc); 94static void *amr_enquiry(struct amr_softc *sc, size_t bufsize, 95 u_int8_t cmd, u_int8_t cmdsub, u_int8_t cmdqual); 96static void amr_completeio(struct amr_command *ac); 97 98/* 99 * Command buffer allocation. 100 */ 101static void amr_alloccmd_cluster(struct amr_softc *sc); 102static void amr_freecmd_cluster(struct amr_command_cluster *acc); 103 104/* 105 * Command processing. 106 */ 107static int amr_bio_command(struct amr_softc *sc, struct amr_command **acp); 108static int amr_wait_command(struct amr_command *ac); 109static int amr_poll_command(struct amr_command *ac); 110static int amr_getslot(struct amr_command *ac); 111static void amr_mapcmd(struct amr_command *ac); 112static void amr_unmapcmd(struct amr_command *ac); 113static int amr_start(struct amr_command *ac); 114static void amr_complete(void *context, int pending); 115 116/* 117 * Status monitoring 118 */ 119static void amr_periodic(void *data); 120 121/* 122 * Interface-specific shims 123 */ 124static int amr_quartz_submit_command(struct amr_softc *sc); 125static int amr_quartz_get_work(struct amr_softc *sc, struct amr_mailbox *mbsave); 126 127static int amr_std_submit_command(struct amr_softc *sc); 128static int amr_std_get_work(struct amr_softc *sc, struct amr_mailbox *mbsave); 129static void amr_std_attach_mailbox(struct amr_softc *sc); 130 131#ifdef AMR_BOARD_INIT 132static int amr_quartz_init(struct amr_softc *sc); 133static int amr_std_init(struct amr_softc *sc); 134#endif 135 136/* 137 * Debugging 138 */ 139static void amr_describe_controller(struct amr_softc *sc); 140#ifdef AMR_DEBUG 141static void amr_printcommand(struct amr_command *ac); 142#endif 143 144/******************************************************************************** 145 ******************************************************************************** 146 Inline Glue 147 ******************************************************************************** 148 ********************************************************************************/ 149 150/******************************************************************************** 151 ******************************************************************************** 152 Public Interfaces 153 ******************************************************************************** 154 ********************************************************************************/ 155 156/******************************************************************************** 157 * Initialise the controller and softc. 158 */ 159int 160amr_attach(struct amr_softc *sc) 161{ 162 163 debug_called(1); 164 165 /* 166 * Initialise per-controller queues. 167 */ 168 TAILQ_INIT(&sc->amr_completed); 169 TAILQ_INIT(&sc->amr_freecmds); 170 TAILQ_INIT(&sc->amr_cmd_clusters); 171 TAILQ_INIT(&sc->amr_ready); 172 bioq_init(&sc->amr_bioq); 173 174#if __FreeBSD_version >= 500005 175 /* 176 * Initialise command-completion task. 177 */ 178 TASK_INIT(&sc->amr_task_complete, 0, amr_complete, sc); 179#endif 180 181 debug(2, "queue init done"); 182 183 /* 184 * Configure for this controller type. 185 */ 186 if (AMR_IS_QUARTZ(sc)) { 187 sc->amr_submit_command = amr_quartz_submit_command; 188 sc->amr_get_work = amr_quartz_get_work; 189 } else { 190 sc->amr_submit_command = amr_std_submit_command; 191 sc->amr_get_work = amr_std_get_work; 192 amr_std_attach_mailbox(sc);; 193 } 194 195#ifdef AMR_BOARD_INIT 196 if ((AMR_IS_QUARTZ(sc) ? amr_quartz_init(sc) : amr_std_init(sc)))) 197 return(ENXIO); 198#endif 199 200 /* 201 * Quiz controller for features and limits. 202 */ 203 if (amr_query_controller(sc)) 204 return(ENXIO); 205 206 debug(2, "controller query complete"); 207 208#ifdef AMR_SCSI_PASSTHROUGH 209 /* 210 * Attach our 'real' SCSI channels to CAM. 211 */ 212 if (amr_cam_attach(sc)) 213 return(ENXIO); 214 debug(2, "CAM attach done"); 215#endif 216 217 /* 218 * Create the control device. 219 */ 220 sc->amr_dev_t = make_dev(&amr_cdevsw, device_get_unit(sc->amr_dev), UID_ROOT, GID_OPERATOR, 221 S_IRUSR | S_IWUSR, "amr%d", device_get_unit(sc->amr_dev)); 222 sc->amr_dev_t->si_drv1 = sc; 223 224 /* 225 * Schedule ourselves to bring the controller up once interrupts are 226 * available. 227 */ 228 bzero(&sc->amr_ich, sizeof(struct intr_config_hook)); 229 sc->amr_ich.ich_func = amr_startup; 230 sc->amr_ich.ich_arg = sc; 231 if (config_intrhook_establish(&sc->amr_ich) != 0) { 232 device_printf(sc->amr_dev, "can't establish configuration hook\n"); 233 return(ENOMEM); 234 } 235 236 /* 237 * Print a little information about the controller. 238 */ 239 amr_describe_controller(sc); 240 241 debug(2, "attach complete"); 242 return(0); 243} 244 245/******************************************************************************** 246 * Locate disk resources and attach children to them. 247 */ 248static void 249amr_startup(void *arg) 250{ 251 struct amr_softc *sc = (struct amr_softc *)arg; 252 struct amr_logdrive *dr; 253 int i, error; 254 255 debug_called(1); 256 257 /* pull ourselves off the intrhook chain */ 258 config_intrhook_disestablish(&sc->amr_ich); 259 260 /* get up-to-date drive information */ 261 if (amr_query_controller(sc)) { 262 device_printf(sc->amr_dev, "can't scan controller for drives\n"); 263 return; 264 } 265 266 /* iterate over available drives */ 267 for (i = 0, dr = &sc->amr_drive[0]; (i < AMR_MAXLD) && (dr->al_size != 0xffffffff); i++, dr++) { 268 /* are we already attached to this drive? */ 269 if (dr->al_disk == 0) { 270 /* generate geometry information */ 271 if (dr->al_size > 0x200000) { /* extended translation? */ 272 dr->al_heads = 255; 273 dr->al_sectors = 63; 274 } else { 275 dr->al_heads = 64; 276 dr->al_sectors = 32; 277 } 278 dr->al_cylinders = dr->al_size / (dr->al_heads * dr->al_sectors); 279 280 dr->al_disk = device_add_child(sc->amr_dev, NULL, -1); 281 if (dr->al_disk == 0) 282 device_printf(sc->amr_dev, "device_add_child failed\n"); 283 device_set_ivars(dr->al_disk, dr); 284 } 285 } 286 287 if ((error = bus_generic_attach(sc->amr_dev)) != 0) 288 device_printf(sc->amr_dev, "bus_generic_attach returned %d\n", error); 289 290 /* mark controller back up */ 291 sc->amr_state &= ~AMR_STATE_SHUTDOWN; 292 293 /* interrupts will be enabled before we do anything more */ 294 sc->amr_state |= AMR_STATE_INTEN; 295 296 /* 297 * Start the timeout routine. 298 */ 299/* sc->amr_timeout = timeout(amr_periodic, sc, hz);*/ 300 301 return; 302} 303 304/******************************************************************************* 305 * Free resources associated with a controller instance 306 */ 307void 308amr_free(struct amr_softc *sc) 309{ 310 struct amr_command_cluster *acc; 311 312#ifdef AMR_SCSI_PASSTHROUGH 313 /* detach from CAM */ 314 amr_cam_detach(sc); 315#endif 316 317 /* cancel status timeout */ 318 untimeout(amr_periodic, sc, sc->amr_timeout); 319 320 /* throw away any command buffers */ 321 while ((acc = TAILQ_FIRST(&sc->amr_cmd_clusters)) != NULL) { 322 TAILQ_REMOVE(&sc->amr_cmd_clusters, acc, acc_link); 323 amr_freecmd_cluster(acc); 324 } 325} 326 327/******************************************************************************* 328 * Receive a bio structure from a child device and queue it on a particular 329 * disk resource, then poke the disk resource to start as much work as it can. 330 */ 331int 332amr_submit_bio(struct amr_softc *sc, struct bio *bio) 333{ 334 debug_called(2); 335 336 amr_enqueue_bio(sc, bio); 337 amr_startio(sc); 338 return(0); 339} 340 341/******************************************************************************** 342 * Accept an open operation on the control device. 343 */ 344int 345amr_open(dev_t dev, int flags, int fmt, struct proc *p) 346{ 347 int unit = minor(dev); 348 struct amr_softc *sc = devclass_get_softc(amr_devclass, unit); 349 350 debug_called(1); 351 352 sc->amr_state |= AMR_STATE_OPEN; 353 return(0); 354} 355 356/******************************************************************************** 357 * Accept the last close on the control device. 358 */ 359int 360amr_close(dev_t dev, int flags, int fmt, struct proc *p) 361{ 362 int unit = minor(dev); 363 struct amr_softc *sc = devclass_get_softc(amr_devclass, unit); 364 365 debug_called(1); 366 367 sc->amr_state &= ~AMR_STATE_OPEN; 368 return (0); 369} 370 371/******************************************************************************** 372 * Handle controller-specific control operations. 373 */ 374int 375amr_ioctl(dev_t dev, u_long cmd, caddr_t addr, int32_t flag, struct proc *p) 376{ 377 struct amr_softc *sc = (struct amr_softc *)dev->si_drv1; 378 int *arg = (int *)addr; 379 struct amr_user_ioctl *au = (struct amr_user_ioctl *)addr; 380 struct amr_command *ac; 381 struct amr_mailbox_ioctl *mbi; 382 struct amr_passthrough *ap; 383 void *dp; 384 int error; 385 386 debug_called(1); 387 388 error = 0; 389 dp = NULL; 390 ap = NULL; 391 ac = NULL; 392 switch(cmd) { 393 394 case AMR_IO_VERSION: 395 debug(1, "AMR_IO_VERSION"); 396 *arg = AMR_IO_VERSION_NUMBER; 397 break; 398 399 case AMR_IO_COMMAND: 400 debug(1, "AMR_IO_COMMAND"); 401 /* handle inbound data buffer */ 402 if (au->au_length != 0) { 403 if ((dp = malloc(au->au_length, M_DEVBUF, M_WAITOK)) == NULL) { 404 error = ENOMEM; 405 break; 406 } 407 if ((error = copyin(au->au_buffer, dp, au->au_length)) != 0) 408 break; 409 } 410 411 if ((ac = amr_alloccmd(sc)) == NULL) { 412 error = ENOMEM; 413 break; 414 } 415 416 /* handle SCSI passthrough command */ 417 if (au->au_cmd[0] == AMR_CMD_PASS) { 418 if ((ap = malloc(sizeof(*ap), M_DEVBUF, M_WAITOK)) == NULL) { 419 error = ENOMEM; 420 break; 421 } 422 bzero(ap, sizeof(*ap)); 423 424 /* copy cdb */ 425 ap->ap_cdb_length = au->au_cmd[2]; 426 bcopy(&au->au_cmd[3], &ap->ap_cdb[0], ap->ap_cdb_length); 427 428 /* build passthrough */ 429 ap->ap_timeout = au->au_cmd[ap->ap_cdb_length + 3] & 0x07; 430 ap->ap_ars = (au->au_cmd[ap->ap_cdb_length + 3] & 0x08) ? 1 : 0; 431 ap->ap_islogical = (au->au_cmd[ap->ap_cdb_length + 3] & 0x80) ? 1 : 0; 432 ap->ap_logical_drive_no = au->au_cmd[ap->ap_cdb_length + 4]; 433 ap->ap_channel = au->au_cmd[ap->ap_cdb_length + 5]; 434 ap->ap_scsi_id = au->au_cmd[ap->ap_cdb_length + 6]; 435 ap->ap_request_sense_length = 14; 436 /* XXX what about the request-sense area? does the caller want it? */ 437 438 /* build command */ 439 ac->ac_data = ap; 440 ac->ac_length = sizeof(*ap); 441 ac->ac_flags |= AMR_CMD_DATAOUT; 442 ac->ac_ccb_data = dp; 443 ac->ac_ccb_length = au->au_length; 444 if (au->au_direction & AMR_IO_READ) 445 ac->ac_flags |= AMR_CMD_CCB_DATAIN; 446 if (au->au_direction & AMR_IO_WRITE) 447 ac->ac_flags |= AMR_CMD_CCB_DATAOUT; 448 449 ac->ac_mailbox.mb_command = AMR_CMD_PASS; 450 451 } else { 452 /* direct command to controller */ 453 mbi = (struct amr_mailbox_ioctl *)&ac->ac_mailbox; 454 455 /* copy pertinent mailbox items */ 456 mbi->mb_command = au->au_cmd[0]; 457 mbi->mb_channel = au->au_cmd[1]; 458 mbi->mb_param = au->au_cmd[2]; 459 mbi->mb_pad[0] = au->au_cmd[3]; 460 mbi->mb_drive = au->au_cmd[4]; 461 462 /* build the command */ 463 ac->ac_data = dp; 464 ac->ac_length = au->au_length; 465 if (au->au_direction & AMR_IO_READ) 466 ac->ac_flags |= AMR_CMD_DATAIN; 467 if (au->au_direction & AMR_IO_WRITE) 468 ac->ac_flags |= AMR_CMD_DATAOUT; 469 } 470 471 /* run the command */ 472 if ((error = amr_wait_command(ac)) != 0) 473 break; 474 475 /* copy out data and set status */ 476 if (au->au_length != 0) 477 error = copyout(dp, au->au_buffer, au->au_length); 478 au->au_status = ac->ac_status; 479 break; 480 481 default: 482 debug(1, "unknown ioctl 0x%lx", cmd); 483 error = ENOIOCTL; 484 break; 485 } 486 487 if (dp != NULL) 488 free(dp, M_DEVBUF); 489 if (ap != NULL) 490 free(ap, M_DEVBUF); 491 if (ac != NULL) 492 amr_releasecmd(ac); 493 return(error); 494} 495 496/******************************************************************************** 497 ******************************************************************************** 498 Status Monitoring 499 ******************************************************************************** 500 ********************************************************************************/ 501 502/******************************************************************************** 503 * Perform a periodic check of the controller status 504 */ 505static void 506amr_periodic(void *data) 507{ 508 struct amr_softc *sc = (struct amr_softc *)data; 509 510 debug_called(2); 511 512 /* XXX perform periodic status checks here */ 513 514 /* compensate for missed interrupts */ 515 amr_done(sc); 516 517 /* reschedule */ 518 sc->amr_timeout = timeout(amr_periodic, sc, hz); 519} 520 521/******************************************************************************** 522 ******************************************************************************** 523 Command Wrappers 524 ******************************************************************************** 525 ********************************************************************************/ 526 527/******************************************************************************** 528 * Interrogate the controller for the operational parameters we require. 529 */ 530static int 531amr_query_controller(struct amr_softc *sc) 532{ 533 struct amr_enquiry3 *aex; 534 struct amr_prodinfo *ap; 535 struct amr_enquiry *ae; 536 int ldrv; 537 538 /* 539 * If we haven't found the real limit yet, let us have a couple of commands in 540 * order to be able to probe. 541 */ 542 if (sc->amr_maxio == 0) 543 sc->amr_maxio = 2; 544 545 /* 546 * Try to issue an ENQUIRY3 command 547 */ 548 if ((aex = amr_enquiry(sc, 2048, AMR_CMD_CONFIG, AMR_CONFIG_ENQ3, 549 AMR_CONFIG_ENQ3_SOLICITED_FULL)) != NULL) { 550 551 /* 552 * Fetch current state of logical drives. 553 */ 554 for (ldrv = 0; ldrv < aex->ae_numldrives; ldrv++) { 555 sc->amr_drive[ldrv].al_size = aex->ae_drivesize[ldrv]; 556 sc->amr_drive[ldrv].al_state = aex->ae_drivestate[ldrv]; 557 sc->amr_drive[ldrv].al_properties = aex->ae_driveprop[ldrv]; 558 debug(2, " drive %d: %d state %x properties %x\n", ldrv, sc->amr_drive[ldrv].al_size, 559 sc->amr_drive[ldrv].al_state, sc->amr_drive[ldrv].al_properties); 560 } 561 free(aex, M_DEVBUF); 562 563 /* 564 * Get product info for channel count. 565 */ 566 if ((ap = amr_enquiry(sc, 2048, AMR_CMD_CONFIG, AMR_CONFIG_PRODUCT_INFO, 0)) == NULL) { 567 device_printf(sc->amr_dev, "can't obtain product data from controller\n"); 568 return(1); 569 } 570 sc->amr_maxdrives = 40; 571 sc->amr_maxchan = ap->ap_nschan; 572 sc->amr_maxio = ap->ap_maxio; 573 sc->amr_type |= AMR_TYPE_40LD; 574 free(ap, M_DEVBUF); 575 576 } else { 577 578 /* failed, try the 8LD ENQUIRY commands */ 579 if ((ae = (struct amr_enquiry *)amr_enquiry(sc, 2048, AMR_CMD_EXT_ENQUIRY2, 0, 0)) == NULL) { 580 if ((ae = (struct amr_enquiry *)amr_enquiry(sc, 2048, AMR_CMD_ENQUIRY, 0, 0)) == NULL) { 581 device_printf(sc->amr_dev, "can't obtain configuration data from controller\n"); 582 return(1); 583 } 584 ae->ae_signature = 0; 585 } 586 587 /* 588 * Fetch current state of logical drives. 589 */ 590 for (ldrv = 0; ldrv < ae->ae_ldrv.al_numdrives; ldrv++) { 591 sc->amr_drive[ldrv].al_size = ae->ae_ldrv.al_size[ldrv]; 592 sc->amr_drive[ldrv].al_state = ae->ae_ldrv.al_state[ldrv]; 593 sc->amr_drive[ldrv].al_properties = ae->ae_ldrv.al_properties[ldrv]; 594 debug(2, " drive %d: %d state %x properties %x\n", ldrv, sc->amr_drive[ldrv].al_size, 595 sc->amr_drive[ldrv].al_state, sc->amr_drive[ldrv].al_properties); 596 } 597 598 sc->amr_maxdrives = 8; 599 sc->amr_maxchan = ae->ae_adapter.aa_channels; 600 sc->amr_maxio = ae->ae_adapter.aa_maxio; 601 free(ae, M_DEVBUF); 602 } 603 604 /* 605 * Mark remaining drives as unused. 606 */ 607 for (; ldrv < AMR_MAXLD; ldrv++) 608 sc->amr_drive[ldrv].al_size = 0xffffffff; 609 610 /* 611 * Cap the maximum number of outstanding I/Os. AMI's Linux driver doesn't trust 612 * the controller's reported value, and lockups have been seen when we do. 613 */ 614 sc->amr_maxio = imin(sc->amr_maxio, AMR_LIMITCMD); 615 616 return(0); 617} 618 619/******************************************************************************** 620 * Run a generic enquiry-style command. 621 */ 622static void * 623amr_enquiry(struct amr_softc *sc, size_t bufsize, u_int8_t cmd, u_int8_t cmdsub, u_int8_t cmdqual) 624{ 625 struct amr_command *ac; 626 void *result; 627 u_int8_t *mbox; 628 int error; 629 630 debug_called(1); 631 632 error = 1; 633 result = NULL; 634 635 /* get ourselves a command buffer */ 636 if ((ac = amr_alloccmd(sc)) == NULL) 637 goto out; 638 /* allocate the response structure */ 639 if ((result = malloc(bufsize, M_DEVBUF, M_NOWAIT)) == NULL) 640 goto out; 641 /* set command flags */ 642 ac->ac_flags |= AMR_CMD_PRIORITY | AMR_CMD_DATAOUT; 643 644 /* point the command at our data */ 645 ac->ac_data = result; 646 ac->ac_length = bufsize; 647 648 /* build the command proper */ 649 mbox = (u_int8_t *)&ac->ac_mailbox; /* XXX want a real structure for this? */ 650 mbox[0] = cmd; 651 mbox[2] = cmdsub; 652 mbox[3] = cmdqual; 653 654 /* can't assume that interrupts are going to work here, so play it safe */ 655 if (amr_poll_command(ac)) 656 goto out; 657 error = ac->ac_status; 658 659 out: 660 if (ac != NULL) 661 amr_releasecmd(ac); 662 if ((error != 0) && (result != NULL)) { 663 free(result, M_DEVBUF); 664 result = NULL; 665 } 666 return(result); 667} 668 669/******************************************************************************** 670 * Flush the controller's internal cache, return status. 671 */ 672int 673amr_flush(struct amr_softc *sc) 674{ 675 struct amr_command *ac; 676 int error; 677 678 /* get ourselves a command buffer */ 679 error = 1; 680 if ((ac = amr_alloccmd(sc)) == NULL) 681 goto out; 682 /* set command flags */ 683 ac->ac_flags |= AMR_CMD_PRIORITY | AMR_CMD_DATAOUT; 684 685 /* build the command proper */ 686 ac->ac_mailbox.mb_command = AMR_CMD_FLUSH; 687 688 /* we have to poll, as the system may be going down or otherwise damaged */ 689 if (amr_poll_command(ac)) 690 goto out; 691 error = ac->ac_status; 692 693 out: 694 if (ac != NULL) 695 amr_releasecmd(ac); 696 return(error); 697} 698 699/******************************************************************************** 700 * Try to find I/O work for the controller from one or more of the work queues. 701 * 702 * We make the assumption that if the controller is not ready to take a command 703 * at some given time, it will generate an interrupt at some later time when 704 * it is. 705 */ 706void 707amr_startio(struct amr_softc *sc) 708{ 709 struct amr_command *ac; 710 711 /* spin until something prevents us from doing any work */ 712 for (;;) { 713 714 /* try to get a ready command */ 715 ac = amr_dequeue_ready(sc); 716 717 /* if that failed, build a command from a bio */ 718 if (ac == NULL) 719 (void)amr_bio_command(sc, &ac); 720 721#ifdef AMR_SCSI_PASSTHROUGH 722 /* if that failed, build a command from a ccb */ 723 if (ac == NULL) 724 (void)amr_cam_command(sc, &ac); 725#endif 726 727 /* if we don't have anything to do, give up */ 728 if (ac == NULL) 729 break; 730 731 /* try to give the command to the controller; if this fails save it for later and give up */ 732 if (amr_start(ac)) { 733 debug(2, "controller busy, command deferred"); 734 amr_requeue_ready(ac); /* XXX schedule retry very soon? */ 735 break; 736 } 737 } 738} 739 740/******************************************************************************** 741 * Handle completion of an I/O command. 742 */ 743static void 744amr_completeio(struct amr_command *ac) 745{ 746 struct amr_softc *sc = ac->ac_sc; 747 748 if (ac->ac_status != AMR_STATUS_SUCCESS) { /* could be more verbose here? */ 749 ac->ac_bio->bio_error = EIO; 750 ac->ac_bio->bio_flags |= BIO_ERROR; 751 752 device_printf(sc->amr_dev, "I/O error - 0x%x\n", ac->ac_status); 753/* amr_printcommand(ac);*/ 754 } 755 amrd_intr(ac->ac_bio); 756 amr_releasecmd(ac); 757} 758 759/******************************************************************************** 760 ******************************************************************************** 761 Command Processing 762 ******************************************************************************** 763 ********************************************************************************/ 764 765/******************************************************************************** 766 * Convert a bio off the top of the bio queue into a command. 767 */ 768static int 769amr_bio_command(struct amr_softc *sc, struct amr_command **acp) 770{ 771 struct amr_command *ac; 772 struct amrd_softc *amrd; 773 struct bio *bio; 774 int error; 775 int blkcount; 776 int driveno; 777 int cmd; 778 779 ac = NULL; 780 error = 0; 781 782 /* get a bio to work on */ 783 if ((bio = amr_dequeue_bio(sc)) == NULL) 784 goto out; 785 786 /* get a command */ 787 if ((ac = amr_alloccmd(sc)) == NULL) { 788 error = ENOMEM; 789 goto out; 790 } 791 792 /* connect the bio to the command */ 793 ac->ac_complete = amr_completeio; 794 ac->ac_bio = bio; 795 ac->ac_data = bio->bio_data; 796 ac->ac_length = bio->bio_bcount; 797 if (BIO_IS_READ(bio)) { 798 ac->ac_flags |= AMR_CMD_DATAIN; 799 cmd = AMR_CMD_LREAD; 800 } else { 801 ac->ac_flags |= AMR_CMD_DATAOUT; 802 cmd = AMR_CMD_LWRITE; 803 } 804 amrd = (struct amrd_softc *)bio->bio_dev->si_drv1; 805 driveno = amrd->amrd_drive - sc->amr_drive; 806 blkcount = (bio->bio_bcount + AMR_BLKSIZE - 1) / AMR_BLKSIZE; 807 808 ac->ac_mailbox.mb_command = cmd; 809 ac->ac_mailbox.mb_blkcount = blkcount; 810 ac->ac_mailbox.mb_lba = bio->bio_pblkno; 811 ac->ac_mailbox.mb_drive = driveno; 812 /* we fill in the s/g related data when the command is mapped */ 813 814 if ((bio->bio_pblkno + blkcount) > sc->amr_drive[driveno].al_size) 815 device_printf(sc->amr_dev, "I/O beyond end of unit (%u,%d > %u)\n", 816 bio->bio_pblkno, blkcount, sc->amr_drive[driveno].al_size); 817 818out: 819 if (error != 0) { 820 if (ac != NULL) 821 amr_releasecmd(ac); 822 if (bio != NULL) /* this breaks ordering... */ 823 amr_enqueue_bio(sc, bio); 824 } 825 *acp = ac; 826 return(error); 827} 828 829/******************************************************************************** 830 * Take a command, submit it to the controller and sleep until it completes 831 * or fails. Interrupts must be enabled, returns nonzero on error. 832 */ 833static int 834amr_wait_command(struct amr_command *ac) 835{ 836 struct amr_softc *sc = ac->ac_sc; 837 int error, count; 838 839 debug_called(1); 840 841 ac->ac_complete = NULL; 842 ac->ac_flags |= AMR_CMD_SLEEP; 843 if ((error = amr_start(ac)) != 0) 844 return(error); 845 846 count = 0; 847 /* XXX better timeout? */ 848 while ((ac->ac_flags & AMR_CMD_BUSY) && (count < 30)) { 849 tsleep(ac, PRIBIO | PCATCH, "amrwcmd", hz); 850 } 851 852 if (ac->ac_status != 0) { 853 device_printf(sc->amr_dev, "I/O error - 0x%x\n", ac->ac_status); 854 return(EIO); 855 } 856 return(0); 857} 858 859/******************************************************************************** 860 * Take a command, submit it to the controller and busy-wait for it to return. 861 * Returns nonzero on error. Can be safely called with interrupts enabled. 862 */ 863static int 864amr_poll_command(struct amr_command *ac) 865{ 866 struct amr_softc *sc = ac->ac_sc; 867 int error, count; 868 869 debug_called(2); 870 871 ac->ac_complete = NULL; 872 if ((error = amr_start(ac)) != 0) 873 return(error); 874 875 count = 0; 876 do { 877 /* 878 * Poll for completion, although the interrupt handler may beat us to it. 879 * Note that the timeout here is somewhat arbitrary. 880 */ 881 amr_done(sc); 882 DELAY(1000); 883 } while ((ac->ac_flags & AMR_CMD_BUSY) && (count++ < 1000)); 884 if (!(ac->ac_flags & AMR_CMD_BUSY)) { 885 error = 0; 886 } else { 887 /* XXX the slot is now marked permanently busy */ 888 error = EIO; 889 device_printf(sc->amr_dev, "polled command timeout\n"); 890 } 891 return(error); 892} 893 894/******************************************************************************** 895 * Get a free command slot for a command if it doesn't already have one. 896 * 897 * May be safely called multiple times for a given command. 898 */ 899static int 900amr_getslot(struct amr_command *ac) 901{ 902 struct amr_softc *sc = ac->ac_sc; 903 int s, slot, limit, error; 904 905 debug_called(3); 906 907 /* if the command already has a slot, don't try to give it another one */ 908 if (ac->ac_slot != 0) 909 return(0); 910 911 /* enforce slot usage limit */ 912 limit = (ac->ac_flags & AMR_CMD_PRIORITY) ? sc->amr_maxio : sc->amr_maxio - 4; 913 if (sc->amr_busyslots > limit) 914 return(EBUSY); 915 916 /* 917 * Allocate a slot. XXX linear scan is slow 918 */ 919 error = EBUSY; 920 s = splbio(); 921 for (slot = 0; slot < sc->amr_maxio; slot++) { 922 if (sc->amr_busycmd[slot] == NULL) { 923 sc->amr_busycmd[slot] = ac; 924 sc->amr_busyslots++; 925 ac->ac_slot = slot; 926 error = 0; 927 break; 928 } 929 } 930 splx(s); 931 932 return(error); 933} 934 935/******************************************************************************** 936 * Map/unmap (ac)'s data in the controller's addressable space as required. 937 * 938 * These functions may be safely called multiple times on a given command. 939 */ 940static void 941amr_setup_dmamap(void *arg, bus_dma_segment_t *segs, int nsegments, int error) 942{ 943 struct amr_command *ac = (struct amr_command *)arg; 944 struct amr_softc *sc = ac->ac_sc; 945 struct amr_sgentry *sg; 946 int i; 947 948 debug_called(3); 949 950 /* get base address of s/g table */ 951 sg = sc->amr_sgtable + (ac->ac_slot * AMR_NSEG); 952 953 /* save data physical address */ 954 ac->ac_dataphys = segs[0].ds_addr; 955 956 /* decide whether we need to populate the s/g table */ 957 if (nsegments < 2) { 958 ac->ac_mailbox.mb_nsgelem = 0; 959 ac->ac_mailbox.mb_physaddr = ac->ac_dataphys; 960 } else { 961 ac->ac_mailbox.mb_nsgelem = nsegments; 962 ac->ac_mailbox.mb_physaddr = sc->amr_sgbusaddr + (ac->ac_slot * AMR_NSEG * sizeof(struct amr_sgentry)); 963 for (i = 0; i < nsegments; i++, sg++) { 964 sg->sg_addr = segs[i].ds_addr; 965 sg->sg_count = segs[i].ds_len; 966 } 967 } 968} 969 970static void 971amr_setup_ccbmap(void *arg, bus_dma_segment_t *segs, int nsegments, int error) 972{ 973 struct amr_command *ac = (struct amr_command *)arg; 974 struct amr_softc *sc = ac->ac_sc; 975 struct amr_sgentry *sg; 976 struct amr_passthrough *ap = (struct amr_passthrough *)ac->ac_data; 977 int i; 978 979 /* get base address of s/g table */ 980 sg = sc->amr_sgtable + (ac->ac_slot * AMR_NSEG); 981 982 /* save s/g table information in passthrough */ 983 ap->ap_no_sg_elements = nsegments; 984 ap->ap_data_transfer_address = sc->amr_sgbusaddr + (ac->ac_slot * AMR_NSEG * sizeof(struct amr_sgentry)); 985 986 /* save pointer to passthrough in command XXX is this already done above? */ 987 ac->ac_mailbox.mb_physaddr = ac->ac_dataphys; 988 989 debug(2, "slot %d %d segments at 0x%x, passthrough at 0x%x", ac->ac_slot, 990 ap->ap_no_sg_elements, ap->ap_data_transfer_address, ac->ac_dataphys); 991 992 /* populate s/g table (overwrites previous call which mapped the passthrough) */ 993 for (i = 0; i < nsegments; i++, sg++) { 994 sg->sg_addr = segs[i].ds_addr; 995 sg->sg_count = segs[i].ds_len; 996 debug(2, " %d: 0x%x/%d", i, sg->sg_addr, sg->sg_count); 997 } 998} 999 1000static void 1001amr_mapcmd(struct amr_command *ac) 1002{ 1003 struct amr_softc *sc = ac->ac_sc; 1004 1005 debug_called(2); 1006 1007 /* if the command involves data at all, and hasn't been mapped */ 1008 if (!(ac->ac_flags & AMR_CMD_MAPPED)) { 1009 1010 if (ac->ac_data != NULL) { 1011 /* map the data buffers into bus space and build the s/g list */ 1012 bus_dmamap_load(sc->amr_buffer_dmat, ac->ac_dmamap, ac->ac_data, ac->ac_length, 1013 amr_setup_dmamap, ac, 0); 1014 if (ac->ac_flags & AMR_CMD_DATAIN) 1015 bus_dmamap_sync(sc->amr_buffer_dmat, ac->ac_dmamap, BUS_DMASYNC_PREREAD); 1016 if (ac->ac_flags & AMR_CMD_DATAOUT) 1017 bus_dmamap_sync(sc->amr_buffer_dmat, ac->ac_dmamap, BUS_DMASYNC_PREWRITE); 1018 } 1019 1020 if (ac->ac_ccb_data != NULL) { 1021 bus_dmamap_load(sc->amr_buffer_dmat, ac->ac_ccb_dmamap, ac->ac_ccb_data, ac->ac_ccb_length, 1022 amr_setup_ccbmap, ac, 0); 1023 if (ac->ac_flags & AMR_CMD_CCB_DATAIN) 1024 bus_dmamap_sync(sc->amr_buffer_dmat, ac->ac_ccb_dmamap, BUS_DMASYNC_PREREAD); 1025 if (ac->ac_flags & AMR_CMD_CCB_DATAOUT) 1026 bus_dmamap_sync(sc->amr_buffer_dmat, ac->ac_ccb_dmamap, BUS_DMASYNC_PREWRITE); 1027 } 1028 ac->ac_flags |= AMR_CMD_MAPPED; 1029 } 1030} 1031 1032static void 1033amr_unmapcmd(struct amr_command *ac) 1034{ 1035 struct amr_softc *sc = ac->ac_sc; 1036 1037 debug_called(2); 1038 1039 /* if the command involved data at all and was mapped */ 1040 if (ac->ac_flags & AMR_CMD_MAPPED) { 1041 1042 if (ac->ac_data != NULL) { 1043 if (ac->ac_flags & AMR_CMD_DATAIN) 1044 bus_dmamap_sync(sc->amr_buffer_dmat, ac->ac_dmamap, BUS_DMASYNC_POSTREAD); 1045 if (ac->ac_flags & AMR_CMD_DATAOUT) 1046 bus_dmamap_sync(sc->amr_buffer_dmat, ac->ac_dmamap, BUS_DMASYNC_POSTWRITE); 1047 bus_dmamap_unload(sc->amr_buffer_dmat, ac->ac_dmamap); 1048 } 1049 1050 if (ac->ac_ccb_data != NULL) { 1051 if (ac->ac_flags & AMR_CMD_CCB_DATAIN) 1052 bus_dmamap_sync(sc->amr_buffer_dmat, ac->ac_ccb_dmamap, BUS_DMASYNC_POSTREAD); 1053 if (ac->ac_flags & AMR_CMD_CCB_DATAOUT) 1054 bus_dmamap_sync(sc->amr_buffer_dmat, ac->ac_ccb_dmamap, BUS_DMASYNC_POSTWRITE); 1055 bus_dmamap_unload(sc->amr_buffer_dmat, ac->ac_ccb_dmamap); 1056 } 1057 ac->ac_flags &= ~AMR_CMD_MAPPED; 1058 } 1059} 1060 1061/******************************************************************************** 1062 * Take a command and give it to the controller, returns 0 if successful, or 1063 * EBUSY if the command should be retried later. 1064 */ 1065static int 1066amr_start(struct amr_command *ac) 1067{ 1068 struct amr_softc *sc = ac->ac_sc; 1069 int done, s, i; 1070 1071 debug_called(2); 1072 1073 /* mark command as busy so that polling consumer can tell */ 1074 ac->ac_flags |= AMR_CMD_BUSY; 1075 1076 /* get a command slot (freed in amr_done) */ 1077 if (amr_getslot(ac)) 1078 return(EBUSY); 1079 1080 /* now we have a slot, we can map the command (unmapped in amr_complete) */ 1081 amr_mapcmd(ac); 1082 1083 /* mark the new mailbox we are going to copy in as busy */ 1084 ac->ac_mailbox.mb_busy = 1; 1085 1086 /* clear the poll/ack fields in the mailbox */ 1087 sc->amr_mailbox->mb_poll = 0; 1088 sc->amr_mailbox->mb_ack = 0; 1089 1090 /* 1091 * Save the slot number so that we can locate this command when complete. 1092 * Note that ident = 0 seems to be special, so we don't use it. 1093 */ 1094 ac->ac_mailbox.mb_ident = ac->ac_slot + 1; 1095 1096 /* 1097 * Spin waiting for the mailbox, give up after ~1 second. We expect the 1098 * controller to be able to handle our I/O. 1099 * 1100 * XXX perhaps we should wait for less time, and count on the deferred command 1101 * handling to deal with retries? 1102 */ 1103 debug(2, "wait for mailbox"); 1104 for (i = 10000, done = 0; (i > 0) && !done; i--) { 1105 s = splbio(); 1106 1107 /* is the mailbox free? */ 1108 if (sc->amr_mailbox->mb_busy == 0) { 1109 debug(2, "got mailbox"); 1110 sc->amr_mailbox64->mb64_segment = 0; 1111 bcopy(&ac->ac_mailbox, (void *)(uintptr_t)(volatile void *)sc->amr_mailbox, AMR_MBOX_CMDSIZE); 1112 done = 1; 1113 1114 /* not free, spin waiting */ 1115 } else { 1116 debug(3, "busy flag %x\n", sc->amr_mailbox->mb_busy); 1117 /* this is somewhat ugly */ 1118 DELAY(100); 1119 } 1120 splx(s); /* drop spl to allow completion interrupts */ 1121 } 1122 1123 /* 1124 * Now give the command to the controller 1125 */ 1126 if (done) { 1127 if (sc->amr_submit_command(sc)) { 1128 /* the controller wasn't ready to take the command, forget that we tried to post it */ 1129 sc->amr_mailbox->mb_busy = 0; 1130 return(EBUSY); 1131 } 1132 debug(2, "posted command"); 1133 return(0); 1134 } 1135 1136 /* 1137 * The controller wouldn't take the command. Return the command as busy 1138 * so that it is retried later. 1139 */ 1140 return(EBUSY); 1141} 1142 1143/******************************************************************************** 1144 * Extract one or more completed commands from the controller (sc) 1145 * 1146 * Returns nonzero if any commands on the work queue were marked as completed. 1147 */ 1148int 1149amr_done(struct amr_softc *sc) 1150{ 1151 struct amr_command *ac; 1152 struct amr_mailbox mbox; 1153 int i, idx, result; 1154 1155 debug_called(2); 1156 1157 /* See if there's anything for us to do */ 1158 result = 0; 1159 1160 /* loop collecting completed commands */ 1161 for (;;) { 1162 /* poll for a completed command's identifier and status */ 1163 if (sc->amr_get_work(sc, &mbox)) { 1164 result = 1; 1165 1166 /* iterate over completed commands in this result */ 1167 for (i = 0; i < mbox.mb_nstatus; i++) { 1168 /* get pointer to busy command */ 1169 idx = mbox.mb_completed[i] - 1; 1170 ac = sc->amr_busycmd[idx]; 1171 1172 /* really a busy command? */ 1173 if (ac != NULL) { 1174 1175 /* pull the command from the busy index */ 1176 sc->amr_busycmd[idx] = NULL; 1177 sc->amr_busyslots--; 1178 1179 /* save status for later use */ 1180 ac->ac_status = mbox.mb_status; 1181 amr_enqueue_completed(ac); 1182 debug(3, "completed command with status %x", mbox.mb_status); 1183 } else { 1184 device_printf(sc->amr_dev, "bad slot %d completed\n", idx); 1185 } 1186 } 1187 } else { 1188 break; /* no work */ 1189 } 1190 } 1191 1192 /* if we've completed any commands, try posting some more */ 1193 if (result) 1194 amr_startio(sc); 1195 1196 /* handle completion and timeouts */ 1197#if __FreeBSD_version >= 500005 1198 if (sc->amr_state & AMR_STATE_INTEN) 1199 taskqueue_enqueue(taskqueue_swi, &sc->amr_task_complete); 1200 else 1201#endif 1202 amr_complete(sc, 0); 1203 1204 return(result); 1205} 1206 1207/******************************************************************************** 1208 * Do completion processing on done commands on (sc) 1209 */ 1210static void 1211amr_complete(void *context, int pending) 1212{ 1213 struct amr_softc *sc = (struct amr_softc *)context; 1214 struct amr_command *ac; 1215 1216 debug_called(2); 1217 1218 /* pull completed commands off the queue */ 1219 for (;;) { 1220 ac = amr_dequeue_completed(sc); 1221 if (ac == NULL) 1222 break; 1223 1224 /* unmap the command's data buffer */ 1225 amr_unmapcmd(ac); 1226 1227 /* unbusy the command */ 1228 ac->ac_flags &= ~AMR_CMD_BUSY; 1229 1230 /* 1231 * Is there a completion handler? 1232 */ 1233 if (ac->ac_complete != NULL) { 1234 ac->ac_complete(ac); 1235 1236 /* 1237 * Is someone sleeping on this one? 1238 */ 1239 } else if (ac->ac_flags & AMR_CMD_SLEEP) { 1240 wakeup(ac); 1241 } 1242 } 1243} 1244 1245/******************************************************************************** 1246 ******************************************************************************** 1247 Command Buffer Management 1248 ******************************************************************************** 1249 ********************************************************************************/ 1250 1251/******************************************************************************** 1252 * Get a new command buffer. 1253 * 1254 * This may return NULL in low-memory cases. 1255 * 1256 * If possible, we recycle a command buffer that's been used before. 1257 */ 1258struct amr_command * 1259amr_alloccmd(struct amr_softc *sc) 1260{ 1261 struct amr_command *ac; 1262 1263 debug_called(3); 1264 1265 ac = amr_dequeue_free(sc); 1266 if (ac == NULL) { 1267 amr_alloccmd_cluster(sc); 1268 ac = amr_dequeue_free(sc); 1269 } 1270 if (ac == NULL) 1271 return(NULL); 1272 1273 /* clear out significant fields */ 1274 ac->ac_slot = 0; 1275 ac->ac_status = 0; 1276 bzero(&ac->ac_mailbox, sizeof(struct amr_mailbox)); 1277 ac->ac_flags = 0; 1278 ac->ac_bio = NULL; 1279 ac->ac_data = NULL; 1280 ac->ac_ccb_data = NULL; 1281 ac->ac_complete = NULL; 1282 return(ac); 1283} 1284 1285/******************************************************************************** 1286 * Release a command buffer for recycling. 1287 */ 1288void 1289amr_releasecmd(struct amr_command *ac) 1290{ 1291 debug_called(3); 1292 1293 amr_enqueue_free(ac); 1294} 1295 1296/******************************************************************************** 1297 * Allocate a new command cluster and initialise it. 1298 */ 1299void 1300amr_alloccmd_cluster(struct amr_softc *sc) 1301{ 1302 struct amr_command_cluster *acc; 1303 struct amr_command *ac; 1304 int s, i; 1305 1306 acc = malloc(AMR_CMD_CLUSTERSIZE, M_DEVBUF, M_NOWAIT); 1307 if (acc != NULL) { 1308 s = splbio(); 1309 TAILQ_INSERT_TAIL(&sc->amr_cmd_clusters, acc, acc_link); 1310 splx(s); 1311 for (i = 0; i < AMR_CMD_CLUSTERCOUNT; i++) { 1312 ac = &acc->acc_command[i]; 1313 bzero(ac, sizeof(*ac)); 1314 ac->ac_sc = sc; 1315 if (!bus_dmamap_create(sc->amr_buffer_dmat, 0, &ac->ac_dmamap) && 1316 !bus_dmamap_create(sc->amr_buffer_dmat, 0, &ac->ac_ccb_dmamap)) 1317 amr_releasecmd(ac); 1318 } 1319 } 1320} 1321 1322/******************************************************************************** 1323 * Free a command cluster 1324 */ 1325void 1326amr_freecmd_cluster(struct amr_command_cluster *acc) 1327{ 1328 struct amr_softc *sc = acc->acc_command[0].ac_sc; 1329 int i; 1330 1331 for (i = 0; i < AMR_CMD_CLUSTERCOUNT; i++) 1332 bus_dmamap_destroy(sc->amr_buffer_dmat, acc->acc_command[i].ac_dmamap); 1333 free(acc, M_DEVBUF); 1334} 1335 1336/******************************************************************************** 1337 ******************************************************************************** 1338 Interface-specific Shims 1339 ******************************************************************************** 1340 ********************************************************************************/ 1341 1342/******************************************************************************** 1343 * Tell the controller that the mailbox contains a valid command 1344 */ 1345static int 1346amr_quartz_submit_command(struct amr_softc *sc) 1347{ 1348 debug_called(3); 1349 1350 if (AMR_QGET_IDB(sc) & AMR_QIDB_SUBMIT) 1351 return(EBUSY); 1352 AMR_QPUT_IDB(sc, sc->amr_mailboxphys | AMR_QIDB_SUBMIT); 1353 return(0); 1354} 1355 1356static int 1357amr_std_submit_command(struct amr_softc *sc) 1358{ 1359 debug_called(3); 1360 1361 if (AMR_SGET_MBSTAT(sc) & AMR_SMBOX_BUSYFLAG) 1362 return(EBUSY); 1363 AMR_SPOST_COMMAND(sc); 1364 return(0); 1365} 1366 1367/******************************************************************************** 1368 * Claim any work that the controller has completed; acknowledge completion, 1369 * save details of the completion in (mbsave) 1370 */ 1371static int 1372amr_quartz_get_work(struct amr_softc *sc, struct amr_mailbox *mbsave) 1373{ 1374 int s, worked; 1375 u_int32_t outd; 1376 1377 debug_called(3); 1378 1379 worked = 0; 1380 s = splbio(); 1381 1382 /* work waiting for us? */ 1383 if ((outd = AMR_QGET_ODB(sc)) == AMR_QODB_READY) { 1384 1385 /* save mailbox, which contains a list of completed commands */ 1386 bcopy((void *)(uintptr_t)(volatile void *)sc->amr_mailbox, mbsave, sizeof(*mbsave)); 1387 1388 /* acknowledge interrupt */ 1389 AMR_QPUT_ODB(sc, AMR_QODB_READY); 1390 1391 /* acknowledge that we have the commands */ 1392 AMR_QPUT_IDB(sc, sc->amr_mailboxphys | AMR_QIDB_ACK); 1393
|
1395 /* 1396 * This waits for the controller to notice that we've taken the 1397 * command from it. It's very inefficient, and we shouldn't do it, 1398 * but if we remove this code, we stop completing commands under 1399 * load. 1400 * 1401 * Peter J says we shouldn't do this. The documentation says we 1402 * should. Who is right? 1403 */ 1404 while(AMR_QGET_IDB(sc) & AMR_QIDB_ACK) 1405 ; /* XXX aiee! what if it dies? */ 1406#endif 1407 1408 worked = 1; /* got some work */ 1409 } 1410 1411 splx(s); 1412 return(worked); 1413} 1414 1415static int 1416amr_std_get_work(struct amr_softc *sc, struct amr_mailbox *mbsave) 1417{ 1418 int s, worked; 1419 u_int8_t istat; 1420 1421 debug_called(3); 1422 1423 worked = 0; 1424 s = splbio(); 1425 1426 /* check for valid interrupt status */ 1427 istat = AMR_SGET_ISTAT(sc); 1428 if ((istat & AMR_SINTR_VALID) != 0) { 1429 AMR_SPUT_ISTAT(sc, istat); /* ack interrupt status */ 1430 1431 /* save mailbox, which contains a list of completed commands */ 1432 bcopy((void *)(uintptr_t)(volatile void *)sc->amr_mailbox, mbsave, sizeof(*mbsave)); 1433 1434 AMR_SACK_INTERRUPT(sc); /* acknowledge we have the mailbox */ 1435 worked = 1; 1436 } 1437 1438 splx(s); 1439 return(worked); 1440} 1441 1442/******************************************************************************** 1443 * Notify the controller of the mailbox location. 1444 */ 1445static void 1446amr_std_attach_mailbox(struct amr_softc *sc) 1447{ 1448 1449 /* program the mailbox physical address */ 1450 AMR_SBYTE_SET(sc, AMR_SMBOX_0, sc->amr_mailboxphys & 0xff); 1451 AMR_SBYTE_SET(sc, AMR_SMBOX_1, (sc->amr_mailboxphys >> 8) & 0xff); 1452 AMR_SBYTE_SET(sc, AMR_SMBOX_2, (sc->amr_mailboxphys >> 16) & 0xff); 1453 AMR_SBYTE_SET(sc, AMR_SMBOX_3, (sc->amr_mailboxphys >> 24) & 0xff); 1454 AMR_SBYTE_SET(sc, AMR_SMBOX_ENABLE, AMR_SMBOX_ADDR); 1455 1456 /* clear any outstanding interrupt and enable interrupts proper */ 1457 AMR_SACK_INTERRUPT(sc); 1458 AMR_SENABLE_INTR(sc); 1459} 1460 1461#ifdef AMR_BOARD_INIT 1462/******************************************************************************** 1463 * Initialise the controller 1464 */ 1465static int 1466amr_quartz_init(struct amr_softc *sc) 1467{ 1468 int status, ostatus; 1469 1470 device_printf(sc->amr_dev, "initial init status %x\n", AMR_QGET_INITSTATUS(sc)); 1471 1472 AMR_QRESET(sc); 1473 1474 ostatus = 0xff; 1475 while ((status = AMR_QGET_INITSTATUS(sc)) != AMR_QINIT_DONE) { 1476 if (status != ostatus) { 1477 device_printf(sc->amr_dev, "(%x) %s\n", status, amr_describe_code(amr_table_qinit, status)); 1478 ostatus = status; 1479 } 1480 switch (status) { 1481 case AMR_QINIT_NOMEM: 1482 return(ENOMEM); 1483 1484 case AMR_QINIT_SCAN: 1485 /* XXX we could print channel/target here */ 1486 break; 1487 } 1488 } 1489 return(0); 1490} 1491 1492static int 1493amr_std_init(struct amr_softc *sc) 1494{ 1495 int status, ostatus; 1496 1497 device_printf(sc->amr_dev, "initial init status %x\n", AMR_SGET_INITSTATUS(sc)); 1498 1499 AMR_SRESET(sc); 1500 1501 ostatus = 0xff; 1502 while ((status = AMR_SGET_INITSTATUS(sc)) != AMR_SINIT_DONE) { 1503 if (status != ostatus) { 1504 device_printf(sc->amr_dev, "(%x) %s\n", status, amr_describe_code(amr_table_sinit, status)); 1505 ostatus = status; 1506 } 1507 switch (status) { 1508 case AMR_SINIT_NOMEM: 1509 return(ENOMEM); 1510 1511 case AMR_SINIT_INPROG: 1512 /* XXX we could print channel/target here? */ 1513 break; 1514 } 1515 } 1516 return(0); 1517} 1518#endif 1519 1520/******************************************************************************** 1521 ******************************************************************************** 1522 Debugging 1523 ******************************************************************************** 1524 ********************************************************************************/ 1525 1526/******************************************************************************** 1527 * Identify the controller and print some information about it. 1528 */ 1529static void 1530amr_describe_controller(struct amr_softc *sc) 1531{ 1532 struct amr_prodinfo *ap; 1533 struct amr_enquiry *ae; 1534 char *prod; 1535 1536 /* 1537 * Try to get 40LD product info, which tells us what the card is labelled as. 1538 */ 1539 if ((ap = amr_enquiry(sc, 2048, AMR_CMD_CONFIG, AMR_CONFIG_PRODUCT_INFO, 0)) != NULL) { 1540 device_printf(sc->amr_dev, "<%.80s> Firmware %.16s, BIOS %.16s, %dMB RAM\n", 1541 ap->ap_product, ap->ap_firmware, ap->ap_bios, 1542 ap->ap_memsize); 1543 1544 free(ap, M_DEVBUF); 1545 return; 1546 } 1547 1548 /* 1549 * Try 8LD extended ENQUIRY to get controller signature, and use lookup table. 1550 */ 1551 if ((ae = (struct amr_enquiry *)amr_enquiry(sc, 2048, AMR_CMD_EXT_ENQUIRY2, 0, 0)) != NULL) { 1552 prod = amr_describe_code(amr_table_adaptertype, ae->ae_signature); 1553 1554 } else if ((ae = (struct amr_enquiry *)amr_enquiry(sc, 2048, AMR_CMD_ENQUIRY, 0, 0)) != NULL) { 1555 1556 /* 1557 * Try to work it out based on the PCI signatures. 1558 */ 1559 switch (pci_get_device(sc->amr_dev)) { 1560 case 0x9010: 1561 prod = "Series 428"; 1562 break; 1563 case 0x9060: 1564 prod = "Series 434"; 1565 break; 1566 default: 1567 prod = "unknown controller"; 1568 break; 1569 } 1570 } else { 1571 prod = "unsupported controller"; 1572 } 1573 device_printf(sc->amr_dev, "<%s> Firmware %.4s, BIOS %.4s, %dMB RAM\n", 1574 prod, ae->ae_adapter.aa_firmware, ae->ae_adapter.aa_bios, 1575 ae->ae_adapter.aa_memorysize); 1576 free(ae, M_DEVBUF); 1577} 1578 1579#ifdef AMR_DEBUG 1580/******************************************************************************** 1581 * Print the command (ac) in human-readable format 1582 */ 1583static void 1584amr_printcommand(struct amr_command *ac) 1585{ 1586 struct amr_softc *sc = ac->ac_sc; 1587 struct amr_sgentry *sg; 1588 int i; 1589 1590 device_printf(sc->amr_dev, "cmd %x ident %d drive %d\n", 1591 ac->ac_mailbox.mb_command, ac->ac_mailbox.mb_ident, ac->ac_mailbox.mb_drive); 1592 device_printf(sc->amr_dev, "blkcount %d lba %d\n", 1593 ac->ac_mailbox.mb_blkcount, ac->ac_mailbox.mb_lba); 1594 device_printf(sc->amr_dev, "virtaddr %p length %lu\n", ac->ac_data, (unsigned long)ac->ac_length); 1595 device_printf(sc->amr_dev, "sg physaddr %08x nsg %d\n", 1596 ac->ac_mailbox.mb_physaddr, ac->ac_mailbox.mb_nsgelem); 1597 device_printf(sc->amr_dev, "ccb %p bio %p\n", ac->ac_ccb_data, ac->ac_bio); 1598 1599 /* get base address of s/g table */ 1600 sg = sc->amr_sgtable + (ac->ac_slot * AMR_NSEG); 1601 for (i = 0; i < ac->ac_mailbox.mb_nsgelem; i++, sg++) 1602 device_printf(sc->amr_dev, " %x/%d\n", sg->sg_addr, sg->sg_count); 1603} 1604#endif
|