1/*- 2 * Copyright (c) 1999,2000 Michael Smith 3 * Copyright (c) 2000 BSDi 4 * Copyright (c) 2005 Scott Long 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28/*- 29 * Copyright (c) 2002 Eric Moore
|
30 * Copyright (c) 2002 LSI Logic Corporation
|
30 * Copyright (c) 2002, 2004 LSI Logic Corporation |
31 * All rights reserved. 32 * 33 * Redistribution and use in source and binary forms, with or without 34 * modification, are permitted provided that the following conditions 35 * are met: 36 * 1. Redistributions of source code must retain the above copyright 37 * notice, this list of conditions and the following disclaimer. 38 * 2. Redistributions in binary form must reproduce the above copyright 39 * notice, this list of conditions and the following disclaimer in the 40 * documentation and/or other materials provided with the distribution. 41 * 3. The party using or redistributing the source code and binary forms 42 * agrees to the disclaimer below and the terms and conditions set forth 43 * herein. 44 * 45 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 46 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 47 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 48 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 49 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 50 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 51 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 52 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 53 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 54 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 55 * SUCH DAMAGE. 56 */ 57 58#include <sys/cdefs.h>
|
59__FBSDID("$FreeBSD: head/sys/dev/amr/amr.c 140687 2005-01-23 23:22:34Z scottl $");
|
59__FBSDID("$FreeBSD: head/sys/dev/amr/amr.c 140688 2005-01-23 23:25:41Z scottl $"); |
60 61/* 62 * Driver for the AMI MegaRaid family of controllers. 63 */ 64 65#include <sys/param.h> 66#include <sys/systm.h> 67#include <sys/malloc.h> 68#include <sys/kernel.h> 69 70#include <dev/amr/amr_compat.h> 71#include <sys/bus.h> 72#include <sys/conf.h> 73#include <sys/stat.h> 74 75#include <machine/bus_memio.h> 76#include <machine/bus_pio.h> 77#include <machine/bus.h> 78#include <machine/resource.h> 79#include <sys/rman.h> 80 81#include <dev/pci/pcireg.h> 82#include <dev/pci/pcivar.h> 83 84#include <dev/amr/amrio.h> 85#include <dev/amr/amrreg.h> 86#include <dev/amr/amrvar.h> 87#define AMR_DEFINE_TABLES 88#include <dev/amr/amr_tables.h> 89 90static d_open_t amr_open; 91static d_close_t amr_close; 92static d_ioctl_t amr_ioctl; 93 94static struct cdevsw amr_cdevsw = { 95 .d_version = D_VERSION, 96 .d_flags = D_NEEDGIANT, 97 .d_open = amr_open, 98 .d_close = amr_close, 99 .d_ioctl = amr_ioctl, 100 .d_name = "amr", 101}; 102 103/* 104 * Initialisation, bus interface. 105 */ 106static void amr_startup(void *arg); 107 108/* 109 * Command wrappers 110 */ 111static int amr_query_controller(struct amr_softc *sc); 112static void *amr_enquiry(struct amr_softc *sc, size_t bufsize, 113 u_int8_t cmd, u_int8_t cmdsub, u_int8_t cmdqual); 114static void amr_completeio(struct amr_command *ac); 115static int amr_support_ext_cdb(struct amr_softc *sc); 116 117/* 118 * Command buffer allocation. 119 */ 120static void amr_alloccmd_cluster(struct amr_softc *sc); 121static void amr_freecmd_cluster(struct amr_command_cluster *acc); 122 123/* 124 * Command processing. 125 */ 126static int amr_bio_command(struct amr_softc *sc, struct amr_command **acp); 127static int amr_wait_command(struct amr_command *ac) __unused; 128static int amr_getslot(struct amr_command *ac); 129static int amr_mapcmd(struct amr_command *ac); 130static void amr_unmapcmd(struct amr_command *ac); 131static int amr_start(struct amr_command *ac); 132static int amr_start1(struct amr_softc *sc, struct amr_command *ac); 133static void amr_complete(void *context, int pending); 134static void amr_setup_dmamap(void *arg, bus_dma_segment_t *segs, int nsegments, int error); 135static void amr_setup_data_dmamap(void *arg, bus_dma_segment_t *segs, int nsegments, int error); 136 137/* 138 * Status monitoring 139 */ 140static void amr_periodic(void *data); 141 142/* 143 * Interface-specific shims 144 */ 145static int amr_quartz_submit_command(struct amr_softc *sc); 146static int amr_quartz_get_work(struct amr_softc *sc, struct amr_mailbox *mbsave); 147static int amr_quartz_poll_command(struct amr_command *ac); 148static int amr_quartz_poll_command1(struct amr_softc *sc, struct amr_command *ac); 149 150static int amr_std_submit_command(struct amr_softc *sc); 151static int amr_std_get_work(struct amr_softc *sc, struct amr_mailbox *mbsave); 152static int amr_std_poll_command(struct amr_command *ac); 153static void amr_std_attach_mailbox(struct amr_softc *sc); 154 155#ifdef AMR_BOARD_INIT 156static int amr_quartz_init(struct amr_softc *sc); 157static int amr_std_init(struct amr_softc *sc); 158#endif 159 160/* 161 * Debugging 162 */ 163static void amr_describe_controller(struct amr_softc *sc); 164#ifdef AMR_DEBUG 165#if 0 166static void amr_printcommand(struct amr_command *ac); 167#endif 168#endif 169 170/******************************************************************************** 171 ******************************************************************************** 172 Inline Glue 173 ******************************************************************************** 174 ********************************************************************************/ 175 176/******************************************************************************** 177 ******************************************************************************** 178 Public Interfaces 179 ******************************************************************************** 180 ********************************************************************************/ 181 182/******************************************************************************** 183 * Initialise the controller and softc. 184 */ 185int 186amr_attach(struct amr_softc *sc) 187{ 188 189 debug_called(1); 190 191 /* 192 * Initialise per-controller queues. 193 */ 194 TAILQ_INIT(&sc->amr_completed); 195 TAILQ_INIT(&sc->amr_freecmds); 196 TAILQ_INIT(&sc->amr_cmd_clusters); 197 TAILQ_INIT(&sc->amr_ready); 198 bioq_init(&sc->amr_bioq); 199 200 debug(2, "queue init done"); 201 202 /* 203 * Configure for this controller type. 204 */ 205 if (AMR_IS_QUARTZ(sc)) { 206 sc->amr_submit_command = amr_quartz_submit_command; 207 sc->amr_get_work = amr_quartz_get_work; 208 sc->amr_poll_command = amr_quartz_poll_command; 209 sc->amr_poll_command1 = amr_quartz_poll_command1; 210 } else { 211 sc->amr_submit_command = amr_std_submit_command; 212 sc->amr_get_work = amr_std_get_work; 213 sc->amr_poll_command = amr_std_poll_command; 214 amr_std_attach_mailbox(sc);; 215 } 216 217#ifdef AMR_BOARD_INIT 218 if ((AMR_IS_QUARTZ(sc) ? amr_quartz_init(sc) : amr_std_init(sc)))) 219 return(ENXIO); 220#endif 221 222 /* 223 * Quiz controller for features and limits. 224 */ 225 if (amr_query_controller(sc)) 226 return(ENXIO); 227 228 debug(2, "controller query complete"); 229 230 /* 231 * Attach our 'real' SCSI channels to CAM. 232 */ 233 if (amr_cam_attach(sc)) 234 return(ENXIO); 235 debug(2, "CAM attach done"); 236 237 /* 238 * Create the control device. 239 */ 240 sc->amr_dev_t = make_dev(&amr_cdevsw, device_get_unit(sc->amr_dev), UID_ROOT, GID_OPERATOR, 241 S_IRUSR | S_IWUSR, "amr%d", device_get_unit(sc->amr_dev)); 242 sc->amr_dev_t->si_drv1 = sc; 243 244 /* 245 * Schedule ourselves to bring the controller up once interrupts are 246 * available. 247 */ 248 bzero(&sc->amr_ich, sizeof(struct intr_config_hook)); 249 sc->amr_ich.ich_func = amr_startup; 250 sc->amr_ich.ich_arg = sc; 251 if (config_intrhook_establish(&sc->amr_ich) != 0) { 252 device_printf(sc->amr_dev, "can't establish configuration hook\n"); 253 return(ENOMEM); 254 } 255 256 /* 257 * Print a little information about the controller. 258 */ 259 amr_describe_controller(sc); 260 261 debug(2, "attach complete"); 262 return(0); 263} 264 265/******************************************************************************** 266 * Locate disk resources and attach children to them. 267 */ 268static void 269amr_startup(void *arg) 270{ 271 struct amr_softc *sc = (struct amr_softc *)arg; 272 struct amr_logdrive *dr; 273 int i, error; 274 275 debug_called(1); 276 277 /* pull ourselves off the intrhook chain */ 278 config_intrhook_disestablish(&sc->amr_ich); 279 280 /* get up-to-date drive information */ 281 if (amr_query_controller(sc)) { 282 device_printf(sc->amr_dev, "can't scan controller for drives\n"); 283 return; 284 } 285 286 /* iterate over available drives */ 287 for (i = 0, dr = &sc->amr_drive[0]; (i < AMR_MAXLD) && (dr->al_size != 0xffffffff); i++, dr++) { 288 /* are we already attached to this drive? */ 289 if (dr->al_disk == 0) { 290 /* generate geometry information */ 291 if (dr->al_size > 0x200000) { /* extended translation? */ 292 dr->al_heads = 255; 293 dr->al_sectors = 63; 294 } else { 295 dr->al_heads = 64; 296 dr->al_sectors = 32; 297 } 298 dr->al_cylinders = dr->al_size / (dr->al_heads * dr->al_sectors); 299 300 dr->al_disk = device_add_child(sc->amr_dev, NULL, -1); 301 if (dr->al_disk == 0) 302 device_printf(sc->amr_dev, "device_add_child failed\n"); 303 device_set_ivars(dr->al_disk, dr); 304 } 305 } 306 307 if ((error = bus_generic_attach(sc->amr_dev)) != 0) 308 device_printf(sc->amr_dev, "bus_generic_attach returned %d\n", error); 309 310 /* mark controller back up */ 311 sc->amr_state &= ~AMR_STATE_SHUTDOWN; 312 313 /* interrupts will be enabled before we do anything more */ 314 sc->amr_state |= AMR_STATE_INTEN; 315 316 /* 317 * Start the timeout routine. 318 */ 319/* sc->amr_timeout = timeout(amr_periodic, sc, hz);*/ 320 321 return; 322} 323 324/******************************************************************************* 325 * Free resources associated with a controller instance 326 */ 327void 328amr_free(struct amr_softc *sc) 329{ 330 struct amr_command_cluster *acc; 331 332 /* detach from CAM */ 333 amr_cam_detach(sc); 334 335 /* cancel status timeout */ 336 untimeout(amr_periodic, sc, sc->amr_timeout); 337 338 /* throw away any command buffers */ 339 while ((acc = TAILQ_FIRST(&sc->amr_cmd_clusters)) != NULL) { 340 TAILQ_REMOVE(&sc->amr_cmd_clusters, acc, acc_link); 341 amr_freecmd_cluster(acc); 342 } 343 344 /* destroy control device */ 345 if( sc->amr_dev_t != (struct cdev *)NULL) 346 destroy_dev(sc->amr_dev_t); 347 348 if (mtx_initialized(&sc->amr_io_lock)) 349 mtx_destroy(&sc->amr_io_lock); 350} 351 352/******************************************************************************* 353 * Receive a bio structure from a child device and queue it on a particular 354 * disk resource, then poke the disk resource to start as much work as it can. 355 */ 356int 357amr_submit_bio(struct amr_softc *sc, struct bio *bio) 358{ 359 debug_called(2); 360 361 mtx_lock(&sc->amr_io_lock); 362 amr_enqueue_bio(sc, bio); 363 amr_startio(sc); 364 mtx_unlock(&sc->amr_io_lock); 365 return(0); 366} 367 368/******************************************************************************** 369 * Accept an open operation on the control device. 370 */ 371static int 372amr_open(struct cdev *dev, int flags, int fmt, d_thread_t *td) 373{ 374 int unit = minor(dev); 375 struct amr_softc *sc = devclass_get_softc(devclass_find("amr"), unit); 376 377 debug_called(1); 378 379 sc->amr_state |= AMR_STATE_OPEN; 380 return(0); 381} 382 383/******************************************************************************** 384 * Accept the last close on the control device. 385 */ 386static int 387amr_close(struct cdev *dev, int flags, int fmt, d_thread_t *td) 388{ 389 int unit = minor(dev); 390 struct amr_softc *sc = devclass_get_softc(devclass_find("amr"), unit); 391 392 debug_called(1); 393 394 sc->amr_state &= ~AMR_STATE_OPEN; 395 return (0); 396} 397 398/******************************************************************************** 399 * Handle controller-specific control operations. 400 */ 401static int 402amr_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int32_t flag, d_thread_t *td) 403{ 404 struct amr_softc *sc = (struct amr_softc *)dev->si_drv1; 405 union { 406 void *_p; 407 struct amr_user_ioctl *au; 408#ifdef AMR_IO_COMMAND32 409 struct amr_user_ioctl32 *au32; 410#endif 411 int *result; 412 } arg; 413 struct amr_command *ac; 414 struct amr_mailbox_ioctl *mbi; 415 void *dp, *au_buffer; 416 unsigned long au_length; 417 unsigned char *au_cmd; 418 int *au_statusp, au_direction; 419 int error; 420 421 debug_called(1); 422 423 arg._p = (void *)addr; 424 425 switch(cmd) { 426 427 case AMR_IO_VERSION: 428 debug(1, "AMR_IO_VERSION"); 429 *arg.result = AMR_IO_VERSION_NUMBER; 430 return(0); 431 432#ifdef AMR_IO_COMMAND32 433 /* 434 * Accept ioctl-s from 32-bit binaries on non-32-bit 435 * platforms, such as AMD. LSI's MEGAMGR utility is 436 * the only example known today... -mi 437 */ 438 case AMR_IO_COMMAND32: 439 debug(1, "AMR_IO_COMMAND32 0x%x", arg.au32->au_cmd[0]); 440 au_cmd = arg.au32->au_cmd; 441 au_buffer = (void *)(u_int64_t)arg.au32->au_buffer; 442 au_length = arg.au32->au_length; 443 au_direction = arg.au32->au_direction; 444 au_statusp = &arg.au32->au_status; 445 break; 446#endif 447 448 case AMR_IO_COMMAND: 449 debug(1, "AMR_IO_COMMAND 0x%x", arg.au->au_cmd[0]); 450 au_cmd = arg.au->au_cmd; 451 au_buffer = (void *)arg.au->au_buffer; 452 au_length = arg.au->au_length; 453 au_direction = arg.au->au_direction; 454 au_statusp = &arg.au->au_status; 455 break; 456 457 default: 458 debug(1, "unknown ioctl 0x%lx", cmd); 459 return(ENOIOCTL); 460 } 461 462 error = 0; 463 dp = NULL; 464 ac = NULL; 465
|
466 /* Logical Drive not supported by the driver */ 467 if (au_cmd[0] == 0xa4 && au_cmd[1] == 0x1c) 468 return (ENOIOCTL); 469 |
470 /* handle inbound data buffer */
|
467 if (au_length != 0) {
|
471 if (au_length != 0 && au_cmd[0] != 0x06) { |
472 if ((dp = malloc(au_length, M_DEVBUF, M_WAITOK)) == NULL) 473 return(ENOMEM); 474 475 if ((error = copyin(au_buffer, dp, au_length)) != 0) { 476 free(dp, M_DEVBUF); 477 return (error); 478 } 479 debug(2, "copyin %ld bytes from %p -> %p", au_length, au_buffer, dp); 480 } 481 482 mtx_lock(&sc->amr_io_lock); 483 if ((ac = amr_alloccmd(sc)) == NULL) { 484 error = ENOMEM; 485 goto out; 486 } 487 488 /* handle SCSI passthrough command */ 489 if (au_cmd[0] == AMR_CMD_PASS) { 490 struct amr_passthrough ap; /* 60 bytes */ 491 int len; 492 493 /* copy cdb */ 494 len = au_cmd[2]; 495 ap.ap_cdb_length = len; 496 bcopy(au_cmd + 3, ap.ap_cdb, len); 497 498 /* build passthrough */ 499 ap.ap_timeout = au_cmd[len + 3] & 0x07; 500 ap.ap_ars = (au_cmd[len + 3] & 0x08) ? 1 : 0; 501 ap.ap_islogical = (au_cmd[len + 3] & 0x80) ? 1 : 0; 502 ap.ap_logical_drive_no = au_cmd[len + 4]; 503 ap.ap_channel = au_cmd[len + 5]; 504 ap.ap_scsi_id = au_cmd[len + 6]; 505 ap.ap_request_sense_length = 14; 506 ap.ap_data_transfer_length = au_length; 507 /* XXX what about the request-sense area? does the caller want it? */ 508 509 /* build command */ 510 ac->ac_data = ≈ 511 ac->ac_length = sizeof(struct amr_passthrough); 512 ac->ac_flags |= AMR_CMD_DATAOUT; 513 ac->ac_ccb_data = dp; 514 ac->ac_ccb_length = au_length; 515 if (au_direction & AMR_IO_READ) 516 ac->ac_flags |= AMR_CMD_CCB_DATAIN; 517 if (au_direction & AMR_IO_WRITE) 518 ac->ac_flags |= AMR_CMD_CCB_DATAOUT; 519 520 ac->ac_mailbox.mb_command = AMR_CMD_PASS; 521 522 } else { 523 /* direct command to controller */ 524 mbi = (struct amr_mailbox_ioctl *)&ac->ac_mailbox; 525 526 /* copy pertinent mailbox items */ 527 mbi->mb_command = au_cmd[0]; 528 mbi->mb_channel = au_cmd[1]; 529 mbi->mb_param = au_cmd[2]; 530 mbi->mb_pad[0] = au_cmd[3]; 531 mbi->mb_drive = au_cmd[4]; 532 533 /* build the command */ 534 ac->ac_data = dp; 535 ac->ac_length = au_length; 536 if (au_direction & AMR_IO_READ) 537 ac->ac_flags |= AMR_CMD_DATAIN; 538 if (au_direction & AMR_IO_WRITE) 539 ac->ac_flags |= AMR_CMD_DATAOUT; 540 } 541 542 /* run the command */ 543 if ((error = amr_wait_command(ac)) != 0) 544 goto out; 545 546 /* copy out data and set status */ 547 if (au_length != 0) { 548 mtx_unlock(&sc->amr_io_lock); 549 error = copyout(dp, au_buffer, au_length); 550 mtx_lock(&sc->amr_io_lock); 551 } 552 debug(2, "copyout %ld bytes from %p -> %p", au_length, dp, au_buffer); 553 if (dp != NULL) 554 debug(2, "%16d", (int)dp); 555 *au_statusp = ac->ac_status; 556 557out: 558 /* 559 * At this point, we know that there is a lock held and that these 560 * objects have been allocated. 561 */ 562 free(dp, M_DEVBUF); 563 amr_releasecmd(ac); 564 mtx_unlock(&sc->amr_io_lock); 565 return(error); 566} 567 568/******************************************************************************** 569 ******************************************************************************** 570 Status Monitoring 571 ******************************************************************************** 572 ********************************************************************************/ 573 574/******************************************************************************** 575 * Perform a periodic check of the controller status 576 */ 577static void 578amr_periodic(void *data) 579{ 580 struct amr_softc *sc = (struct amr_softc *)data; 581 582 debug_called(2); 583 584 /* XXX perform periodic status checks here */ 585 586 /* compensate for missed interrupts */ 587 amr_done(sc); 588 589 /* reschedule */ 590 sc->amr_timeout = timeout(amr_periodic, sc, hz); 591} 592 593/******************************************************************************** 594 ******************************************************************************** 595 Command Wrappers 596 ******************************************************************************** 597 ********************************************************************************/ 598 599/******************************************************************************** 600 * Interrogate the controller for the operational parameters we require. 601 */ 602static int 603amr_query_controller(struct amr_softc *sc) 604{ 605 struct amr_enquiry3 *aex; 606 struct amr_prodinfo *ap; 607 struct amr_enquiry *ae; 608 int ldrv; 609 610 mtx_lock(&sc->amr_io_lock); 611 612 /* 613 * If we haven't found the real limit yet, let us have a couple of commands in 614 * order to be able to probe. 615 */ 616 if (sc->amr_maxio == 0) 617 sc->amr_maxio = 2; 618 619 /* 620 * Greater than 10 byte cdb support 621 */ 622 sc->support_ext_cdb = amr_support_ext_cdb(sc); 623 624 if(sc->support_ext_cdb) { 625 debug(2,"supports extended CDBs."); 626 } 627 628 /* 629 * Try to issue an ENQUIRY3 command 630 */ 631 if ((aex = amr_enquiry(sc, 2048, AMR_CMD_CONFIG, AMR_CONFIG_ENQ3, 632 AMR_CONFIG_ENQ3_SOLICITED_FULL)) != NULL) { 633 634 /* 635 * Fetch current state of logical drives. 636 */ 637 for (ldrv = 0; ldrv < aex->ae_numldrives; ldrv++) { 638 sc->amr_drive[ldrv].al_size = aex->ae_drivesize[ldrv]; 639 sc->amr_drive[ldrv].al_state = aex->ae_drivestate[ldrv]; 640 sc->amr_drive[ldrv].al_properties = aex->ae_driveprop[ldrv]; 641 debug(2, " drive %d: %d state %x properties %x\n", ldrv, sc->amr_drive[ldrv].al_size, 642 sc->amr_drive[ldrv].al_state, sc->amr_drive[ldrv].al_properties); 643 } 644 free(aex, M_DEVBUF); 645 646 /* 647 * Get product info for channel count. 648 */ 649 if ((ap = amr_enquiry(sc, 2048, AMR_CMD_CONFIG, AMR_CONFIG_PRODUCT_INFO, 0)) == NULL) { 650 device_printf(sc->amr_dev, "can't obtain product data from controller\n"); 651 mtx_unlock(&sc->amr_io_lock); 652 return(1); 653 } 654 sc->amr_maxdrives = 40; 655 sc->amr_maxchan = ap->ap_nschan; 656 sc->amr_maxio = ap->ap_maxio; 657 sc->amr_type |= AMR_TYPE_40LD; 658 free(ap, M_DEVBUF); 659 660 } else { 661 662 /* failed, try the 8LD ENQUIRY commands */ 663 if ((ae = (struct amr_enquiry *)amr_enquiry(sc, 2048, AMR_CMD_EXT_ENQUIRY2, 0, 0)) == NULL) { 664 if ((ae = (struct amr_enquiry *)amr_enquiry(sc, 2048, AMR_CMD_ENQUIRY, 0, 0)) == NULL) { 665 device_printf(sc->amr_dev, "can't obtain configuration data from controller\n"); 666 mtx_unlock(&sc->amr_io_lock); 667 return(1); 668 } 669 ae->ae_signature = 0; 670 } 671 672 /* 673 * Fetch current state of logical drives. 674 */ 675 for (ldrv = 0; ldrv < ae->ae_ldrv.al_numdrives; ldrv++) { 676 sc->amr_drive[ldrv].al_size = ae->ae_ldrv.al_size[ldrv]; 677 sc->amr_drive[ldrv].al_state = ae->ae_ldrv.al_state[ldrv]; 678 sc->amr_drive[ldrv].al_properties = ae->ae_ldrv.al_properties[ldrv]; 679 debug(2, " drive %d: %d state %x properties %x\n", ldrv, sc->amr_drive[ldrv].al_size, 680 sc->amr_drive[ldrv].al_state, sc->amr_drive[ldrv].al_properties); 681 } 682 683 sc->amr_maxdrives = 8; 684 sc->amr_maxchan = ae->ae_adapter.aa_channels; 685 sc->amr_maxio = ae->ae_adapter.aa_maxio; 686 free(ae, M_DEVBUF); 687 } 688 689 /* 690 * Mark remaining drives as unused. 691 */ 692 for (; ldrv < AMR_MAXLD; ldrv++) 693 sc->amr_drive[ldrv].al_size = 0xffffffff; 694 695 /* 696 * Cap the maximum number of outstanding I/Os. AMI's Linux driver doesn't trust 697 * the controller's reported value, and lockups have been seen when we do. 698 */ 699 sc->amr_maxio = imin(sc->amr_maxio, AMR_LIMITCMD); 700 701 mtx_unlock(&sc->amr_io_lock); 702 return(0); 703} 704 705/******************************************************************************** 706 * Run a generic enquiry-style command. 707 */ 708static void * 709amr_enquiry(struct amr_softc *sc, size_t bufsize, u_int8_t cmd, u_int8_t cmdsub, u_int8_t cmdqual) 710{ 711 struct amr_command *ac; 712 void *result; 713 u_int8_t *mbox; 714 int error; 715 716 debug_called(1); 717 718 error = 1; 719 result = NULL; 720 721 /* get ourselves a command buffer */ 722 if ((ac = amr_alloccmd(sc)) == NULL) 723 goto out; 724 /* allocate the response structure */ 725 if ((result = malloc(bufsize, M_DEVBUF, M_ZERO|M_NOWAIT)) == NULL) 726 goto out; 727 /* set command flags */ 728 729 ac->ac_flags |= AMR_CMD_PRIORITY | AMR_CMD_DATAIN; 730 731 /* point the command at our data */ 732 ac->ac_data = result; 733 ac->ac_length = bufsize; 734 735 /* build the command proper */ 736 mbox = (u_int8_t *)&ac->ac_mailbox; /* XXX want a real structure for this? */ 737 mbox[0] = cmd; 738 mbox[2] = cmdsub; 739 mbox[3] = cmdqual; 740 741 /* can't assume that interrupts are going to work here, so play it safe */ 742 if (sc->amr_poll_command(ac)) 743 goto out; 744 error = ac->ac_status; 745 746 out: 747 if (ac != NULL) 748 amr_releasecmd(ac); 749 if ((error != 0) && (result != NULL)) { 750 free(result, M_DEVBUF); 751 result = NULL; 752 } 753 return(result); 754} 755 756/******************************************************************************** 757 * Flush the controller's internal cache, return status. 758 */ 759int 760amr_flush(struct amr_softc *sc) 761{ 762 struct amr_command *ac; 763 int error; 764 765 /* get ourselves a command buffer */ 766 error = 1; 767 mtx_lock(&sc->amr_io_lock); 768 if ((ac = amr_alloccmd(sc)) == NULL) 769 goto out; 770 /* set command flags */ 771 ac->ac_flags |= AMR_CMD_PRIORITY | AMR_CMD_DATAOUT; 772 773 /* build the command proper */ 774 ac->ac_mailbox.mb_command = AMR_CMD_FLUSH; 775 776 /* we have to poll, as the system may be going down or otherwise damaged */ 777 if (sc->amr_poll_command(ac)) 778 goto out; 779 error = ac->ac_status; 780 781 out: 782 if (ac != NULL) 783 amr_releasecmd(ac); 784 mtx_unlock(&sc->amr_io_lock); 785 return(error); 786} 787 788/******************************************************************************** 789 * Detect extented cdb >> greater than 10 byte cdb support 790 * returns '1' means this support exist 791 * returns '0' means this support doesn't exist 792 */ 793static int 794amr_support_ext_cdb(struct amr_softc *sc) 795{ 796 struct amr_command *ac; 797 u_int8_t *mbox; 798 int error; 799 800 /* get ourselves a command buffer */ 801 error = 0; 802 if ((ac = amr_alloccmd(sc)) == NULL) 803 goto out; 804 /* set command flags */ 805 ac->ac_flags |= AMR_CMD_PRIORITY | AMR_CMD_DATAOUT; 806 807 /* build the command proper */ 808 mbox = (u_int8_t *)&ac->ac_mailbox; /* XXX want a real structure for this? */ 809 mbox[0] = 0xA4; 810 mbox[2] = 0x16; 811 812 813 /* we have to poll, as the system may be going down or otherwise damaged */ 814 if (sc->amr_poll_command(ac)) 815 goto out; 816 if( ac->ac_status == AMR_STATUS_SUCCESS ) { 817 error = 1; 818 } 819 820out: 821 if (ac != NULL) 822 amr_releasecmd(ac); 823 return(error); 824} 825 826/******************************************************************************** 827 * Try to find I/O work for the controller from one or more of the work queues. 828 * 829 * We make the assumption that if the controller is not ready to take a command 830 * at some given time, it will generate an interrupt at some later time when 831 * it is. 832 */ 833void 834amr_startio(struct amr_softc *sc) 835{ 836 struct amr_command *ac; 837 838 /* spin until something prevents us from doing any work */ 839 for (;;) { 840 841 /* Don't bother to queue commands no bounce buffers are available. */ 842 if (sc->amr_state & AMR_STATE_QUEUE_FRZN) 843 break; 844 845 /* try to get a ready command */ 846 ac = amr_dequeue_ready(sc); 847 848 /* if that failed, build a command from a bio */ 849 if (ac == NULL) 850 (void)amr_bio_command(sc, &ac); 851 852 /* if that failed, build a command from a ccb */ 853 if (ac == NULL) 854 (void)amr_cam_command(sc, &ac); 855 856 /* if we don't have anything to do, give up */ 857 if (ac == NULL) 858 break; 859 860 /* try to give the command to the controller; if this fails save it for later and give up */ 861 if (amr_start(ac)) { 862 debug(2, "controller busy, command deferred"); 863 amr_requeue_ready(ac); /* XXX schedule retry very soon? */ 864 break; 865 } 866 } 867} 868 869/******************************************************************************** 870 * Handle completion of an I/O command. 871 */ 872static void 873amr_completeio(struct amr_command *ac) 874{ 875 struct amr_softc *sc = ac->ac_sc; 876 877 if (ac->ac_status != AMR_STATUS_SUCCESS) { /* could be more verbose here? */ 878 ac->ac_bio->bio_error = EIO; 879 ac->ac_bio->bio_flags |= BIO_ERROR; 880 881 device_printf(sc->amr_dev, "I/O error - 0x%x\n", ac->ac_status); 882/* amr_printcommand(ac);*/ 883 } 884 amrd_intr(ac->ac_bio); 885 amr_releasecmd(ac); 886} 887 888/******************************************************************************** 889 ******************************************************************************** 890 Command Processing 891 ******************************************************************************** 892 ********************************************************************************/ 893 894/******************************************************************************** 895 * Convert a bio off the top of the bio queue into a command. 896 */ 897static int 898amr_bio_command(struct amr_softc *sc, struct amr_command **acp) 899{ 900 struct amr_command *ac; 901 struct amrd_softc *amrd; 902 struct bio *bio; 903 int error; 904 int blkcount; 905 int driveno; 906 int cmd; 907 908 ac = NULL; 909 error = 0; 910 911 /* get a command */ 912 if ((ac = amr_alloccmd(sc)) == NULL) 913 return (ENOMEM); 914 915 /* get a bio to work on */ 916 if ((bio = amr_dequeue_bio(sc)) == NULL) { 917 amr_releasecmd(ac); 918 return (0); 919 } 920 921 /* connect the bio to the command */ 922 ac->ac_complete = amr_completeio; 923 ac->ac_bio = bio; 924 ac->ac_data = bio->bio_data; 925 ac->ac_length = bio->bio_bcount; 926 if (BIO_IS_READ(bio)) { 927 ac->ac_flags |= AMR_CMD_DATAIN; 928 cmd = AMR_CMD_LREAD; 929 } else { 930 ac->ac_flags |= AMR_CMD_DATAOUT; 931 cmd = AMR_CMD_LWRITE; 932 } 933 amrd = (struct amrd_softc *)bio->bio_disk->d_drv1; 934 driveno = amrd->amrd_drive - sc->amr_drive; 935 blkcount = (bio->bio_bcount + AMR_BLKSIZE - 1) / AMR_BLKSIZE; 936 937 ac->ac_mailbox.mb_command = cmd; 938 ac->ac_mailbox.mb_blkcount = blkcount; 939 ac->ac_mailbox.mb_lba = bio->bio_pblkno; 940 ac->ac_mailbox.mb_drive = driveno; 941 /* we fill in the s/g related data when the command is mapped */ 942 943 if ((bio->bio_pblkno + blkcount) > sc->amr_drive[driveno].al_size) 944 device_printf(sc->amr_dev, "I/O beyond end of unit (%lld,%d > %lu)\n", 945 (long long)bio->bio_pblkno, blkcount, 946 (u_long)sc->amr_drive[driveno].al_size); 947 948 *acp = ac; 949 return(error); 950} 951 952/******************************************************************************** 953 * Take a command, submit it to the controller and sleep until it completes 954 * or fails. Interrupts must be enabled, returns nonzero on error. 955 */ 956static int 957amr_wait_command(struct amr_command *ac) 958{ 959 int error, count; 960 961 debug_called(1); 962 963 ac->ac_complete = NULL; 964 ac->ac_flags |= AMR_CMD_SLEEP; 965 if ((error = amr_start(ac)) != 0) 966 return(error); 967 968 count = 0; 969 /* XXX better timeout? */ 970 while ((ac->ac_flags & AMR_CMD_BUSY) && (count < 30)) { 971 msleep(ac, &ac->ac_sc->amr_io_lock, PRIBIO | PCATCH, "amrwcmd", hz); 972 } 973 return(0); 974} 975 976/******************************************************************************** 977 * Take a command, submit it to the controller and busy-wait for it to return. 978 * Returns nonzero on error. Can be safely called with interrupts enabled. 979 */ 980static int 981amr_std_poll_command(struct amr_command *ac) 982{ 983 struct amr_softc *sc = ac->ac_sc; 984 int error, count; 985 986 debug_called(2); 987 988 ac->ac_complete = NULL; 989 if ((error = amr_start(ac)) != 0) 990 return(error); 991 992 count = 0; 993 do { 994 /* 995 * Poll for completion, although the interrupt handler may beat us to it. 996 * Note that the timeout here is somewhat arbitrary. 997 */ 998 amr_done(sc); 999 DELAY(1000); 1000 } while ((ac->ac_flags & AMR_CMD_BUSY) && (count++ < 1000)); 1001 if (!(ac->ac_flags & AMR_CMD_BUSY)) { 1002 error = 0; 1003 } else { 1004 /* XXX the slot is now marked permanently busy */ 1005 error = EIO; 1006 device_printf(sc->amr_dev, "polled command timeout\n"); 1007 } 1008 return(error); 1009} 1010 1011static void 1012amr_setup_polled_dmamap(void *arg, bus_dma_segment_t *segs, int nsegs, int err) 1013{ 1014 struct amr_command *ac = arg; 1015 struct amr_softc *sc = ac->ac_sc; 1016 1017 amr_setup_dmamap(arg, segs, nsegs, err); 1018 bus_dmamap_sync(sc->amr_buffer_dmat,ac->ac_dmamap,BUS_DMASYNC_PREREAD); 1019 sc->amr_poll_command1(sc, ac); 1020} 1021 1022/******************************************************************************** 1023 * Take a command, submit it to the controller and busy-wait for it to return. 1024 * Returns nonzero on error. Can be safely called with interrupts enabled. 1025 */ 1026static int 1027amr_quartz_poll_command(struct amr_command *ac) 1028{ 1029 struct amr_softc *sc = ac->ac_sc; 1030 int s, error; 1031 1032 debug_called(2); 1033 1034 s = splbio(); 1035 error = 0; 1036 1037 /* now we have a slot, we can map the command (unmapped in amr_complete) */ 1038 if (ac->ac_data != 0) { 1039 if (bus_dmamap_load(sc->amr_buffer_dmat, ac->ac_dmamap, ac->ac_data, 1040 ac->ac_length, amr_setup_polled_dmamap, ac, BUS_DMA_NOWAIT) != 0) { 1041 error = 1; 1042 } 1043 } else { 1044 error = amr_quartz_poll_command1(sc, ac); 1045 } 1046 1047 splx(s); 1048 return (error); 1049} 1050 1051static int 1052amr_quartz_poll_command1(struct amr_softc *sc, struct amr_command *ac) 1053{ 1054 int count, error; 1055
|
1052 if ((sc->amr_state & AMR_STATE_CRASHDUMP) == 0) {
|
1056 if ((sc->amr_state & AMR_STATE_INTEN) == 0) { |
1057 count=0; 1058 while (sc->amr_busyslots) { 1059 msleep(sc, &sc->amr_io_lock, PRIBIO | PCATCH, "amrpoll", hz); 1060 if(count++>10) { 1061 break; 1062 } 1063 } 1064 1065 if(sc->amr_busyslots) { 1066 device_printf(sc->amr_dev, "adapter is busy\n"); 1067 if (ac->ac_data != NULL) 1068 bus_dmamap_unload(sc->amr_buffer_dmat, ac->ac_dmamap); 1069 ac->ac_status=0; 1070 return(1); 1071 } 1072 } 1073 1074 bcopy(&ac->ac_mailbox, (void *)(uintptr_t)(volatile void *)sc->amr_mailbox, AMR_MBOX_CMDSIZE); 1075 1076 /* clear the poll/ack fields in the mailbox */ 1077 sc->amr_mailbox->mb_ident = 0xFE; 1078 sc->amr_mailbox->mb_nstatus = 0xFF; 1079 sc->amr_mailbox->mb_status = 0xFF; 1080 sc->amr_mailbox->mb_poll = 0; 1081 sc->amr_mailbox->mb_ack = 0; 1082 sc->amr_mailbox->mb_busy = 1; 1083 1084 AMR_QPUT_IDB(sc, sc->amr_mailboxphys | AMR_QIDB_SUBMIT); 1085 1086 while(sc->amr_mailbox->mb_nstatus == 0xFF); 1087 while(sc->amr_mailbox->mb_status == 0xFF); 1088 ac->ac_status=sc->amr_mailbox->mb_status; 1089 error = (ac->ac_status !=AMR_STATUS_SUCCESS) ? 1:0; 1090 while(sc->amr_mailbox->mb_poll != 0x77); 1091 sc->amr_mailbox->mb_poll = 0; 1092 sc->amr_mailbox->mb_ack = 0x77; 1093 1094 /* acknowledge that we have the commands */ 1095 AMR_QPUT_IDB(sc, sc->amr_mailboxphys | AMR_QIDB_ACK); 1096 while(AMR_QGET_IDB(sc) & AMR_QIDB_ACK); 1097 1098 /* unmap the command's data buffer */ 1099 bus_dmamap_sync(sc->amr_buffer_dmat, ac->ac_dmamap, BUS_DMASYNC_POSTREAD); 1100 bus_dmamap_unload(sc->amr_buffer_dmat, ac->ac_dmamap); 1101 1102 return(error); 1103} 1104 1105/******************************************************************************** 1106 * Get a free command slot for a command if it doesn't already have one. 1107 * 1108 * May be safely called multiple times for a given command. 1109 */ 1110static int 1111amr_getslot(struct amr_command *ac) 1112{ 1113 struct amr_softc *sc = ac->ac_sc; 1114 int slot; 1115 1116 debug_called(3); 1117 1118 slot = ac->ac_slot; 1119 if (sc->amr_busycmd[slot] != NULL) 1120 panic("amr: slot %d busy?\n", slot); 1121 1122 sc->amr_busycmd[slot] = ac; 1123 sc->amr_busyslots++; 1124 1125 return (0); 1126} 1127 1128/******************************************************************************** 1129 * Map/unmap (ac)'s data in the controller's addressable space as required. 1130 * 1131 * These functions may be safely called multiple times on a given command. 1132 */ 1133static void 1134amr_setup_dmamap(void *arg, bus_dma_segment_t *segs, int nsegments, int error) 1135{ 1136 struct amr_command *ac = (struct amr_command *)arg; 1137 struct amr_softc *sc = ac->ac_sc; 1138 struct amr_sgentry *sg; 1139 int i; 1140 u_int8_t *sgc; 1141 1142 debug_called(3); 1143 1144 /* get base address of s/g table */ 1145 sg = sc->amr_sgtable + (ac->ac_slot * AMR_NSEG); 1146 1147 /* save data physical address */ 1148 ac->ac_dataphys = segs[0].ds_addr; 1149 1150 /* for AMR_CMD_CONFIG the s/g count goes elsewhere */ 1151 if (ac->ac_mailbox.mb_command == AMR_CMD_CONFIG) { 1152 sgc = &(((struct amr_mailbox_ioctl *)&ac->ac_mailbox)->mb_param); 1153 } else { 1154 sgc = &ac->ac_mailbox.mb_nsgelem; 1155 } 1156 1157 /* decide whether we need to populate the s/g table */ 1158 if (nsegments < 2) { 1159 *sgc = 0; 1160 ac->ac_mailbox.mb_nsgelem = 0; 1161 ac->ac_mailbox.mb_physaddr = ac->ac_dataphys; 1162 } else { 1163 ac->ac_mailbox.mb_nsgelem = nsegments; 1164 *sgc = nsegments; 1165 ac->ac_mailbox.mb_physaddr = sc->amr_sgbusaddr + 1166 (ac->ac_slot * AMR_NSEG * sizeof(struct amr_sgentry)); 1167 for (i = 0; i < nsegments; i++, sg++) { 1168 sg->sg_addr = segs[i].ds_addr; 1169 sg->sg_count = segs[i].ds_len; 1170 } 1171 } 1172 1173} 1174 1175static void 1176amr_setup_ccbmap(void *arg, bus_dma_segment_t *segs, int nsegments, int error) 1177{ 1178 struct amr_command *ac = (struct amr_command *)arg; 1179 struct amr_softc *sc = ac->ac_sc; 1180 struct amr_sgentry *sg; 1181 struct amr_passthrough *ap = (struct amr_passthrough *)ac->ac_data; 1182 struct amr_ext_passthrough *aep = (struct amr_ext_passthrough *)ac->ac_data; 1183 int i; 1184 1185 /* get base address of s/g table */ 1186 sg = sc->amr_sgtable + (ac->ac_slot * AMR_NSEG); 1187 1188 /* decide whether we need to populate the s/g table */ 1189 if( ac->ac_mailbox.mb_command == AMR_CMD_EXTPASS ) { 1190 if (nsegments < 2) { 1191 aep->ap_no_sg_elements = 0; 1192 aep->ap_data_transfer_address = segs[0].ds_addr; 1193 } else { 1194 /* save s/g table information in passthrough */ 1195 aep->ap_no_sg_elements = nsegments; 1196 aep->ap_data_transfer_address = sc->amr_sgbusaddr + 1197 (ac->ac_slot * AMR_NSEG * sizeof(struct amr_sgentry)); 1198 /* 1199 * populate s/g table (overwrites previous call which mapped the 1200 * passthrough) 1201 */ 1202 for (i = 0; i < nsegments; i++, sg++) { 1203 sg->sg_addr = segs[i].ds_addr; 1204 sg->sg_count = segs[i].ds_len; 1205 debug(3, " %d: 0x%x/%d", i, sg->sg_addr, sg->sg_count); 1206 } 1207 } 1208 debug(3, "slot %d %d segments at 0x%x, passthrough at 0x%x\n", 1209 ac->ac_slot, aep->ap_no_sg_elements, aep->ap_data_transfer_address, 1210 ac->ac_dataphys); 1211 } else { 1212 if (nsegments < 2) { 1213 ap->ap_no_sg_elements = 0; 1214 ap->ap_data_transfer_address = segs[0].ds_addr; 1215 } else { 1216 /* save s/g table information in passthrough */ 1217 ap->ap_no_sg_elements = nsegments; 1218 ap->ap_data_transfer_address = sc->amr_sgbusaddr + 1219 (ac->ac_slot * AMR_NSEG * sizeof(struct amr_sgentry)); 1220 /* 1221 * populate s/g table (overwrites previous call which mapped the 1222 * passthrough) 1223 */ 1224 for (i = 0; i < nsegments; i++, sg++) { 1225 sg->sg_addr = segs[i].ds_addr; 1226 sg->sg_count = segs[i].ds_len; 1227 debug(3, " %d: 0x%x/%d", i, sg->sg_addr, sg->sg_count); 1228 } 1229 } 1230 debug(3, "slot %d %d segments at 0x%x, passthrough at 0x%x", 1231 ac->ac_slot, ap->ap_no_sg_elements, ap->ap_data_transfer_address, 1232 ac->ac_dataphys); 1233 } 1234 if (ac->ac_flags & AMR_CMD_CCB_DATAIN) 1235 bus_dmamap_sync(sc->amr_buffer_dmat, ac->ac_ccb_dmamap, 1236 BUS_DMASYNC_PREREAD); 1237 if (ac->ac_flags & AMR_CMD_CCB_DATAOUT) 1238 bus_dmamap_sync(sc->amr_buffer_dmat, ac->ac_ccb_dmamap, 1239 BUS_DMASYNC_PREWRITE); 1240 if ((ac->ac_flags & (AMR_CMD_CCB_DATAIN | AMR_CMD_CCB_DATAOUT)) == 0) 1241 panic("no direction for ccb?\n"); 1242 1243 if (ac->ac_flags & AMR_CMD_DATAIN) 1244 bus_dmamap_sync(sc->amr_buffer_dmat,ac->ac_dmamap,BUS_DMASYNC_PREREAD); 1245 if (ac->ac_flags & AMR_CMD_DATAOUT) 1246 bus_dmamap_sync(sc->amr_buffer_dmat,ac->ac_dmamap,BUS_DMASYNC_PREWRITE); 1247 1248 ac->ac_flags |= AMR_CMD_MAPPED; 1249 1250 amr_start1(sc, ac); 1251} 1252 1253static int 1254amr_mapcmd(struct amr_command *ac) 1255{ 1256 struct amr_softc *sc = ac->ac_sc; 1257 1258 debug_called(3); 1259 1260 /* if the command involves data at all, and hasn't been mapped */ 1261 if ((ac->ac_flags & AMR_CMD_MAPPED) == 0 && (ac->ac_data != NULL)) { 1262 if (ac->ac_ccb_data == NULL) { 1263 /* map the data buffers into bus space and build the s/g list */ 1264 if (bus_dmamap_load(sc->amr_buffer_dmat, ac->ac_dmamap, ac->ac_data, 1265 ac->ac_length, amr_setup_data_dmamap, ac, 0) == EINPROGRESS) { 1266 sc->amr_state |= AMR_STATE_QUEUE_FRZN; 1267 } 1268 } else { 1269 1270 if (bus_dmamap_load(sc->amr_buffer_dmat, ac->ac_dmamap, ac->ac_data, 1271 ac->ac_length, amr_setup_dmamap, ac, BUS_DMA_NOWAIT) != 0){ 1272 return (ENOMEM); 1273 } 1274 if (bus_dmamap_load(sc->amr_buffer_dmat, ac->ac_ccb_dmamap, 1275 ac->ac_ccb_data, ac->ac_ccb_length, amr_setup_ccbmap, ac, 1276 0) == EINPROGRESS) { 1277 sc->amr_state |= AMR_STATE_QUEUE_FRZN; 1278 } 1279 } 1280 } 1281 return (0); 1282} 1283 1284static void 1285amr_unmapcmd(struct amr_command *ac) 1286{ 1287 struct amr_softc *sc = ac->ac_sc; 1288 1289 debug_called(3); 1290 1291 /* if the command involved data at all and was mapped */ 1292 if (ac->ac_flags & AMR_CMD_MAPPED) { 1293 1294 if (ac->ac_data != NULL) { 1295 if (ac->ac_flags & AMR_CMD_DATAIN) 1296 bus_dmamap_sync(sc->amr_buffer_dmat, ac->ac_dmamap, 1297 BUS_DMASYNC_POSTREAD); 1298 if (ac->ac_flags & AMR_CMD_DATAOUT) 1299 bus_dmamap_sync(sc->amr_buffer_dmat, ac->ac_dmamap, 1300 BUS_DMASYNC_POSTWRITE); 1301 bus_dmamap_unload(sc->amr_buffer_dmat, ac->ac_dmamap); 1302 } 1303 1304 if (ac->ac_ccb_data != NULL) { 1305 if (ac->ac_flags & AMR_CMD_CCB_DATAIN) 1306 bus_dmamap_sync(sc->amr_buffer_dmat, ac->ac_ccb_dmamap, 1307 BUS_DMASYNC_POSTREAD); 1308 if (ac->ac_flags & AMR_CMD_CCB_DATAOUT) 1309 bus_dmamap_sync(sc->amr_buffer_dmat, ac->ac_ccb_dmamap, 1310 BUS_DMASYNC_POSTWRITE); 1311 bus_dmamap_unload(sc->amr_buffer_dmat, ac->ac_ccb_dmamap); 1312 debug(3, "slot %d %d segments at 0x%x, passthrough at 0x%x\n", 1313 ac->ac_slot, aep->ap_no_sg_elements, aep->ap_data_transfer_address, 1314 ac->ac_dataphys); 1315 } 1316 ac->ac_flags &= ~AMR_CMD_MAPPED; 1317 } 1318} 1319 1320static void 1321amr_setup_data_dmamap(void *arg, bus_dma_segment_t *segs, int nsegs, int err) 1322{ 1323 struct amr_command *ac = arg; 1324 struct amr_softc *sc = ac->ac_sc; 1325 1326 amr_setup_dmamap(arg, segs, nsegs, err); 1327 1328 if (ac->ac_flags & AMR_CMD_DATAIN) 1329 bus_dmamap_sync(sc->amr_buffer_dmat,ac->ac_dmamap,BUS_DMASYNC_PREREAD); 1330 if (ac->ac_flags & AMR_CMD_DATAOUT) 1331 bus_dmamap_sync(sc->amr_buffer_dmat,ac->ac_dmamap,BUS_DMASYNC_PREWRITE); 1332 ac->ac_flags |= AMR_CMD_MAPPED; 1333 1334 amr_start1(sc, ac); 1335} 1336 1337/******************************************************************************** 1338 * Take a command and give it to the controller, returns 0 if successful, or 1339 * EBUSY if the command should be retried later. 1340 */ 1341static int 1342amr_start(struct amr_command *ac) 1343{ 1344 struct amr_softc *sc; 1345 int error = 0; 1346 1347 debug_called(3); 1348 1349 /* mark command as busy so that polling consumer can tell */ 1350 sc = ac->ac_sc; 1351 ac->ac_flags |= AMR_CMD_BUSY; 1352 1353 /* get a command slot (freed in amr_done) */ 1354 if (amr_getslot(ac)) { 1355 return(EBUSY); 1356 } 1357 1358 /* Now we have a slot, we can map the command (unmapped in amr_complete). */ 1359 if ((error = amr_mapcmd(ac)) == ENOMEM) { 1360 /* 1361 * Memroy resources are short, so free the slot and let this be tried 1362 * later. 1363 */ 1364 sc->amr_busycmd[ac->ac_slot] = NULL; 1365 sc->amr_busyslots--; 1366 } 1367 1368 return (error); 1369} 1370 1371 1372static int 1373amr_start1(struct amr_softc *sc, struct amr_command *ac) 1374{ 1375 int done, s, i; 1376 1377 /* mark the new mailbox we are going to copy in as busy */ 1378 ac->ac_mailbox.mb_busy = 1; 1379 1380 /* clear the poll/ack fields in the mailbox */ 1381 sc->amr_mailbox->mb_poll = 0; 1382 sc->amr_mailbox->mb_ack = 0; 1383 1384 /* 1385 * Save the slot number so that we can locate this command when complete. 1386 * Note that ident = 0 seems to be special, so we don't use it. 1387 */ 1388 ac->ac_mailbox.mb_ident = ac->ac_slot + 1; 1389 1390 /* 1391 * Spin waiting for the mailbox, give up after ~1 second. We expect the 1392 * controller to be able to handle our I/O. 1393 * 1394 * XXX perhaps we should wait for less time, and count on the deferred command 1395 * handling to deal with retries? 1396 */ 1397 debug(4, "wait for mailbox"); 1398 for (i = 10000, done = 0; (i > 0) && !done; i--) { 1399 s = splbio(); 1400 1401 /* is the mailbox free? */ 1402 if (sc->amr_mailbox->mb_busy == 0) { 1403 debug(4, "got mailbox"); 1404 sc->amr_mailbox64->mb64_segment = 0; 1405 bcopy(&ac->ac_mailbox, (void *)(uintptr_t)(volatile void *)sc->amr_mailbox, AMR_MBOX_CMDSIZE); 1406 done = 1; 1407 1408 /* not free, spin waiting */ 1409 } else { 1410 debug(4, "busy flag %x\n", sc->amr_mailbox->mb_busy); 1411 /* this is somewhat ugly */ 1412 DELAY(100); 1413 } 1414 splx(s); /* drop spl to allow completion interrupts */ 1415 } 1416 1417 /* 1418 * Now give the command to the controller 1419 */ 1420 if (done) { 1421 if (sc->amr_submit_command(sc)) { 1422 /* the controller wasn't ready to take the command, forget that we tried to post it */ 1423 sc->amr_mailbox->mb_busy = 0; 1424 return(EBUSY); 1425 } 1426 debug(3, "posted command"); 1427 return(0); 1428 } 1429 1430 /* 1431 * The controller wouldn't take the command. Return the command as busy 1432 * so that it is retried later. 1433 */ 1434 return(EBUSY); 1435} 1436 1437/******************************************************************************** 1438 * Extract one or more completed commands from the controller (sc) 1439 * 1440 * Returns nonzero if any commands on the work queue were marked as completed. 1441 */ 1442 1443int 1444amr_done(struct amr_softc *sc) 1445{ 1446 struct amr_command *ac; 1447 struct amr_mailbox mbox; 1448 int i, idx, result; 1449 1450 debug_called(3); 1451 1452 /* See if there's anything for us to do */ 1453 result = 0; 1454 1455 /* loop collecting completed commands */ 1456 for (;;) { 1457 /* poll for a completed command's identifier and status */ 1458 if (sc->amr_get_work(sc, &mbox)) { 1459 result = 1; 1460 1461 /* iterate over completed commands in this result */ 1462 for (i = 0; i < mbox.mb_nstatus; i++) { 1463 /* get pointer to busy command */ 1464 idx = mbox.mb_completed[i] - 1; 1465 ac = sc->amr_busycmd[idx]; 1466 1467 /* really a busy command? */ 1468 if (ac != NULL) { 1469 1470 /* pull the command from the busy index */ 1471 sc->amr_busycmd[idx] = NULL; 1472 sc->amr_busyslots--; 1473 1474 /* save status for later use */ 1475 ac->ac_status = mbox.mb_status; 1476 amr_enqueue_completed(ac); 1477 debug(3, "completed command with status %x", mbox.mb_status); 1478 } else { 1479 device_printf(sc->amr_dev, "bad slot %d completed\n", idx); 1480 } 1481 } 1482 } else { 1483 break; /* no work */ 1484 } 1485 } 1486 1487 /* handle completion and timeouts */ 1488 amr_complete(sc, 0); 1489 1490 return(result); 1491} 1492 1493/******************************************************************************** 1494 * Do completion processing on done commands on (sc) 1495 */ 1496 1497static void 1498amr_complete(void *context, int pending) 1499{ 1500 struct amr_softc *sc = (struct amr_softc *)context; 1501 struct amr_command *ac; 1502 1503 debug_called(3); 1504 1505 /* pull completed commands off the queue */ 1506 for (;;) { 1507 ac = amr_dequeue_completed(sc); 1508 if (ac == NULL) 1509 break; 1510 1511 /* unmap the command's data buffer */ 1512 amr_unmapcmd(ac); 1513 1514 /* unbusy the command */ 1515 ac->ac_flags &= ~AMR_CMD_BUSY; 1516 1517 /* 1518 * Is there a completion handler? 1519 */ 1520 if (ac->ac_complete != NULL) { 1521 ac->ac_complete(ac); 1522 1523 /* 1524 * Is someone sleeping on this one? 1525 */ 1526 } else if (ac->ac_flags & AMR_CMD_SLEEP) { 1527 wakeup(ac); 1528 } 1529 1530 if(!sc->amr_busyslots) { 1531 wakeup(sc); 1532 } 1533 } 1534 1535 sc->amr_state &= ~AMR_STATE_QUEUE_FRZN; 1536 amr_startio(sc); 1537} 1538 1539/******************************************************************************** 1540 ******************************************************************************** 1541 Command Buffer Management 1542 ******************************************************************************** 1543 ********************************************************************************/ 1544 1545/******************************************************************************** 1546 * Get a new command buffer. 1547 * 1548 * This may return NULL in low-memory cases. 1549 * 1550 * If possible, we recycle a command buffer that's been used before. 1551 */ 1552struct amr_command * 1553amr_alloccmd(struct amr_softc *sc) 1554{ 1555 struct amr_command *ac; 1556 1557 debug_called(3); 1558 1559 ac = amr_dequeue_free(sc); 1560 if (ac == NULL) { 1561 amr_alloccmd_cluster(sc); 1562 ac = amr_dequeue_free(sc); 1563 } 1564 if (ac == NULL) { 1565 sc->amr_state |= AMR_STATE_QUEUE_FRZN; 1566 return(NULL); 1567 } 1568 1569 /* clear out significant fields */ 1570 ac->ac_status = 0; 1571 bzero(&ac->ac_mailbox, sizeof(struct amr_mailbox)); 1572 ac->ac_flags = 0; 1573 ac->ac_bio = NULL; 1574 ac->ac_data = NULL; 1575 ac->ac_ccb_data = NULL; 1576 ac->ac_complete = NULL; 1577 return(ac); 1578} 1579 1580/******************************************************************************** 1581 * Release a command buffer for recycling. 1582 */ 1583void 1584amr_releasecmd(struct amr_command *ac) 1585{ 1586 debug_called(3); 1587 1588 amr_enqueue_free(ac); 1589} 1590 1591/******************************************************************************** 1592 * Allocate a new command cluster and initialise it. 1593 */ 1594static void 1595amr_alloccmd_cluster(struct amr_softc *sc) 1596{ 1597 struct amr_command_cluster *acc; 1598 struct amr_command *ac; 1599 int s, i, nextslot; 1600 1601 if (sc->amr_nextslot > sc->amr_maxio) 1602 return; 1603 acc = malloc(AMR_CMD_CLUSTERSIZE, M_DEVBUF, M_NOWAIT | M_ZERO); 1604 if (acc != NULL) { 1605 s = splbio(); 1606 nextslot = sc->amr_nextslot; 1607 TAILQ_INSERT_TAIL(&sc->amr_cmd_clusters, acc, acc_link); 1608 splx(s); 1609 for (i = 0; i < AMR_CMD_CLUSTERCOUNT; i++) { 1610 ac = &acc->acc_command[i]; 1611 ac->ac_sc = sc; 1612 ac->ac_slot = nextslot; 1613 if (!bus_dmamap_create(sc->amr_buffer_dmat, 0, &ac->ac_dmamap) && 1614 !bus_dmamap_create(sc->amr_buffer_dmat, 0, &ac->ac_ccb_dmamap)) 1615 amr_releasecmd(ac); 1616 if (++nextslot > sc->amr_maxio) 1617 break; 1618 } 1619 sc->amr_nextslot = nextslot; 1620 } 1621} 1622 1623/******************************************************************************** 1624 * Free a command cluster 1625 */ 1626static void 1627amr_freecmd_cluster(struct amr_command_cluster *acc) 1628{ 1629 struct amr_softc *sc = acc->acc_command[0].ac_sc; 1630 int i; 1631 1632 for (i = 0; i < AMR_CMD_CLUSTERCOUNT; i++) 1633 bus_dmamap_destroy(sc->amr_buffer_dmat, acc->acc_command[i].ac_dmamap); 1634 free(acc, M_DEVBUF); 1635} 1636 1637/******************************************************************************** 1638 ******************************************************************************** 1639 Interface-specific Shims 1640 ******************************************************************************** 1641 ********************************************************************************/ 1642 1643/******************************************************************************** 1644 * Tell the controller that the mailbox contains a valid command 1645 */ 1646static int 1647amr_quartz_submit_command(struct amr_softc *sc) 1648{ 1649 debug_called(3); 1650 1651 if (AMR_QGET_IDB(sc) & AMR_QIDB_SUBMIT) 1652 return(EBUSY); 1653 AMR_QPUT_IDB(sc, sc->amr_mailboxphys | AMR_QIDB_SUBMIT); 1654 return(0); 1655} 1656 1657static int 1658amr_std_submit_command(struct amr_softc *sc) 1659{ 1660 debug_called(3); 1661 1662 if (AMR_SGET_MBSTAT(sc) & AMR_SMBOX_BUSYFLAG) 1663 return(EBUSY); 1664 AMR_SPOST_COMMAND(sc); 1665 return(0); 1666} 1667 1668/******************************************************************************** 1669 * Claim any work that the controller has completed; acknowledge completion, 1670 * save details of the completion in (mbsave) 1671 */ 1672static int 1673amr_quartz_get_work(struct amr_softc *sc, struct amr_mailbox *mbsave) 1674{ 1675 int s, worked; 1676 u_int32_t outd; 1677 u_int8_t nstatus; 1678 1679 debug_called(3); 1680 1681 worked = 0; 1682 s = splbio(); 1683 1684 /* work waiting for us? */ 1685 if ((outd = AMR_QGET_ODB(sc)) == AMR_QODB_READY) { 1686 1687 /* acknowledge interrupt */ 1688 AMR_QPUT_ODB(sc, AMR_QODB_READY); 1689 1690 while ((nstatus = sc->amr_mailbox->mb_nstatus) == 0xff) 1691 ; 1692 sc->amr_mailbox->mb_nstatus = 0xff; 1693 1694 /* save mailbox, which contains a list of completed commands */ 1695 bcopy((void *)(uintptr_t)(volatile void *)sc->amr_mailbox, mbsave, sizeof(*mbsave)); 1696 mbsave->mb_nstatus = nstatus; 1697 1698 /* acknowledge that we have the commands */ 1699 AMR_QPUT_IDB(sc, AMR_QIDB_ACK); 1700 1701#ifndef AMR_QUARTZ_GOFASTER 1702 /* 1703 * This waits for the controller to notice that we've taken the 1704 * command from it. It's very inefficient, and we shouldn't do it, 1705 * but if we remove this code, we stop completing commands under 1706 * load. 1707 * 1708 * Peter J says we shouldn't do this. The documentation says we 1709 * should. Who is right? 1710 */ 1711 while(AMR_QGET_IDB(sc) & AMR_QIDB_ACK) 1712 ; /* XXX aiee! what if it dies? */ 1713#endif 1714 1715 worked = 1; /* got some work */ 1716 } 1717 1718 splx(s); 1719 return(worked); 1720} 1721 1722static int 1723amr_std_get_work(struct amr_softc *sc, struct amr_mailbox *mbsave) 1724{ 1725 int s, worked; 1726 u_int8_t istat; 1727 1728 debug_called(3); 1729 1730 worked = 0; 1731 s = splbio(); 1732 1733 /* check for valid interrupt status */ 1734 istat = AMR_SGET_ISTAT(sc); 1735 if ((istat & AMR_SINTR_VALID) != 0) { 1736 AMR_SPUT_ISTAT(sc, istat); /* ack interrupt status */ 1737 1738 /* save mailbox, which contains a list of completed commands */ 1739 bcopy((void *)(uintptr_t)(volatile void *)sc->amr_mailbox, mbsave, sizeof(*mbsave)); 1740 1741 AMR_SACK_INTERRUPT(sc); /* acknowledge we have the mailbox */ 1742 worked = 1; 1743 } 1744 1745 splx(s); 1746 return(worked); 1747} 1748 1749/******************************************************************************** 1750 * Notify the controller of the mailbox location. 1751 */ 1752static void 1753amr_std_attach_mailbox(struct amr_softc *sc) 1754{ 1755 1756 /* program the mailbox physical address */ 1757 AMR_SBYTE_SET(sc, AMR_SMBOX_0, sc->amr_mailboxphys & 0xff); 1758 AMR_SBYTE_SET(sc, AMR_SMBOX_1, (sc->amr_mailboxphys >> 8) & 0xff); 1759 AMR_SBYTE_SET(sc, AMR_SMBOX_2, (sc->amr_mailboxphys >> 16) & 0xff); 1760 AMR_SBYTE_SET(sc, AMR_SMBOX_3, (sc->amr_mailboxphys >> 24) & 0xff); 1761 AMR_SBYTE_SET(sc, AMR_SMBOX_ENABLE, AMR_SMBOX_ADDR); 1762 1763 /* clear any outstanding interrupt and enable interrupts proper */ 1764 AMR_SACK_INTERRUPT(sc); 1765 AMR_SENABLE_INTR(sc); 1766} 1767 1768#ifdef AMR_BOARD_INIT 1769/******************************************************************************** 1770 * Initialise the controller 1771 */ 1772static int 1773amr_quartz_init(struct amr_softc *sc) 1774{ 1775 int status, ostatus; 1776 1777 device_printf(sc->amr_dev, "initial init status %x\n", AMR_QGET_INITSTATUS(sc)); 1778 1779 AMR_QRESET(sc); 1780 1781 ostatus = 0xff; 1782 while ((status = AMR_QGET_INITSTATUS(sc)) != AMR_QINIT_DONE) { 1783 if (status != ostatus) { 1784 device_printf(sc->amr_dev, "(%x) %s\n", status, amr_describe_code(amr_table_qinit, status)); 1785 ostatus = status; 1786 } 1787 switch (status) { 1788 case AMR_QINIT_NOMEM: 1789 return(ENOMEM); 1790 1791 case AMR_QINIT_SCAN: 1792 /* XXX we could print channel/target here */ 1793 break; 1794 } 1795 } 1796 return(0); 1797} 1798 1799static int 1800amr_std_init(struct amr_softc *sc) 1801{ 1802 int status, ostatus; 1803 1804 device_printf(sc->amr_dev, "initial init status %x\n", AMR_SGET_INITSTATUS(sc)); 1805 1806 AMR_SRESET(sc); 1807 1808 ostatus = 0xff; 1809 while ((status = AMR_SGET_INITSTATUS(sc)) != AMR_SINIT_DONE) { 1810 if (status != ostatus) { 1811 device_printf(sc->amr_dev, "(%x) %s\n", status, amr_describe_code(amr_table_sinit, status)); 1812 ostatus = status; 1813 } 1814 switch (status) { 1815 case AMR_SINIT_NOMEM: 1816 return(ENOMEM); 1817 1818 case AMR_SINIT_INPROG: 1819 /* XXX we could print channel/target here? */ 1820 break; 1821 } 1822 } 1823 return(0); 1824} 1825#endif 1826 1827/******************************************************************************** 1828 ******************************************************************************** 1829 Debugging 1830 ******************************************************************************** 1831 ********************************************************************************/ 1832 1833/******************************************************************************** 1834 * Identify the controller and print some information about it. 1835 */ 1836static void 1837amr_describe_controller(struct amr_softc *sc) 1838{ 1839 struct amr_prodinfo *ap; 1840 struct amr_enquiry *ae; 1841 char *prod; 1842 1843 mtx_lock(&sc->amr_io_lock); 1844 /* 1845 * Try to get 40LD product info, which tells us what the card is labelled as. 1846 */ 1847 if ((ap = amr_enquiry(sc, 2048, AMR_CMD_CONFIG, AMR_CONFIG_PRODUCT_INFO, 0)) != NULL) { 1848 device_printf(sc->amr_dev, "<LSILogic %.80s> Firmware %.16s, BIOS %.16s, %dMB RAM\n", 1849 ap->ap_product, ap->ap_firmware, ap->ap_bios, 1850 ap->ap_memsize); 1851 1852 free(ap, M_DEVBUF); 1853 mtx_unlock(&sc->amr_io_lock); 1854 return; 1855 } 1856 1857 /* 1858 * Try 8LD extended ENQUIRY to get controller signature, and use lookup table. 1859 */ 1860 if ((ae = (struct amr_enquiry *)amr_enquiry(sc, 2048, AMR_CMD_EXT_ENQUIRY2, 0, 0)) != NULL) { 1861 prod = amr_describe_code(amr_table_adaptertype, ae->ae_signature); 1862 1863 } else if ((ae = (struct amr_enquiry *)amr_enquiry(sc, 2048, AMR_CMD_ENQUIRY, 0, 0)) != NULL) { 1864 1865 /* 1866 * Try to work it out based on the PCI signatures. 1867 */ 1868 switch (pci_get_device(sc->amr_dev)) { 1869 case 0x9010: 1870 prod = "Series 428"; 1871 break; 1872 case 0x9060: 1873 prod = "Series 434"; 1874 break; 1875 default: 1876 prod = "unknown controller"; 1877 break; 1878 } 1879 } else { 1880 prod = "unsupported controller"; 1881 } 1882 1883 /* 1884 * HP NetRaid controllers have a special encoding of the firmware and 1885 * BIOS versions. The AMI version seems to have it as strings whereas 1886 * the HP version does it with a leading uppercase character and two 1887 * binary numbers. 1888 */ 1889 1890 if(ae->ae_adapter.aa_firmware[2] >= 'A' && 1891 ae->ae_adapter.aa_firmware[2] <= 'Z' && 1892 ae->ae_adapter.aa_firmware[1] < ' ' && 1893 ae->ae_adapter.aa_firmware[0] < ' ' && 1894 ae->ae_adapter.aa_bios[2] >= 'A' && 1895 ae->ae_adapter.aa_bios[2] <= 'Z' && 1896 ae->ae_adapter.aa_bios[1] < ' ' && 1897 ae->ae_adapter.aa_bios[0] < ' ') { 1898 1899 /* this looks like we have an HP NetRaid version of the MegaRaid */ 1900 1901 if(ae->ae_signature == AMR_SIG_438) { 1902 /* the AMI 438 is a NetRaid 3si in HP-land */ 1903 prod = "HP NetRaid 3si"; 1904 } 1905 1906 device_printf(sc->amr_dev, "<%s> Firmware %c.%02d.%02d, BIOS %c.%02d.%02d, %dMB RAM\n", 1907 prod, ae->ae_adapter.aa_firmware[2], 1908 ae->ae_adapter.aa_firmware[1], 1909 ae->ae_adapter.aa_firmware[0], 1910 ae->ae_adapter.aa_bios[2], 1911 ae->ae_adapter.aa_bios[1], 1912 ae->ae_adapter.aa_bios[0], 1913 ae->ae_adapter.aa_memorysize); 1914 } else { 1915 device_printf(sc->amr_dev, "<%s> Firmware %.4s, BIOS %.4s, %dMB RAM\n", 1916 prod, ae->ae_adapter.aa_firmware, ae->ae_adapter.aa_bios, 1917 ae->ae_adapter.aa_memorysize); 1918 } 1919 free(ae, M_DEVBUF); 1920 mtx_unlock(&sc->amr_io_lock); 1921} 1922 1923int 1924amr_dump_blocks(struct amr_softc *sc, int unit, u_int32_t lba, void *data, int blks) 1925{ 1926 struct amr_command *ac; 1927 int error = EIO; 1928 1929 debug_called(1); 1930
|
1927 sc->amr_state |= AMR_STATE_CRASHDUMP;
|
1931 sc->amr_state |= AMR_STATE_INTEN; |
1932 1933 /* get ourselves a command buffer */ 1934 if ((ac = amr_alloccmd(sc)) == NULL) 1935 goto out; 1936 /* set command flags */ 1937 ac->ac_flags |= AMR_CMD_PRIORITY | AMR_CMD_DATAOUT; 1938 1939 /* point the command at our data */ 1940 ac->ac_data = data; 1941 ac->ac_length = blks * AMR_BLKSIZE; 1942 1943 /* build the command proper */ 1944 ac->ac_mailbox.mb_command = AMR_CMD_LWRITE; 1945 ac->ac_mailbox.mb_blkcount = blks; 1946 ac->ac_mailbox.mb_lba = lba; 1947 ac->ac_mailbox.mb_drive = unit; 1948 1949 /* can't assume that interrupts are going to work here, so play it safe */ 1950 if (sc->amr_poll_command(ac)) 1951 goto out; 1952 error = ac->ac_status; 1953 1954 out: 1955 if (ac != NULL) 1956 amr_releasecmd(ac); 1957
|
1954 sc->amr_state &= ~AMR_STATE_CRASHDUMP;
|
1958 sc->amr_state &= ~AMR_STATE_INTEN; |
1959 return (error); 1960} 1961 1962 1963 1964#ifdef AMR_DEBUG 1965/******************************************************************************** 1966 * Print the command (ac) in human-readable format 1967 */ 1968#if 0 1969static void 1970amr_printcommand(struct amr_command *ac) 1971{ 1972 struct amr_softc *sc = ac->ac_sc; 1973 struct amr_sgentry *sg; 1974 int i; 1975 1976 device_printf(sc->amr_dev, "cmd %x ident %d drive %d\n", 1977 ac->ac_mailbox.mb_command, ac->ac_mailbox.mb_ident, ac->ac_mailbox.mb_drive); 1978 device_printf(sc->amr_dev, "blkcount %d lba %d\n", 1979 ac->ac_mailbox.mb_blkcount, ac->ac_mailbox.mb_lba); 1980 device_printf(sc->amr_dev, "virtaddr %p length %lu\n", ac->ac_data, (unsigned long)ac->ac_length); 1981 device_printf(sc->amr_dev, "sg physaddr %08x nsg %d\n", 1982 ac->ac_mailbox.mb_physaddr, ac->ac_mailbox.mb_nsgelem); 1983 device_printf(sc->amr_dev, "ccb %p bio %p\n", ac->ac_ccb_data, ac->ac_bio); 1984 1985 /* get base address of s/g table */ 1986 sg = sc->amr_sgtable + (ac->ac_slot * AMR_NSEG); 1987 for (i = 0; i < ac->ac_mailbox.mb_nsgelem; i++, sg++) 1988 device_printf(sc->amr_dev, " %x/%d\n", sg->sg_addr, sg->sg_count); 1989} 1990#endif 1991#endif
|