1 /* 2 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 3 * Use is subject to license terms. 4 * Copyright (c) 2011 Bayard G. Bell. All rights reserved. 5 */ 6 /* 7 * Copyright (c) 1999,2000 Michael Smith 8 * Copyright (c) 2000 BSDi 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 */ 32 /* 33 * Copyright (c) 2002 Eric Moore 34 * Copyright (c) 2002 LSI Logic Corporation 35 * All rights reserved. 36 * 37 * Redistribution and use in source and binary forms, with or without 38 * modification, are permitted provided that the following conditions 39 * are met: 40 * 1. Redistributions of source code must retain the above copyright 41 * notice, this list of conditions and the following disclaimer. 42 * 2. Redistributions in binary form must reproduce the above copyright 43 * notice, this list of conditions and the following disclaimer in the 44 * documentation and/or other materials provided with the distribution. 45 * 3. The party using or redistributing the source code and binary forms 46 * agrees to the disclaimer below and the terms and conditions set forth 47 * herein. 48 * 49 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 50 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 51 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 52 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 53 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 54 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 55 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 56 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 57 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 58 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 59 * SUCH DAMAGE. 60 */ 61 62 #include <sys/int_types.h> 63 #include <sys/scsi/scsi.h> 64 #include <sys/dkbad.h> 65 #include <sys/dklabel.h> 66 #include <sys/dkio.h> 67 #include <sys/cdio.h> 68 #include <sys/mhd.h> 69 #include <sys/vtoc.h> 70 #include <sys/dktp/fdisk.h> 71 #include <sys/scsi/targets/sddef.h> 72 #include <sys/debug.h> 73 #include <sys/pci.h> 74 #include <sys/ksynch.h> 75 #include <sys/ddi.h> 76 #include <sys/sunddi.h> 77 #include <sys/modctl.h> 78 #include <sys/byteorder.h> 79 80 #include "amrreg.h" 81 #include "amrvar.h" 82 83 /* dynamic debug symbol */ 84 int amr_debug_var = 0; 85 86 #define AMR_DELAY(cond, count, done_flag) { \ 87 int local_counter = 0; \ 88 done_flag = 1; \ 89 while (!(cond)) { \ 90 delay(drv_usectohz(100)); \ 91 if ((local_counter) > count) { \ 92 done_flag = 0; \ 93 break; \ 94 } \ 95 (local_counter)++; \ 96 } \ 97 } 98 99 #define AMR_BUSYWAIT(cond, count, done_flag) { \ 100 int local_counter = 0; \ 101 done_flag = 1; \ 102 while (!(cond)) { \ 103 drv_usecwait(100); \ 104 if ((local_counter) > count) { \ 105 done_flag = 0; \ 106 break; \ 107 } \ 108 (local_counter)++; \ 109 } \ 110 } 111 112 /* 113 * driver interfaces 114 */ 115 116 static uint_t amr_intr(caddr_t arg); 117 static void amr_done(struct amr_softs *softs); 118 119 static int amr_info(dev_info_t *dip, ddi_info_cmd_t infocmd, 120 void *arg, void **result); 121 static int amr_attach(dev_info_t *, ddi_attach_cmd_t); 122 static int amr_detach(dev_info_t *, ddi_detach_cmd_t); 123 124 static int amr_setup_mbox(struct amr_softs *softs); 125 static int amr_setup_sg(struct amr_softs *softs); 126 127 /* 128 * Command wrappers 129 */ 130 static int amr_query_controller(struct amr_softs *softs); 131 static void *amr_enquiry(struct amr_softs *softs, size_t bufsize, 132 uint8_t cmd, uint8_t cmdsub, uint8_t cmdqual); 133 static int amr_flush(struct amr_softs *softs); 134 135 /* 136 * Command processing. 137 */ 138 static void amr_rw_command(struct amr_softs *softs, 139 struct scsi_pkt *pkt, int lun); 140 static void amr_mode_sense(union scsi_cdb *cdbp, struct buf *bp, 141 unsigned int capacity); 142 static void amr_set_arq_data(struct scsi_pkt *pkt, uchar_t key); 143 static int amr_enquiry_mapcmd(struct amr_command *ac, uint32_t data_size); 144 static void amr_enquiry_unmapcmd(struct amr_command *ac); 145 static int amr_mapcmd(struct amr_command *ac, int (*callback)(), caddr_t arg); 146 static void amr_unmapcmd(struct amr_command *ac); 147 148 /* 149 * Status monitoring 150 */ 151 static void amr_periodic(void *data); 152 153 /* 154 * Interface-specific shims 155 */ 156 static int amr_poll_command(struct amr_command *ac); 157 static void amr_start_waiting_queue(void *softp); 158 static void amr_call_pkt_comp(struct amr_command *head); 159 160 /* 161 * SCSI interface 162 */ 163 static int amr_setup_tran(dev_info_t *dip, struct amr_softs *softp); 164 165 /* 166 * Function prototypes 167 * 168 * SCSA functions exported by means of the transport table 169 */ 170 static int amr_tran_tgt_init(dev_info_t *hba_dip, dev_info_t *tgt_dip, 171 scsi_hba_tran_t *tran, struct scsi_device *sd); 172 static int amr_tran_start(struct scsi_address *ap, struct scsi_pkt *pkt); 173 static int amr_tran_reset(struct scsi_address *ap, int level); 174 static int amr_tran_getcap(struct scsi_address *ap, char *cap, int whom); 175 static int amr_tran_setcap(struct scsi_address *ap, char *cap, int value, 176 int whom); 177 static struct scsi_pkt *amr_tran_init_pkt(struct scsi_address *ap, 178 struct scsi_pkt *pkt, struct buf *bp, int cmdlen, int statuslen, 179 int tgtlen, int flags, int (*callback)(), caddr_t arg); 180 static void amr_tran_destroy_pkt(struct scsi_address *ap, struct scsi_pkt *pkt); 181 static void amr_tran_dmafree(struct scsi_address *ap, struct scsi_pkt *pkt); 182 static void amr_tran_sync_pkt(struct scsi_address *ap, struct scsi_pkt *pkt); 183 184 static ddi_dma_attr_t buffer_dma_attr = { 185 DMA_ATTR_V0, /* version of this structure */ 186 0, /* lowest usable address */ 187 0xffffffffull, /* highest usable address */ 188 0x00ffffffull, /* maximum DMAable byte count */ 189 4, /* alignment */ 190 1, /* burst sizes */ 191 1, /* minimum transfer */ 192 0xffffffffull, /* maximum transfer */ 193 0xffffffffull, /* maximum segment length */ 194 AMR_NSEG, /* maximum number of segments */ 195 AMR_BLKSIZE, /* granularity */ 196 0, /* flags (reserved) */ 197 }; 198 199 static ddi_dma_attr_t addr_dma_attr = { 200 DMA_ATTR_V0, /* version of this structure */ 201 0, /* lowest usable address */ 202 0xffffffffull, /* highest usable address */ 203 0x7fffffff, /* maximum DMAable byte count */ 204 4, /* alignment */ 205 1, /* burst sizes */ 206 1, /* minimum transfer */ 207 0xffffffffull, /* maximum transfer */ 208 0xffffffffull, /* maximum segment length */ 209 1, /* maximum number of segments */ 210 1, /* granularity */ 211 0, /* flags (reserved) */ 212 }; 213 214 215 static struct dev_ops amr_ops = { 216 DEVO_REV, /* devo_rev, */ 217 0, /* refcnt */ 218 amr_info, /* info */ 219 nulldev, /* identify */ 220 nulldev, /* probe */ 221 amr_attach, /* attach */ 222 amr_detach, /* detach */ 223 nodev, /* reset */ 224 NULL, /* driver operations */ 225 (struct bus_ops *)0, /* bus operations */ 226 0, /* power */ 227 ddi_quiesce_not_supported, /* devo_quiesce */ 228 }; 229 230 231 extern struct mod_ops mod_driverops; 232 static struct modldrv modldrv = { 233 &mod_driverops, /* Type of module. driver here */ 234 "AMR Driver", /* Name of the module. */ 235 &amr_ops, /* Driver ops vector */ 236 }; 237 238 static struct modlinkage modlinkage = { 239 MODREV_1, 240 { &modldrv, NULL } 241 }; 242 243 /* DMA access attributes */ 244 static ddi_device_acc_attr_t accattr = { 245 DDI_DEVICE_ATTR_V0, 246 DDI_NEVERSWAP_ACC, 247 DDI_STRICTORDER_ACC 248 }; 249 250 static struct amr_softs *amr_softstatep; 251 252 253 int 254 _init(void) 255 { 256 int error; 257 258 error = ddi_soft_state_init((void *)&amr_softstatep, 259 sizeof (struct amr_softs), 0); 260 261 if (error != 0) 262 goto error_out; 263 264 if ((error = scsi_hba_init(&modlinkage)) != 0) { 265 ddi_soft_state_fini((void*)&amr_softstatep); 266 goto error_out; 267 } 268 269 error = mod_install(&modlinkage); 270 if (error != 0) { 271 scsi_hba_fini(&modlinkage); 272 ddi_soft_state_fini((void*)&amr_softstatep); 273 goto error_out; 274 } 275 276 return (error); 277 278 error_out: 279 cmn_err(CE_NOTE, "_init failed"); 280 return (error); 281 } 282 283 int 284 _info(struct modinfo *modinfop) 285 { 286 return (mod_info(&modlinkage, modinfop)); 287 } 288 289 int 290 _fini(void) 291 { 292 int error; 293 294 if ((error = mod_remove(&modlinkage)) != 0) { 295 return (error); 296 } 297 298 scsi_hba_fini(&modlinkage); 299 300 ddi_soft_state_fini((void*)&amr_softstatep); 301 return (error); 302 } 303 304 305 static int 306 amr_attach(dev_info_t *dev, ddi_attach_cmd_t cmd) 307 { 308 struct amr_softs *softs; 309 int error; 310 uint32_t command, i; 311 int instance; 312 caddr_t cfgaddr; 313 314 instance = ddi_get_instance(dev); 315 316 switch (cmd) { 317 case DDI_ATTACH: 318 break; 319 320 case DDI_RESUME: 321 return (DDI_FAILURE); 322 323 default: 324 return (DDI_FAILURE); 325 } 326 327 /* 328 * Initialize softs. 329 */ 330 if (ddi_soft_state_zalloc(amr_softstatep, instance) != DDI_SUCCESS) 331 return (DDI_FAILURE); 332 softs = ddi_get_soft_state(amr_softstatep, instance); 333 softs->state |= AMR_STATE_SOFT_STATE_SETUP; 334 335 softs->dev_info_p = dev; 336 337 AMRDB_PRINT((CE_NOTE, "softs: %p; busy_slot addr: %p", 338 (void *)softs, (void *)&(softs->amr_busyslots))); 339 340 if (pci_config_setup(dev, &(softs->pciconfig_handle)) 341 != DDI_SUCCESS) { 342 goto error_out; 343 } 344 softs->state |= AMR_STATE_PCI_CONFIG_SETUP; 345 346 error = ddi_regs_map_setup(dev, 1, &cfgaddr, 0, 0, 347 &accattr, &(softs->regsmap_handle)); 348 if (error != DDI_SUCCESS) { 349 goto error_out; 350 } 351 softs->state |= AMR_STATE_PCI_MEM_MAPPED; 352 353 /* 354 * Determine board type. 355 */ 356 command = pci_config_get16(softs->pciconfig_handle, PCI_CONF_COMM); 357 358 /* 359 * Make sure we are going to be able to talk to this board. 360 */ 361 if ((command & PCI_COMM_MAE) == 0) { 362 AMRDB_PRINT((CE_NOTE, "memory window not available")); 363 goto error_out; 364 } 365 366 /* force the busmaster enable bit on */ 367 if (!(command & PCI_COMM_ME)) { 368 command |= PCI_COMM_ME; 369 pci_config_put16(softs->pciconfig_handle, 370 PCI_CONF_COMM, command); 371 command = pci_config_get16(softs->pciconfig_handle, 372 PCI_CONF_COMM); 373 if (!(command & PCI_COMM_ME)) 374 goto error_out; 375 } 376 377 /* 378 * Allocate and connect our interrupt. 379 */ 380 if (ddi_intr_hilevel(dev, 0) != 0) { 381 AMRDB_PRINT((CE_NOTE, 382 "High level interrupt is not supported!")); 383 goto error_out; 384 } 385 386 if (ddi_get_iblock_cookie(dev, 0, &softs->iblock_cookiep) 387 != DDI_SUCCESS) { 388 goto error_out; 389 } 390 391 mutex_init(&softs->cmd_mutex, NULL, MUTEX_DRIVER, 392 softs->iblock_cookiep); /* should be used in interrupt */ 393 mutex_init(&softs->queue_mutex, NULL, MUTEX_DRIVER, 394 softs->iblock_cookiep); /* should be used in interrupt */ 395 mutex_init(&softs->periodic_mutex, NULL, MUTEX_DRIVER, 396 softs->iblock_cookiep); /* should be used in interrupt */ 397 /* sychronize waits for the busy slots via this cv */ 398 cv_init(&softs->cmd_cv, NULL, CV_DRIVER, NULL); 399 softs->state |= AMR_STATE_KMUTEX_INITED; 400 401 /* 402 * Do bus-independent initialisation, bring controller online. 403 */ 404 if (amr_setup_mbox(softs) != DDI_SUCCESS) 405 goto error_out; 406 softs->state |= AMR_STATE_MAILBOX_SETUP; 407 408 if (amr_setup_sg(softs) != DDI_SUCCESS) 409 goto error_out; 410 411 softs->state |= AMR_STATE_SG_TABLES_SETUP; 412 413 if (amr_query_controller(softs) != DDI_SUCCESS) 414 goto error_out; 415 416 /* 417 * A taskq is created for dispatching the waiting queue processing 418 * thread. The threads number equals to the logic drive number and 419 * the thread number should be 1 if there is no logic driver is 420 * configured for this instance. 421 */ 422 if ((softs->amr_taskq = ddi_taskq_create(dev, "amr_taskq", 423 MAX(softs->amr_nlogdrives, 1), TASKQ_DEFAULTPRI, 0)) == NULL) { 424 goto error_out; 425 } 426 softs->state |= AMR_STATE_TASKQ_SETUP; 427 428 if (ddi_add_intr(dev, 0, &softs->iblock_cookiep, NULL, 429 amr_intr, (caddr_t)softs) != DDI_SUCCESS) { 430 goto error_out; 431 } 432 softs->state |= AMR_STATE_INTR_SETUP; 433 434 /* set up the tran interface */ 435 if (amr_setup_tran(softs->dev_info_p, softs) != DDI_SUCCESS) { 436 AMRDB_PRINT((CE_NOTE, "setup tran failed")); 437 goto error_out; 438 } 439 softs->state |= AMR_STATE_TRAN_SETUP; 440 441 /* schedule a thread for periodic check */ 442 mutex_enter(&softs->periodic_mutex); 443 softs->timeout_t = timeout(amr_periodic, (void *)softs, 444 drv_usectohz(500000*AMR_PERIODIC_TIMEOUT)); 445 softs->state |= AMR_STATE_TIMEOUT_ENABLED; 446 mutex_exit(&softs->periodic_mutex); 447 448 /* print firmware information in verbose mode */ 449 cmn_err(CE_CONT, "?MegaRaid %s %s attached.", 450 softs->amr_product_info.pi_product_name, 451 softs->amr_product_info.pi_firmware_ver); 452 453 /* clear any interrupts */ 454 AMR_QCLEAR_INTR(softs); 455 return (DDI_SUCCESS); 456 457 error_out: 458 if (softs->state & AMR_STATE_INTR_SETUP) { 459 ddi_remove_intr(dev, 0, softs->iblock_cookiep); 460 } 461 if (softs->state & AMR_STATE_TASKQ_SETUP) { 462 ddi_taskq_destroy(softs->amr_taskq); 463 } 464 if (softs->state & AMR_STATE_SG_TABLES_SETUP) { 465 for (i = 0; i < softs->sg_max_count; i++) { 466 (void) ddi_dma_unbind_handle( 467 softs->sg_items[i].sg_handle); 468 (void) ddi_dma_mem_free( 469 &((softs->sg_items[i]).sg_acc_handle)); 470 (void) ddi_dma_free_handle( 471 &(softs->sg_items[i].sg_handle)); 472 } 473 } 474 if (softs->state & AMR_STATE_MAILBOX_SETUP) { 475 (void) ddi_dma_unbind_handle(softs->mbox_dma_handle); 476 (void) ddi_dma_mem_free(&softs->mbox_acc_handle); 477 (void) ddi_dma_free_handle(&softs->mbox_dma_handle); 478 } 479 if (softs->state & AMR_STATE_KMUTEX_INITED) { 480 mutex_destroy(&softs->queue_mutex); 481 mutex_destroy(&softs->cmd_mutex); 482 mutex_destroy(&softs->periodic_mutex); 483 cv_destroy(&softs->cmd_cv); 484 } 485 if (softs->state & AMR_STATE_PCI_MEM_MAPPED) 486 ddi_regs_map_free(&softs->regsmap_handle); 487 if (softs->state & AMR_STATE_PCI_CONFIG_SETUP) 488 pci_config_teardown(&softs->pciconfig_handle); 489 if (softs->state & AMR_STATE_SOFT_STATE_SETUP) 490 ddi_soft_state_free(amr_softstatep, instance); 491 return (DDI_FAILURE); 492 } 493 494 /* 495 * Bring the controller down to a dormant state and detach all child devices. 496 * This function is called during detach, system shutdown. 497 * 498 * Note that we can assume that the bufq on the controller is empty, as we won't 499 * allow shutdown if any device is open. 500 */ 501 /*ARGSUSED*/ 502 static int amr_detach(dev_info_t *dev, ddi_detach_cmd_t cmd) 503 { 504 struct amr_softs *softs; 505 int instance; 506 uint32_t i, done_flag; 507 508 instance = ddi_get_instance(dev); 509 softs = ddi_get_soft_state(amr_softstatep, instance); 510 511 /* flush the controllor */ 512 if (amr_flush(softs) != 0) { 513 AMRDB_PRINT((CE_NOTE, "device shutdown failed")); 514 return (EIO); 515 } 516 517 /* release the amr timer */ 518 mutex_enter(&softs->periodic_mutex); 519 softs->state &= ~AMR_STATE_TIMEOUT_ENABLED; 520 if (softs->timeout_t) { 521 (void) untimeout(softs->timeout_t); 522 softs->timeout_t = 0; 523 } 524 mutex_exit(&softs->periodic_mutex); 525 526 for (i = 0; i < softs->sg_max_count; i++) { 527 (void) ddi_dma_unbind_handle( 528 softs->sg_items[i].sg_handle); 529 (void) ddi_dma_mem_free( 530 &((softs->sg_items[i]).sg_acc_handle)); 531 (void) ddi_dma_free_handle( 532 &(softs->sg_items[i].sg_handle)); 533 } 534 535 (void) ddi_dma_unbind_handle(softs->mbox_dma_handle); 536 (void) ddi_dma_mem_free(&softs->mbox_acc_handle); 537 (void) ddi_dma_free_handle(&softs->mbox_dma_handle); 538 539 /* disconnect the interrupt handler */ 540 ddi_remove_intr(softs->dev_info_p, 0, softs->iblock_cookiep); 541 542 /* wait for the completion of current in-progress interruptes */ 543 AMR_DELAY((softs->amr_interrupts_counter == 0), 1000, done_flag); 544 if (!done_flag) { 545 cmn_err(CE_WARN, "Suspicious interrupts in-progress."); 546 } 547 548 ddi_taskq_destroy(softs->amr_taskq); 549 550 (void) scsi_hba_detach(dev); 551 scsi_hba_tran_free(softs->hba_tran); 552 ddi_regs_map_free(&softs->regsmap_handle); 553 pci_config_teardown(&softs->pciconfig_handle); 554 555 mutex_destroy(&softs->queue_mutex); 556 mutex_destroy(&softs->cmd_mutex); 557 mutex_destroy(&softs->periodic_mutex); 558 cv_destroy(&softs->cmd_cv); 559 560 /* print firmware information in verbose mode */ 561 cmn_err(CE_NOTE, "?MegaRaid %s %s detached.", 562 softs->amr_product_info.pi_product_name, 563 softs->amr_product_info.pi_firmware_ver); 564 565 ddi_soft_state_free(amr_softstatep, instance); 566 567 return (DDI_SUCCESS); 568 } 569 570 571 /*ARGSUSED*/ 572 static int amr_info(dev_info_t *dip, ddi_info_cmd_t infocmd, 573 void *arg, void **result) 574 { 575 struct amr_softs *softs; 576 int instance; 577 578 instance = ddi_get_instance(dip); 579 580 switch (infocmd) { 581 case DDI_INFO_DEVT2DEVINFO: 582 softs = ddi_get_soft_state(amr_softstatep, instance); 583 if (softs != NULL) { 584 *result = softs->dev_info_p; 585 return (DDI_SUCCESS); 586 } else { 587 *result = NULL; 588 return (DDI_FAILURE); 589 } 590 case DDI_INFO_DEVT2INSTANCE: 591 *(int *)result = instance; 592 break; 593 default: 594 break; 595 } 596 return (DDI_SUCCESS); 597 } 598 599 /* 600 * Take an interrupt, or be poked by other code to look for interrupt-worthy 601 * status. 602 */ 603 static uint_t 604 amr_intr(caddr_t arg) 605 { 606 struct amr_softs *softs = (struct amr_softs *)arg; 607 608 softs->amr_interrupts_counter++; 609 610 if (AMR_QGET_ODB(softs) != AMR_QODB_READY) { 611 softs->amr_interrupts_counter--; 612 return (DDI_INTR_UNCLAIMED); 613 } 614 615 /* collect finished commands, queue anything waiting */ 616 amr_done(softs); 617 618 softs->amr_interrupts_counter--; 619 620 return (DDI_INTR_CLAIMED); 621 622 } 623 624 /* 625 * Setup the amr mailbox 626 */ 627 static int 628 amr_setup_mbox(struct amr_softs *softs) 629 { 630 uint32_t move; 631 size_t mbox_len; 632 633 if (ddi_dma_alloc_handle( 634 softs->dev_info_p, 635 &addr_dma_attr, 636 DDI_DMA_SLEEP, 637 NULL, 638 &softs->mbox_dma_handle) != DDI_SUCCESS) { 639 AMRDB_PRINT((CE_NOTE, "Cannot alloc dma handle for mailbox")); 640 goto error_out; 641 } 642 643 if (ddi_dma_mem_alloc( 644 softs->mbox_dma_handle, 645 sizeof (struct amr_mailbox) + 16, 646 &accattr, 647 DDI_DMA_RDWR | DDI_DMA_CONSISTENT, 648 DDI_DMA_SLEEP, 649 NULL, 650 (caddr_t *)(&softs->mbox), 651 &mbox_len, 652 &softs->mbox_acc_handle) != 653 DDI_SUCCESS) { 654 655 AMRDB_PRINT((CE_WARN, "Cannot alloc dma memory for mailbox")); 656 goto error_out; 657 } 658 659 if (ddi_dma_addr_bind_handle( 660 softs->mbox_dma_handle, 661 NULL, 662 (caddr_t)softs->mbox, 663 mbox_len, 664 DDI_DMA_RDWR | DDI_DMA_CONSISTENT, 665 DDI_DMA_SLEEP, 666 NULL, 667 &softs->mbox_dma_cookie, 668 &softs->mbox_dma_cookien) != DDI_DMA_MAPPED) { 669 670 AMRDB_PRINT((CE_NOTE, "Cannot bind dma memory for mailbox")); 671 goto error_out; 672 } 673 674 if (softs->mbox_dma_cookien != 1) 675 goto error_out; 676 677 /* The phy address of mailbox must be aligned on a 16-byte boundary */ 678 move = 16 - (((uint32_t)softs->mbox_dma_cookie.dmac_address)&0xf); 679 softs->mbox_phyaddr = 680 (softs->mbox_dma_cookie.dmac_address + move); 681 682 softs->mailbox = 683 (struct amr_mailbox *)(((uintptr_t)softs->mbox) + move); 684 685 AMRDB_PRINT((CE_NOTE, "phraddy=%x, mailbox=%p, softs->mbox=%p, move=%x", 686 softs->mbox_phyaddr, (void *)softs->mailbox, 687 softs->mbox, move)); 688 689 return (DDI_SUCCESS); 690 691 error_out: 692 if (softs->mbox_dma_cookien) 693 (void) ddi_dma_unbind_handle(softs->mbox_dma_handle); 694 if (softs->mbox_acc_handle) { 695 (void) ddi_dma_mem_free(&(softs->mbox_acc_handle)); 696 softs->mbox_acc_handle = NULL; 697 } 698 if (softs->mbox_dma_handle) { 699 (void) ddi_dma_free_handle(&softs->mbox_dma_handle); 700 softs->mbox_dma_handle = NULL; 701 } 702 703 return (DDI_FAILURE); 704 } 705 706 /* 707 * Perform a periodic check of the controller status 708 */ 709 static void 710 amr_periodic(void *data) 711 { 712 uint32_t i; 713 struct amr_softs *softs = (struct amr_softs *)data; 714 struct scsi_pkt *pkt; 715 register struct amr_command *ac; 716 717 for (i = 0; i < softs->sg_max_count; i++) { 718 if (softs->busycmd[i] == NULL) 719 continue; 720 721 mutex_enter(&softs->cmd_mutex); 722 723 if (softs->busycmd[i] == NULL) { 724 mutex_exit(&softs->cmd_mutex); 725 continue; 726 } 727 728 pkt = softs->busycmd[i]->pkt; 729 730 if ((pkt->pkt_time != 0) && 731 (ddi_get_time() - 732 softs->busycmd[i]->ac_timestamp > 733 pkt->pkt_time)) { 734 735 cmn_err(CE_WARN, 736 "!timed out packet detected,\ 737 sc = %p, pkt = %p, index = %d, ac = %p", 738 (void *)softs, 739 (void *)pkt, 740 i, 741 (void *)softs->busycmd[i]); 742 743 ac = softs->busycmd[i]; 744 ac->ac_next = NULL; 745 746 /* pull command from the busy index */ 747 softs->busycmd[i] = NULL; 748 if (softs->amr_busyslots > 0) 749 softs->amr_busyslots--; 750 if (softs->amr_busyslots == 0) 751 cv_broadcast(&softs->cmd_cv); 752 753 mutex_exit(&softs->cmd_mutex); 754 755 pkt = ac->pkt; 756 *pkt->pkt_scbp = 0; 757 pkt->pkt_statistics |= STAT_TIMEOUT; 758 pkt->pkt_reason = CMD_TIMEOUT; 759 if (!(pkt->pkt_flags & FLAG_NOINTR)) { 760 /* call pkt callback */ 761 scsi_hba_pkt_comp(pkt); 762 } 763 764 } else { 765 mutex_exit(&softs->cmd_mutex); 766 } 767 } 768 769 /* restart the amr timer */ 770 mutex_enter(&softs->periodic_mutex); 771 if (softs->state & AMR_STATE_TIMEOUT_ENABLED) 772 softs->timeout_t = timeout(amr_periodic, (void *)softs, 773 drv_usectohz(500000*AMR_PERIODIC_TIMEOUT)); 774 mutex_exit(&softs->periodic_mutex); 775 } 776 777 /* 778 * Interrogate the controller for the operational parameters we require. 779 */ 780 static int 781 amr_query_controller(struct amr_softs *softs) 782 { 783 struct amr_enquiry3 *aex; 784 struct amr_prodinfo *ap; 785 struct amr_enquiry *ae; 786 uint32_t ldrv; 787 int instance; 788 789 /* 790 * If we haven't found the real limit yet, let us have a couple of 791 * commands in order to be able to probe. 792 */ 793 if (softs->maxio == 0) 794 softs->maxio = 2; 795 796 instance = ddi_get_instance(softs->dev_info_p); 797 798 /* 799 * Try to issue an ENQUIRY3 command 800 */ 801 if ((aex = amr_enquiry(softs, AMR_ENQ_BUFFER_SIZE, AMR_CMD_CONFIG, 802 AMR_CONFIG_ENQ3, AMR_CONFIG_ENQ3_SOLICITED_FULL)) != NULL) { 803 804 AMRDB_PRINT((CE_NOTE, "First enquiry")); 805 806 for (ldrv = 0; ldrv < aex->ae_numldrives; ldrv++) { 807 softs->logic_drive[ldrv].al_size = 808 aex->ae_drivesize[ldrv]; 809 softs->logic_drive[ldrv].al_state = 810 aex->ae_drivestate[ldrv]; 811 softs->logic_drive[ldrv].al_properties = 812 aex->ae_driveprop[ldrv]; 813 AMRDB_PRINT((CE_NOTE, 814 " drive %d: size: %d state %x properties %x\n", 815 ldrv, 816 softs->logic_drive[ldrv].al_size, 817 softs->logic_drive[ldrv].al_state, 818 softs->logic_drive[ldrv].al_properties)); 819 820 if (softs->logic_drive[ldrv].al_state == 821 AMR_LDRV_OFFLINE) 822 cmn_err(CE_NOTE, 823 "!instance %d log-drive %d is offline", 824 instance, ldrv); 825 else 826 softs->amr_nlogdrives++; 827 } 828 kmem_free(aex, AMR_ENQ_BUFFER_SIZE); 829 830 if ((ap = amr_enquiry(softs, AMR_ENQ_BUFFER_SIZE, 831 AMR_CMD_CONFIG, AMR_CONFIG_PRODUCT_INFO, 0)) == NULL) { 832 AMRDB_PRINT((CE_NOTE, 833 "Cannot obtain product data from controller")); 834 return (EIO); 835 } 836 837 softs->maxdrives = AMR_40LD_MAXDRIVES; 838 softs->maxchan = ap->ap_nschan; 839 softs->maxio = ap->ap_maxio; 840 841 bcopy(ap->ap_firmware, softs->amr_product_info.pi_firmware_ver, 842 AMR_FIRMWARE_VER_SIZE); 843 softs->amr_product_info. 844 pi_firmware_ver[AMR_FIRMWARE_VER_SIZE] = 0; 845 846 bcopy(ap->ap_product, softs->amr_product_info.pi_product_name, 847 AMR_PRODUCT_INFO_SIZE); 848 softs->amr_product_info. 849 pi_product_name[AMR_PRODUCT_INFO_SIZE] = 0; 850 851 kmem_free(ap, AMR_ENQ_BUFFER_SIZE); 852 AMRDB_PRINT((CE_NOTE, "maxio=%d", softs->maxio)); 853 } else { 854 855 AMRDB_PRINT((CE_NOTE, "First enquiry failed, \ 856 so try another way")); 857 858 /* failed, try the 8LD ENQUIRY commands */ 859 if ((ae = (struct amr_enquiry *)amr_enquiry(softs, 860 AMR_ENQ_BUFFER_SIZE, AMR_CMD_EXT_ENQUIRY2, 0, 0)) 861 == NULL) { 862 863 if ((ae = (struct amr_enquiry *)amr_enquiry(softs, 864 AMR_ENQ_BUFFER_SIZE, AMR_CMD_ENQUIRY, 0, 0)) 865 == NULL) { 866 AMRDB_PRINT((CE_NOTE, 867 "Cannot obtain configuration data")); 868 return (EIO); 869 } 870 ae->ae_signature = 0; 871 } 872 873 /* 874 * Fetch current state of logical drives. 875 */ 876 for (ldrv = 0; ldrv < ae->ae_ldrv.al_numdrives; ldrv++) { 877 softs->logic_drive[ldrv].al_size = 878 ae->ae_ldrv.al_size[ldrv]; 879 softs->logic_drive[ldrv].al_state = 880 ae->ae_ldrv.al_state[ldrv]; 881 softs->logic_drive[ldrv].al_properties = 882 ae->ae_ldrv.al_properties[ldrv]; 883 AMRDB_PRINT((CE_NOTE, 884 " ********* drive %d: %d state %x properties %x", 885 ldrv, 886 softs->logic_drive[ldrv].al_size, 887 softs->logic_drive[ldrv].al_state, 888 softs->logic_drive[ldrv].al_properties)); 889 890 if (softs->logic_drive[ldrv].al_state == 891 AMR_LDRV_OFFLINE) 892 cmn_err(CE_NOTE, 893 "!instance %d log-drive %d is offline", 894 instance, ldrv); 895 else 896 softs->amr_nlogdrives++; 897 } 898 899 softs->maxdrives = AMR_8LD_MAXDRIVES; 900 softs->maxchan = ae->ae_adapter.aa_channels; 901 softs->maxio = ae->ae_adapter.aa_maxio; 902 kmem_free(ae, AMR_ENQ_BUFFER_SIZE); 903 } 904 905 /* 906 * Mark remaining drives as unused. 907 */ 908 for (; ldrv < AMR_MAXLD; ldrv++) 909 softs->logic_drive[ldrv].al_state = AMR_LDRV_OFFLINE; 910 911 /* 912 * Cap the maximum number of outstanding I/Os. AMI's driver 913 * doesn't trust the controller's reported value, and lockups have 914 * been seen when we do. 915 */ 916 softs->maxio = MIN(softs->maxio, AMR_LIMITCMD); 917 918 return (DDI_SUCCESS); 919 } 920 921 /* 922 * Run a generic enquiry-style command. 923 */ 924 static void * 925 amr_enquiry(struct amr_softs *softs, size_t bufsize, uint8_t cmd, 926 uint8_t cmdsub, uint8_t cmdqual) 927 { 928 struct amr_command ac; 929 void *result; 930 931 result = NULL; 932 933 bzero(&ac, sizeof (struct amr_command)); 934 ac.ac_softs = softs; 935 936 /* set command flags */ 937 ac.ac_flags |= AMR_CMD_DATAOUT; 938 939 /* build the command proper */ 940 ac.mailbox.mb_command = cmd; 941 ac.mailbox.mb_cmdsub = cmdsub; 942 ac.mailbox.mb_cmdqual = cmdqual; 943 944 if (amr_enquiry_mapcmd(&ac, bufsize) != DDI_SUCCESS) 945 return (NULL); 946 947 if (amr_poll_command(&ac) || ac.ac_status != 0) { 948 AMRDB_PRINT((CE_NOTE, "can not poll command, goto out")); 949 amr_enquiry_unmapcmd(&ac); 950 return (NULL); 951 } 952 953 /* allocate the response structure */ 954 result = kmem_zalloc(bufsize, KM_SLEEP); 955 956 bcopy(ac.ac_data, result, bufsize); 957 958 amr_enquiry_unmapcmd(&ac); 959 return (result); 960 } 961 962 /* 963 * Flush the controller's internal cache, return status. 964 */ 965 static int 966 amr_flush(struct amr_softs *softs) 967 { 968 struct amr_command ac; 969 int error = 0; 970 971 bzero(&ac, sizeof (struct amr_command)); 972 ac.ac_softs = softs; 973 974 ac.ac_flags |= AMR_CMD_DATAOUT; 975 976 /* build the command proper */ 977 ac.mailbox.mb_command = AMR_CMD_FLUSH; 978 979 /* have to poll, as the system may be going down or otherwise damaged */ 980 if (error = amr_poll_command(&ac)) { 981 AMRDB_PRINT((CE_NOTE, "can not poll this cmd")); 982 return (error); 983 } 984 985 return (error); 986 } 987 988 /* 989 * Take a command, submit it to the controller and wait for it to return. 990 * Returns nonzero on error. Can be safely called with interrupts enabled. 991 */ 992 static int 993 amr_poll_command(struct amr_command *ac) 994 { 995 struct amr_softs *softs = ac->ac_softs; 996 volatile uint32_t done_flag; 997 998 AMRDB_PRINT((CE_NOTE, "Amr_Poll bcopy(%p, %p, %d)", 999 (void *)&ac->mailbox, 1000 (void *)softs->mailbox, 1001 (uint32_t)AMR_MBOX_CMDSIZE)); 1002 1003 mutex_enter(&softs->cmd_mutex); 1004 1005 while (softs->amr_busyslots != 0) 1006 cv_wait(&softs->cmd_cv, &softs->cmd_mutex); 1007 1008 /* 1009 * For read/write commands, the scatter/gather table should be 1010 * filled, and the last entry in scatter/gather table will be used. 1011 */ 1012 if ((ac->mailbox.mb_command == AMR_CMD_LREAD) || 1013 (ac->mailbox.mb_command == AMR_CMD_LWRITE)) { 1014 bcopy(ac->sgtable, 1015 softs->sg_items[softs->sg_max_count - 1].sg_table, 1016 sizeof (struct amr_sgentry) * AMR_NSEG); 1017 1018 (void) ddi_dma_sync( 1019 softs->sg_items[softs->sg_max_count - 1].sg_handle, 1020 0, 0, DDI_DMA_SYNC_FORDEV); 1021 1022 ac->mailbox.mb_physaddr = 1023 softs->sg_items[softs->sg_max_count - 1].sg_phyaddr; 1024 } 1025 1026 bcopy(&ac->mailbox, (void *)softs->mailbox, AMR_MBOX_CMDSIZE); 1027 1028 /* sync the dma memory */ 1029 (void) ddi_dma_sync(softs->mbox_dma_handle, 0, 0, DDI_DMA_SYNC_FORDEV); 1030 1031 /* clear the poll/ack fields in the mailbox */ 1032 softs->mailbox->mb_ident = AMR_POLL_COMMAND_ID; 1033 softs->mailbox->mb_nstatus = AMR_POLL_DEFAULT_NSTATUS; 1034 softs->mailbox->mb_status = AMR_POLL_DEFAULT_STATUS; 1035 softs->mailbox->mb_poll = 0; 1036 softs->mailbox->mb_ack = 0; 1037 softs->mailbox->mb_busy = 1; 1038 1039 AMR_QPUT_IDB(softs, softs->mbox_phyaddr | AMR_QIDB_SUBMIT); 1040 1041 /* sync the dma memory */ 1042 (void) ddi_dma_sync(softs->mbox_dma_handle, 0, 0, DDI_DMA_SYNC_FORCPU); 1043 1044 AMR_DELAY((softs->mailbox->mb_nstatus != AMR_POLL_DEFAULT_NSTATUS), 1045 1000, done_flag); 1046 if (!done_flag) { 1047 mutex_exit(&softs->cmd_mutex); 1048 return (1); 1049 } 1050 1051 ac->ac_status = softs->mailbox->mb_status; 1052 1053 AMR_DELAY((softs->mailbox->mb_poll == AMR_POLL_ACK), 1000, done_flag); 1054 if (!done_flag) { 1055 mutex_exit(&softs->cmd_mutex); 1056 return (1); 1057 } 1058 1059 softs->mailbox->mb_poll = 0; 1060 softs->mailbox->mb_ack = AMR_POLL_ACK; 1061 1062 /* acknowledge that we have the commands */ 1063 AMR_QPUT_IDB(softs, softs->mbox_phyaddr | AMR_QIDB_ACK); 1064 1065 AMR_DELAY(!(AMR_QGET_IDB(softs) & AMR_QIDB_ACK), 1000, done_flag); 1066 if (!done_flag) { 1067 mutex_exit(&softs->cmd_mutex); 1068 return (1); 1069 } 1070 1071 mutex_exit(&softs->cmd_mutex); 1072 return (ac->ac_status != AMR_STATUS_SUCCESS); 1073 } 1074 1075 /* 1076 * setup the scatter/gather table 1077 */ 1078 static int 1079 amr_setup_sg(struct amr_softs *softs) 1080 { 1081 uint32_t i; 1082 size_t len; 1083 ddi_dma_cookie_t cookie; 1084 uint_t cookien; 1085 1086 softs->sg_max_count = 0; 1087 1088 for (i = 0; i < AMR_MAXCMD; i++) { 1089 1090 /* reset the cookien */ 1091 cookien = 0; 1092 1093 (softs->sg_items[i]).sg_handle = NULL; 1094 if (ddi_dma_alloc_handle( 1095 softs->dev_info_p, 1096 &addr_dma_attr, 1097 DDI_DMA_SLEEP, 1098 NULL, 1099 &((softs->sg_items[i]).sg_handle)) != DDI_SUCCESS) { 1100 1101 AMRDB_PRINT((CE_WARN, 1102 "Cannot alloc dma handle for s/g table")); 1103 goto error_out; 1104 } 1105 1106 if (ddi_dma_mem_alloc((softs->sg_items[i]).sg_handle, 1107 sizeof (struct amr_sgentry) * AMR_NSEG, 1108 &accattr, 1109 DDI_DMA_RDWR | DDI_DMA_CONSISTENT, 1110 DDI_DMA_SLEEP, NULL, 1111 (caddr_t *)(&(softs->sg_items[i]).sg_table), 1112 &len, 1113 &(softs->sg_items[i]).sg_acc_handle) 1114 != DDI_SUCCESS) { 1115 1116 AMRDB_PRINT((CE_WARN, 1117 "Cannot allocate DMA memory")); 1118 goto error_out; 1119 } 1120 1121 if (ddi_dma_addr_bind_handle( 1122 (softs->sg_items[i]).sg_handle, 1123 NULL, 1124 (caddr_t)((softs->sg_items[i]).sg_table), 1125 len, 1126 DDI_DMA_RDWR | DDI_DMA_CONSISTENT, 1127 DDI_DMA_SLEEP, 1128 NULL, 1129 &cookie, 1130 &cookien) != DDI_DMA_MAPPED) { 1131 1132 AMRDB_PRINT((CE_WARN, 1133 "Cannot bind communication area for s/g table")); 1134 goto error_out; 1135 } 1136 1137 if (cookien != 1) 1138 goto error_out; 1139 1140 softs->sg_items[i].sg_phyaddr = cookie.dmac_address; 1141 softs->sg_max_count++; 1142 } 1143 1144 return (DDI_SUCCESS); 1145 1146 error_out: 1147 /* 1148 * Couldn't allocate/initialize all of the sg table entries. 1149 * Clean up the partially-initialized entry before returning. 1150 */ 1151 if (cookien) { 1152 (void) ddi_dma_unbind_handle((softs->sg_items[i]).sg_handle); 1153 } 1154 if ((softs->sg_items[i]).sg_acc_handle) { 1155 (void) ddi_dma_mem_free(&((softs->sg_items[i]).sg_acc_handle)); 1156 (softs->sg_items[i]).sg_acc_handle = NULL; 1157 } 1158 if ((softs->sg_items[i]).sg_handle) { 1159 (void) ddi_dma_free_handle(&((softs->sg_items[i]).sg_handle)); 1160 (softs->sg_items[i]).sg_handle = NULL; 1161 } 1162 1163 /* 1164 * At least two sg table entries are needed. One is for regular data 1165 * I/O commands, the other is for poll I/O commands. 1166 */ 1167 return (softs->sg_max_count > 1 ? DDI_SUCCESS : DDI_FAILURE); 1168 } 1169 1170 /* 1171 * Map/unmap (ac)'s data in the controller's addressable space as required. 1172 * 1173 * These functions may be safely called multiple times on a given command. 1174 */ 1175 static void 1176 amr_setup_dmamap(struct amr_command *ac, ddi_dma_cookie_t *buffer_dma_cookiep, 1177 int nsegments) 1178 { 1179 struct amr_sgentry *sg; 1180 uint32_t i, size; 1181 1182 sg = ac->sgtable; 1183 1184 size = 0; 1185 1186 ac->mailbox.mb_nsgelem = (uint8_t)nsegments; 1187 for (i = 0; i < nsegments; i++, sg++) { 1188 sg->sg_addr = buffer_dma_cookiep->dmac_address; 1189 sg->sg_count = buffer_dma_cookiep->dmac_size; 1190 size += sg->sg_count; 1191 1192 /* 1193 * There is no next cookie if the end of the current 1194 * window is reached. Otherwise, the next cookie 1195 * would be found. 1196 */ 1197 if ((ac->current_cookie + i + 1) != ac->num_of_cookie) 1198 ddi_dma_nextcookie(ac->buffer_dma_handle, 1199 buffer_dma_cookiep); 1200 } 1201 1202 ac->transfer_size = size; 1203 ac->data_transfered += size; 1204 } 1205 1206 1207 /* 1208 * map the amr command for enquiry, allocate the DMA resource 1209 */ 1210 static int 1211 amr_enquiry_mapcmd(struct amr_command *ac, uint32_t data_size) 1212 { 1213 struct amr_softs *softs = ac->ac_softs; 1214 size_t len; 1215 uint_t dma_flags; 1216 1217 AMRDB_PRINT((CE_NOTE, "Amr_enquiry_mapcmd called, ac=%p, flags=%x", 1218 (void *)ac, ac->ac_flags)); 1219 1220 if (ac->ac_flags & AMR_CMD_DATAOUT) { 1221 dma_flags = DDI_DMA_READ; 1222 } else { 1223 dma_flags = DDI_DMA_WRITE; 1224 } 1225 1226 dma_flags |= DDI_DMA_CONSISTENT; 1227 1228 /* process the DMA by address bind mode */ 1229 if (ddi_dma_alloc_handle(softs->dev_info_p, 1230 &addr_dma_attr, DDI_DMA_SLEEP, NULL, 1231 &ac->buffer_dma_handle) != 1232 DDI_SUCCESS) { 1233 1234 AMRDB_PRINT((CE_WARN, 1235 "Cannot allocate addr DMA tag")); 1236 goto error_out; 1237 } 1238 1239 if (ddi_dma_mem_alloc(ac->buffer_dma_handle, 1240 data_size, 1241 &accattr, 1242 dma_flags, 1243 DDI_DMA_SLEEP, 1244 NULL, 1245 (caddr_t *)&ac->ac_data, 1246 &len, 1247 &ac->buffer_acc_handle) != 1248 DDI_SUCCESS) { 1249 1250 AMRDB_PRINT((CE_WARN, 1251 "Cannot allocate DMA memory")); 1252 goto error_out; 1253 } 1254 1255 if ((ddi_dma_addr_bind_handle( 1256 ac->buffer_dma_handle, 1257 NULL, ac->ac_data, len, dma_flags, 1258 DDI_DMA_SLEEP, NULL, &ac->buffer_dma_cookie, 1259 &ac->num_of_cookie)) != DDI_DMA_MAPPED) { 1260 1261 AMRDB_PRINT((CE_WARN, 1262 "Cannot bind addr for dma")); 1263 goto error_out; 1264 } 1265 1266 ac->ac_dataphys = (&ac->buffer_dma_cookie)->dmac_address; 1267 1268 ((struct amr_mailbox *)&(ac->mailbox))->mb_param = 0; 1269 ac->mailbox.mb_nsgelem = 0; 1270 ac->mailbox.mb_physaddr = ac->ac_dataphys; 1271 1272 ac->ac_flags |= AMR_CMD_MAPPED; 1273 1274 return (DDI_SUCCESS); 1275 1276 error_out: 1277 if (ac->num_of_cookie) 1278 (void) ddi_dma_unbind_handle(ac->buffer_dma_handle); 1279 if (ac->buffer_acc_handle) { 1280 ddi_dma_mem_free(&ac->buffer_acc_handle); 1281 ac->buffer_acc_handle = NULL; 1282 } 1283 if (ac->buffer_dma_handle) { 1284 (void) ddi_dma_free_handle(&ac->buffer_dma_handle); 1285 ac->buffer_dma_handle = NULL; 1286 } 1287 1288 return (DDI_FAILURE); 1289 } 1290 1291 /* 1292 * unmap the amr command for enquiry, free the DMA resource 1293 */ 1294 static void 1295 amr_enquiry_unmapcmd(struct amr_command *ac) 1296 { 1297 AMRDB_PRINT((CE_NOTE, "Amr_enquiry_unmapcmd called, ac=%p", 1298 (void *)ac)); 1299 1300 /* if the command involved data at all and was mapped */ 1301 if ((ac->ac_flags & AMR_CMD_MAPPED) && ac->ac_data) { 1302 if (ac->buffer_dma_handle) 1303 (void) ddi_dma_unbind_handle( 1304 ac->buffer_dma_handle); 1305 if (ac->buffer_acc_handle) { 1306 ddi_dma_mem_free(&ac->buffer_acc_handle); 1307 ac->buffer_acc_handle = NULL; 1308 } 1309 if (ac->buffer_dma_handle) { 1310 (void) ddi_dma_free_handle( 1311 &ac->buffer_dma_handle); 1312 ac->buffer_dma_handle = NULL; 1313 } 1314 } 1315 1316 ac->ac_flags &= ~AMR_CMD_MAPPED; 1317 } 1318 1319 /* 1320 * map the amr command, allocate the DMA resource 1321 */ 1322 static int 1323 amr_mapcmd(struct amr_command *ac, int (*callback)(), caddr_t arg) 1324 { 1325 uint_t dma_flags; 1326 off_t off; 1327 size_t len; 1328 int error; 1329 int (*cb)(caddr_t); 1330 1331 AMRDB_PRINT((CE_NOTE, "Amr_mapcmd called, ac=%p, flags=%x", 1332 (void *)ac, ac->ac_flags)); 1333 1334 if (ac->ac_flags & AMR_CMD_DATAOUT) { 1335 dma_flags = DDI_DMA_READ; 1336 } else { 1337 dma_flags = DDI_DMA_WRITE; 1338 } 1339 1340 if (ac->ac_flags & AMR_CMD_PKT_CONSISTENT) { 1341 dma_flags |= DDI_DMA_CONSISTENT; 1342 } 1343 if (ac->ac_flags & AMR_CMD_PKT_DMA_PARTIAL) { 1344 dma_flags |= DDI_DMA_PARTIAL; 1345 } 1346 1347 if ((!(ac->ac_flags & AMR_CMD_MAPPED)) && (ac->ac_buf == NULL)) { 1348 ac->ac_flags |= AMR_CMD_MAPPED; 1349 return (DDI_SUCCESS); 1350 } 1351 1352 cb = (callback == NULL_FUNC) ? DDI_DMA_DONTWAIT : DDI_DMA_SLEEP; 1353 1354 /* if the command involves data at all, and hasn't been mapped */ 1355 if (!(ac->ac_flags & AMR_CMD_MAPPED)) { 1356 /* process the DMA by buffer bind mode */ 1357 error = ddi_dma_buf_bind_handle(ac->buffer_dma_handle, 1358 ac->ac_buf, 1359 dma_flags, 1360 cb, 1361 arg, 1362 &ac->buffer_dma_cookie, 1363 &ac->num_of_cookie); 1364 switch (error) { 1365 case DDI_DMA_PARTIAL_MAP: 1366 if (ddi_dma_numwin(ac->buffer_dma_handle, 1367 &ac->num_of_win) == DDI_FAILURE) { 1368 1369 AMRDB_PRINT((CE_WARN, 1370 "Cannot get dma num win")); 1371 (void) ddi_dma_unbind_handle( 1372 ac->buffer_dma_handle); 1373 (void) ddi_dma_free_handle( 1374 &ac->buffer_dma_handle); 1375 ac->buffer_dma_handle = NULL; 1376 return (DDI_FAILURE); 1377 } 1378 ac->current_win = 0; 1379 break; 1380 1381 case DDI_DMA_MAPPED: 1382 ac->num_of_win = 1; 1383 ac->current_win = 0; 1384 break; 1385 1386 default: 1387 AMRDB_PRINT((CE_WARN, 1388 "Cannot bind buf for dma")); 1389 1390 (void) ddi_dma_free_handle( 1391 &ac->buffer_dma_handle); 1392 ac->buffer_dma_handle = NULL; 1393 return (DDI_FAILURE); 1394 } 1395 1396 ac->current_cookie = 0; 1397 1398 ac->ac_flags |= AMR_CMD_MAPPED; 1399 } else if (ac->current_cookie == AMR_LAST_COOKIE_TAG) { 1400 /* get the next window */ 1401 ac->current_win++; 1402 (void) ddi_dma_getwin(ac->buffer_dma_handle, 1403 ac->current_win, &off, &len, 1404 &ac->buffer_dma_cookie, 1405 &ac->num_of_cookie); 1406 ac->current_cookie = 0; 1407 } 1408 1409 if ((ac->num_of_cookie - ac->current_cookie) > AMR_NSEG) { 1410 amr_setup_dmamap(ac, &ac->buffer_dma_cookie, AMR_NSEG); 1411 ac->current_cookie += AMR_NSEG; 1412 } else { 1413 amr_setup_dmamap(ac, &ac->buffer_dma_cookie, 1414 ac->num_of_cookie - ac->current_cookie); 1415 ac->current_cookie = AMR_LAST_COOKIE_TAG; 1416 } 1417 1418 return (DDI_SUCCESS); 1419 } 1420 1421 /* 1422 * unmap the amr command, free the DMA resource 1423 */ 1424 static void 1425 amr_unmapcmd(struct amr_command *ac) 1426 { 1427 AMRDB_PRINT((CE_NOTE, "Amr_unmapcmd called, ac=%p", 1428 (void *)ac)); 1429 1430 /* if the command involved data at all and was mapped */ 1431 if ((ac->ac_flags & AMR_CMD_MAPPED) && 1432 ac->ac_buf && ac->buffer_dma_handle) 1433 (void) ddi_dma_unbind_handle(ac->buffer_dma_handle); 1434 1435 ac->ac_flags &= ~AMR_CMD_MAPPED; 1436 } 1437 1438 static int 1439 amr_setup_tran(dev_info_t *dip, struct amr_softs *softp) 1440 { 1441 softp->hba_tran = scsi_hba_tran_alloc(dip, SCSI_HBA_CANSLEEP); 1442 1443 /* 1444 * hba_private always points to the amr_softs struct 1445 */ 1446 softp->hba_tran->tran_hba_private = softp; 1447 softp->hba_tran->tran_tgt_init = amr_tran_tgt_init; 1448 softp->hba_tran->tran_tgt_probe = scsi_hba_probe; 1449 softp->hba_tran->tran_start = amr_tran_start; 1450 softp->hba_tran->tran_reset = amr_tran_reset; 1451 softp->hba_tran->tran_getcap = amr_tran_getcap; 1452 softp->hba_tran->tran_setcap = amr_tran_setcap; 1453 softp->hba_tran->tran_init_pkt = amr_tran_init_pkt; 1454 softp->hba_tran->tran_destroy_pkt = amr_tran_destroy_pkt; 1455 softp->hba_tran->tran_dmafree = amr_tran_dmafree; 1456 softp->hba_tran->tran_sync_pkt = amr_tran_sync_pkt; 1457 softp->hba_tran->tran_abort = NULL; 1458 softp->hba_tran->tran_tgt_free = NULL; 1459 softp->hba_tran->tran_quiesce = NULL; 1460 softp->hba_tran->tran_unquiesce = NULL; 1461 softp->hba_tran->tran_sd = NULL; 1462 1463 if (scsi_hba_attach_setup(dip, &buffer_dma_attr, softp->hba_tran, 1464 SCSI_HBA_TRAN_CLONE) != DDI_SUCCESS) { 1465 scsi_hba_tran_free(softp->hba_tran); 1466 softp->hba_tran = NULL; 1467 return (DDI_FAILURE); 1468 } else { 1469 return (DDI_SUCCESS); 1470 } 1471 } 1472 1473 /*ARGSUSED*/ 1474 static int 1475 amr_tran_tgt_init(dev_info_t *hba_dip, dev_info_t *tgt_dip, 1476 scsi_hba_tran_t *tran, struct scsi_device *sd) 1477 { 1478 struct amr_softs *softs; 1479 ushort_t target = sd->sd_address.a_target; 1480 uchar_t lun = sd->sd_address.a_lun; 1481 1482 softs = (struct amr_softs *) 1483 (sd->sd_address.a_hba_tran->tran_hba_private); 1484 1485 if ((lun == 0) && (target < AMR_MAXLD)) 1486 if (softs->logic_drive[target].al_state != AMR_LDRV_OFFLINE) 1487 return (DDI_SUCCESS); 1488 1489 return (DDI_FAILURE); 1490 } 1491 1492 static int 1493 amr_tran_start(struct scsi_address *ap, struct scsi_pkt *pkt) 1494 { 1495 struct amr_softs *softs; 1496 struct buf *bp = NULL; 1497 union scsi_cdb *cdbp = (union scsi_cdb *)pkt->pkt_cdbp; 1498 int ret; 1499 uint32_t capacity; 1500 struct amr_command *ac; 1501 1502 AMRDB_PRINT((CE_NOTE, "amr_tran_start, cmd=%X,target=%d,lun=%d", 1503 cdbp->scc_cmd, ap->a_target, ap->a_lun)); 1504 1505 softs = (struct amr_softs *)(ap->a_hba_tran->tran_hba_private); 1506 if ((ap->a_lun != 0) || (ap->a_target >= AMR_MAXLD) || 1507 (softs->logic_drive[ap->a_target].al_state == 1508 AMR_LDRV_OFFLINE)) { 1509 cmn_err(CE_WARN, "target or lun is not correct!"); 1510 ret = TRAN_BADPKT; 1511 return (ret); 1512 } 1513 1514 ac = (struct amr_command *)pkt->pkt_ha_private; 1515 bp = ac->ac_buf; 1516 1517 AMRDB_PRINT((CE_NOTE, "scsi cmd accepted, cmd=%X", cdbp->scc_cmd)); 1518 1519 switch (cdbp->scc_cmd) { 1520 case SCMD_READ: /* read */ 1521 case SCMD_READ_G1: /* read g1 */ 1522 case SCMD_READ_BUFFER: /* read buffer */ 1523 case SCMD_WRITE: /* write */ 1524 case SCMD_WRITE_G1: /* write g1 */ 1525 case SCMD_WRITE_BUFFER: /* write buffer */ 1526 amr_rw_command(softs, pkt, ap->a_target); 1527 1528 if (pkt->pkt_flags & FLAG_NOINTR) { 1529 (void) amr_poll_command(ac); 1530 pkt->pkt_state |= (STATE_GOT_BUS 1531 | STATE_GOT_TARGET 1532 | STATE_SENT_CMD 1533 | STATE_XFERRED_DATA); 1534 *pkt->pkt_scbp = 0; 1535 pkt->pkt_statistics |= STAT_SYNC; 1536 pkt->pkt_reason = CMD_CMPLT; 1537 } else { 1538 mutex_enter(&softs->queue_mutex); 1539 if (softs->waiting_q_head == NULL) { 1540 ac->ac_prev = NULL; 1541 ac->ac_next = NULL; 1542 softs->waiting_q_head = ac; 1543 softs->waiting_q_tail = ac; 1544 } else { 1545 ac->ac_next = NULL; 1546 ac->ac_prev = softs->waiting_q_tail; 1547 softs->waiting_q_tail->ac_next = ac; 1548 softs->waiting_q_tail = ac; 1549 } 1550 mutex_exit(&softs->queue_mutex); 1551 amr_start_waiting_queue((void *)softs); 1552 } 1553 ret = TRAN_ACCEPT; 1554 break; 1555 1556 case SCMD_INQUIRY: /* inquiry */ 1557 if (bp && bp->b_un.b_addr && bp->b_bcount) { 1558 struct scsi_inquiry inqp; 1559 uint8_t *sinq_p = (uint8_t *)&inqp; 1560 1561 bzero(&inqp, sizeof (struct scsi_inquiry)); 1562 1563 if (((char *)cdbp)[1] || ((char *)cdbp)[2]) { 1564 /* 1565 * The EVDP and pagecode is 1566 * not supported 1567 */ 1568 sinq_p[1] = 0xFF; 1569 sinq_p[2] = 0x0; 1570 } else { 1571 inqp.inq_len = AMR_INQ_ADDITIONAL_LEN; 1572 inqp.inq_ansi = AMR_INQ_ANSI_VER; 1573 inqp.inq_rdf = AMR_INQ_RESP_DATA_FORMAT; 1574 /* Enable Tag Queue */ 1575 inqp.inq_cmdque = 1; 1576 bcopy("MegaRaid", inqp.inq_vid, 1577 sizeof (inqp.inq_vid)); 1578 bcopy(softs->amr_product_info.pi_product_name, 1579 inqp.inq_pid, 1580 AMR_PRODUCT_INFO_SIZE); 1581 bcopy(softs->amr_product_info.pi_firmware_ver, 1582 inqp.inq_revision, 1583 AMR_FIRMWARE_VER_SIZE); 1584 } 1585 1586 amr_unmapcmd(ac); 1587 1588 if (bp->b_flags & (B_PHYS | B_PAGEIO)) 1589 bp_mapin(bp); 1590 bcopy(&inqp, bp->b_un.b_addr, 1591 sizeof (struct scsi_inquiry)); 1592 1593 pkt->pkt_state |= STATE_XFERRED_DATA; 1594 } 1595 pkt->pkt_reason = CMD_CMPLT; 1596 pkt->pkt_state |= (STATE_GOT_BUS 1597 | STATE_GOT_TARGET 1598 | STATE_SENT_CMD); 1599 *pkt->pkt_scbp = 0; 1600 ret = TRAN_ACCEPT; 1601 if (!(pkt->pkt_flags & FLAG_NOINTR)) 1602 scsi_hba_pkt_comp(pkt); 1603 break; 1604 1605 case SCMD_READ_CAPACITY: /* read capacity */ 1606 if (bp && bp->b_un.b_addr && bp->b_bcount) { 1607 struct scsi_capacity cp; 1608 1609 capacity = softs->logic_drive[ap->a_target].al_size - 1; 1610 cp.capacity = BE_32(capacity); 1611 cp.lbasize = BE_32(512); 1612 1613 amr_unmapcmd(ac); 1614 1615 if (bp->b_flags & (B_PHYS | B_PAGEIO)) 1616 bp_mapin(bp); 1617 bcopy(&cp, bp->b_un.b_addr, 8); 1618 } 1619 pkt->pkt_reason = CMD_CMPLT; 1620 pkt->pkt_state |= (STATE_GOT_BUS 1621 | STATE_GOT_TARGET 1622 | STATE_SENT_CMD 1623 | STATE_XFERRED_DATA); 1624 *pkt->pkt_scbp = 0; 1625 ret = TRAN_ACCEPT; 1626 if (!(pkt->pkt_flags & FLAG_NOINTR)) 1627 scsi_hba_pkt_comp(pkt); 1628 break; 1629 1630 case SCMD_MODE_SENSE: /* mode sense */ 1631 case SCMD_MODE_SENSE_G1: /* mode sense g1 */ 1632 amr_unmapcmd(ac); 1633 1634 capacity = softs->logic_drive[ap->a_target].al_size - 1; 1635 amr_mode_sense(cdbp, bp, capacity); 1636 1637 pkt->pkt_reason = CMD_CMPLT; 1638 pkt->pkt_state |= (STATE_GOT_BUS 1639 | STATE_GOT_TARGET 1640 | STATE_SENT_CMD 1641 | STATE_XFERRED_DATA); 1642 *pkt->pkt_scbp = 0; 1643 ret = TRAN_ACCEPT; 1644 if (!(pkt->pkt_flags & FLAG_NOINTR)) 1645 scsi_hba_pkt_comp(pkt); 1646 break; 1647 1648 case SCMD_TEST_UNIT_READY: /* test unit ready */ 1649 case SCMD_REQUEST_SENSE: /* request sense */ 1650 case SCMD_FORMAT: /* format */ 1651 case SCMD_START_STOP: /* start stop */ 1652 case SCMD_SYNCHRONIZE_CACHE: /* synchronize cache */ 1653 if (bp && bp->b_un.b_addr && bp->b_bcount) { 1654 amr_unmapcmd(ac); 1655 1656 if (bp->b_flags & (B_PHYS | B_PAGEIO)) 1657 bp_mapin(bp); 1658 bzero(bp->b_un.b_addr, bp->b_bcount); 1659 1660 pkt->pkt_state |= STATE_XFERRED_DATA; 1661 } 1662 pkt->pkt_reason = CMD_CMPLT; 1663 pkt->pkt_state |= (STATE_GOT_BUS 1664 | STATE_GOT_TARGET 1665 | STATE_SENT_CMD); 1666 ret = TRAN_ACCEPT; 1667 *pkt->pkt_scbp = 0; 1668 if (!(pkt->pkt_flags & FLAG_NOINTR)) 1669 scsi_hba_pkt_comp(pkt); 1670 break; 1671 1672 default: /* any other commands */ 1673 amr_unmapcmd(ac); 1674 pkt->pkt_reason = CMD_INCOMPLETE; 1675 pkt->pkt_state = (STATE_GOT_BUS 1676 | STATE_GOT_TARGET 1677 | STATE_SENT_CMD 1678 | STATE_GOT_STATUS 1679 | STATE_ARQ_DONE); 1680 ret = TRAN_ACCEPT; 1681 *pkt->pkt_scbp = 0; 1682 amr_set_arq_data(pkt, KEY_ILLEGAL_REQUEST); 1683 if (!(pkt->pkt_flags & FLAG_NOINTR)) 1684 scsi_hba_pkt_comp(pkt); 1685 break; 1686 } 1687 1688 return (ret); 1689 } 1690 1691 /* 1692 * tran_reset() will reset the bus/target/adapter to support the fault recovery 1693 * functionality according to the "level" in interface. However, we got the 1694 * confirmation from LSI that these HBA cards does not support any commands to 1695 * reset bus/target/adapter/channel. 1696 * 1697 * If the tran_reset() return a FAILURE to the sd, the system will not 1698 * continue to dump the core. But core dump is an crucial method to analyze 1699 * problems in panic. Now we adopt a work around solution, that is to return 1700 * a fake SUCCESS to sd during panic, which will force the system continue 1701 * to dump core though the core may have problems in some situtation because 1702 * some on-the-fly commands will continue DMAing data to the memory. 1703 * In addition, the work around core dump method may not be performed 1704 * successfully if the panic is caused by the HBA itself. So the work around 1705 * solution is not a good example for the implementation of tran_reset(), 1706 * the most reasonable approach should send a reset command to the adapter. 1707 */ 1708 /*ARGSUSED*/ 1709 static int 1710 amr_tran_reset(struct scsi_address *ap, int level) 1711 { 1712 struct amr_softs *softs; 1713 volatile uint32_t done_flag; 1714 1715 if (ddi_in_panic()) { 1716 softs = (struct amr_softs *)(ap->a_hba_tran->tran_hba_private); 1717 1718 /* Acknowledge the card if there are any significant commands */ 1719 while (softs->amr_busyslots > 0) { 1720 AMR_DELAY((softs->mailbox->mb_busy == 0), 1721 AMR_RETRYCOUNT, done_flag); 1722 if (!done_flag) { 1723 /* 1724 * command not completed, indicate the 1725 * problem and continue get ac 1726 */ 1727 cmn_err(CE_WARN, 1728 "AMR command is not completed"); 1729 return (0); 1730 } 1731 1732 AMR_QPUT_IDB(softs, softs->mbox_phyaddr | AMR_QIDB_ACK); 1733 1734 /* wait for the acknowledge from hardware */ 1735 AMR_BUSYWAIT(!(AMR_QGET_IDB(softs) & AMR_QIDB_ACK), 1736 AMR_RETRYCOUNT, done_flag); 1737 if (!done_flag) { 1738 /* 1739 * command is not completed, return from the 1740 * current interrupt and wait for the next one 1741 */ 1742 cmn_err(CE_WARN, "No answer from the hardware"); 1743 1744 mutex_exit(&softs->cmd_mutex); 1745 return (0); 1746 } 1747 1748 softs->amr_busyslots -= softs->mailbox->mb_nstatus; 1749 } 1750 1751 /* flush the controllor */ 1752 (void) amr_flush(softs); 1753 1754 /* 1755 * If the system is in panic, the tran_reset() will return a 1756 * fake SUCCESS to sd, then the system would continue dump the 1757 * core by poll commands. This is a work around for dumping 1758 * core in panic. 1759 * 1760 * Note: Some on-the-fly command will continue DMAing data to 1761 * the memory when the core is dumping, which may cause 1762 * some flaws in the dumped core file, so a cmn_err() 1763 * will be printed out to warn users. However, for most 1764 * cases, the core file will be fine. 1765 */ 1766 cmn_err(CE_WARN, "This system contains a SCSI HBA card/driver " 1767 "that doesn't support software reset. This " 1768 "means that memory being used by the HBA for " 1769 "DMA based reads could have been updated after " 1770 "we panic'd."); 1771 return (1); 1772 } else { 1773 /* return failure to sd */ 1774 return (0); 1775 } 1776 } 1777 1778 /*ARGSUSED*/ 1779 static int 1780 amr_tran_getcap(struct scsi_address *ap, char *cap, int whom) 1781 { 1782 struct amr_softs *softs; 1783 1784 /* 1785 * We don't allow inquiring about capabilities for other targets 1786 */ 1787 if (cap == NULL || whom == 0) 1788 return (-1); 1789 1790 softs = ((struct amr_softs *)(ap->a_hba_tran)->tran_hba_private); 1791 1792 switch (scsi_hba_lookup_capstr(cap)) { 1793 case SCSI_CAP_ARQ: 1794 return (1); 1795 case SCSI_CAP_GEOMETRY: 1796 return ((AMR_DEFAULT_HEADS << 16) | AMR_DEFAULT_CYLINDERS); 1797 case SCSI_CAP_SECTOR_SIZE: 1798 return (AMR_DEFAULT_SECTORS); 1799 case SCSI_CAP_TOTAL_SECTORS: 1800 /* number of sectors */ 1801 return (softs->logic_drive[ap->a_target].al_size); 1802 case SCSI_CAP_UNTAGGED_QING: 1803 case SCSI_CAP_TAGGED_QING: 1804 return (1); 1805 default: 1806 return (-1); 1807 } 1808 } 1809 1810 /*ARGSUSED*/ 1811 static int 1812 amr_tran_setcap(struct scsi_address *ap, char *cap, int value, 1813 int whom) 1814 { 1815 /* 1816 * We don't allow setting capabilities for other targets 1817 */ 1818 if (cap == NULL || whom == 0) { 1819 AMRDB_PRINT((CE_NOTE, 1820 "Set Cap not supported, string = %s, whom=%d", 1821 cap, whom)); 1822 return (-1); 1823 } 1824 1825 switch (scsi_hba_lookup_capstr(cap)) { 1826 case SCSI_CAP_ARQ: 1827 return (1); 1828 case SCSI_CAP_TOTAL_SECTORS: 1829 return (1); 1830 case SCSI_CAP_SECTOR_SIZE: 1831 return (1); 1832 case SCSI_CAP_UNTAGGED_QING: 1833 case SCSI_CAP_TAGGED_QING: 1834 return ((value == 1) ? 1 : 0); 1835 default: 1836 return (0); 1837 } 1838 } 1839 1840 static struct scsi_pkt * 1841 amr_tran_init_pkt(struct scsi_address *ap, 1842 struct scsi_pkt *pkt, struct buf *bp, int cmdlen, int statuslen, 1843 int tgtlen, int flags, int (*callback)(), caddr_t arg) 1844 { 1845 struct amr_softs *softs; 1846 struct amr_command *ac; 1847 uint32_t slen; 1848 1849 softs = (struct amr_softs *)(ap->a_hba_tran->tran_hba_private); 1850 1851 if ((ap->a_lun != 0)||(ap->a_target >= AMR_MAXLD)|| 1852 (softs->logic_drive[ap->a_target].al_state == 1853 AMR_LDRV_OFFLINE)) { 1854 return (NULL); 1855 } 1856 1857 if (pkt == NULL) { 1858 /* force auto request sense */ 1859 slen = MAX(statuslen, sizeof (struct scsi_arq_status)); 1860 1861 pkt = scsi_hba_pkt_alloc(softs->dev_info_p, ap, cmdlen, 1862 slen, tgtlen, sizeof (struct amr_command), 1863 callback, arg); 1864 if (pkt == NULL) { 1865 AMRDB_PRINT((CE_WARN, "scsi_hba_pkt_alloc failed")); 1866 return (NULL); 1867 } 1868 pkt->pkt_address = *ap; 1869 pkt->pkt_comp = (void (*)())NULL; 1870 pkt->pkt_time = 0; 1871 pkt->pkt_resid = 0; 1872 pkt->pkt_statistics = 0; 1873 pkt->pkt_reason = 0; 1874 1875 ac = (struct amr_command *)pkt->pkt_ha_private; 1876 ac->ac_buf = bp; 1877 ac->cmdlen = cmdlen; 1878 ac->ac_softs = softs; 1879 ac->pkt = pkt; 1880 ac->ac_flags &= ~AMR_CMD_GOT_SLOT; 1881 ac->ac_flags &= ~AMR_CMD_BUSY; 1882 1883 if ((bp == NULL) || (bp->b_bcount == 0)) { 1884 return (pkt); 1885 } 1886 1887 if (ddi_dma_alloc_handle(softs->dev_info_p, &buffer_dma_attr, 1888 DDI_DMA_SLEEP, NULL, 1889 &ac->buffer_dma_handle) != DDI_SUCCESS) { 1890 1891 AMRDB_PRINT((CE_WARN, 1892 "Cannot allocate buffer DMA tag")); 1893 scsi_hba_pkt_free(ap, pkt); 1894 return (NULL); 1895 1896 } 1897 1898 } else { 1899 if ((bp == NULL) || (bp->b_bcount == 0)) { 1900 return (pkt); 1901 } 1902 ac = (struct amr_command *)pkt->pkt_ha_private; 1903 } 1904 1905 ASSERT(ac != NULL); 1906 1907 if (bp->b_flags & B_READ) { 1908 ac->ac_flags |= AMR_CMD_DATAOUT; 1909 } else { 1910 ac->ac_flags |= AMR_CMD_DATAIN; 1911 } 1912 1913 if (flags & PKT_CONSISTENT) { 1914 ac->ac_flags |= AMR_CMD_PKT_CONSISTENT; 1915 } 1916 1917 if (flags & PKT_DMA_PARTIAL) { 1918 ac->ac_flags |= AMR_CMD_PKT_DMA_PARTIAL; 1919 } 1920 1921 if (amr_mapcmd(ac, callback, arg) != DDI_SUCCESS) { 1922 scsi_hba_pkt_free(ap, pkt); 1923 return (NULL); 1924 } 1925 1926 pkt->pkt_resid = bp->b_bcount - ac->data_transfered; 1927 1928 AMRDB_PRINT((CE_NOTE, 1929 "init pkt, pkt_resid=%d, b_bcount=%d, data_transfered=%d", 1930 (uint32_t)pkt->pkt_resid, (uint32_t)bp->b_bcount, 1931 ac->data_transfered)); 1932 1933 ASSERT(pkt->pkt_resid >= 0); 1934 1935 return (pkt); 1936 } 1937 1938 static void 1939 amr_tran_destroy_pkt(struct scsi_address *ap, struct scsi_pkt *pkt) 1940 { 1941 struct amr_command *ac = (struct amr_command *)pkt->pkt_ha_private; 1942 1943 amr_unmapcmd(ac); 1944 1945 if (ac->buffer_dma_handle) { 1946 (void) ddi_dma_free_handle(&ac->buffer_dma_handle); 1947 ac->buffer_dma_handle = NULL; 1948 } 1949 1950 scsi_hba_pkt_free(ap, pkt); 1951 AMRDB_PRINT((CE_NOTE, "Destroy pkt called")); 1952 } 1953 1954 /*ARGSUSED*/ 1955 static void 1956 amr_tran_sync_pkt(struct scsi_address *ap, struct scsi_pkt *pkt) 1957 { 1958 struct amr_command *ac = (struct amr_command *)pkt->pkt_ha_private; 1959 1960 if (ac->buffer_dma_handle) { 1961 (void) ddi_dma_sync(ac->buffer_dma_handle, 0, 0, 1962 (ac->ac_flags & AMR_CMD_DATAIN) ? 1963 DDI_DMA_SYNC_FORDEV : DDI_DMA_SYNC_FORCPU); 1964 } 1965 } 1966 1967 /*ARGSUSED*/ 1968 static void 1969 amr_tran_dmafree(struct scsi_address *ap, struct scsi_pkt *pkt) 1970 { 1971 struct amr_command *ac = (struct amr_command *)pkt->pkt_ha_private; 1972 1973 if (ac->ac_flags & AMR_CMD_MAPPED) { 1974 (void) ddi_dma_unbind_handle(ac->buffer_dma_handle); 1975 (void) ddi_dma_free_handle(&ac->buffer_dma_handle); 1976 ac->buffer_dma_handle = NULL; 1977 ac->ac_flags &= ~AMR_CMD_MAPPED; 1978 } 1979 1980 } 1981 1982 /*ARGSUSED*/ 1983 static void 1984 amr_rw_command(struct amr_softs *softs, struct scsi_pkt *pkt, int target) 1985 { 1986 struct amr_command *ac = (struct amr_command *)pkt->pkt_ha_private; 1987 union scsi_cdb *cdbp = (union scsi_cdb *)pkt->pkt_cdbp; 1988 uint8_t cmd; 1989 1990 if (ac->ac_flags & AMR_CMD_DATAOUT) { 1991 cmd = AMR_CMD_LREAD; 1992 } else { 1993 cmd = AMR_CMD_LWRITE; 1994 } 1995 1996 ac->mailbox.mb_command = cmd; 1997 ac->mailbox.mb_blkcount = 1998 (ac->transfer_size + AMR_BLKSIZE - 1)/AMR_BLKSIZE; 1999 ac->mailbox.mb_lba = (ac->cmdlen == 10) ? 2000 GETG1ADDR(cdbp) : GETG0ADDR(cdbp); 2001 ac->mailbox.mb_drive = (uint8_t)target; 2002 } 2003 2004 static void 2005 amr_mode_sense(union scsi_cdb *cdbp, struct buf *bp, unsigned int capacity) 2006 { 2007 uchar_t pagecode; 2008 struct mode_format *page3p; 2009 struct mode_geometry *page4p; 2010 struct mode_header *headerp; 2011 uint32_t ncyl; 2012 2013 if (!(bp && bp->b_un.b_addr && bp->b_bcount)) 2014 return; 2015 2016 if (bp->b_flags & (B_PHYS | B_PAGEIO)) 2017 bp_mapin(bp); 2018 2019 pagecode = cdbp->cdb_un.sg.scsi[0]; 2020 switch (pagecode) { 2021 case SD_MODE_SENSE_PAGE3_CODE: 2022 headerp = (struct mode_header *)(bp->b_un.b_addr); 2023 headerp->bdesc_length = MODE_BLK_DESC_LENGTH; 2024 2025 page3p = (struct mode_format *)((caddr_t)headerp + 2026 MODE_HEADER_LENGTH + MODE_BLK_DESC_LENGTH); 2027 page3p->mode_page.code = BE_8(SD_MODE_SENSE_PAGE3_CODE); 2028 page3p->mode_page.length = BE_8(sizeof (struct mode_format)); 2029 page3p->data_bytes_sect = BE_16(AMR_DEFAULT_SECTORS); 2030 page3p->sect_track = BE_16(AMR_DEFAULT_CYLINDERS); 2031 2032 return; 2033 2034 case SD_MODE_SENSE_PAGE4_CODE: 2035 headerp = (struct mode_header *)(bp->b_un.b_addr); 2036 headerp->bdesc_length = MODE_BLK_DESC_LENGTH; 2037 2038 page4p = (struct mode_geometry *)((caddr_t)headerp + 2039 MODE_HEADER_LENGTH + MODE_BLK_DESC_LENGTH); 2040 page4p->mode_page.code = BE_8(SD_MODE_SENSE_PAGE4_CODE); 2041 page4p->mode_page.length = BE_8(sizeof (struct mode_geometry)); 2042 page4p->heads = BE_8(AMR_DEFAULT_HEADS); 2043 page4p->rpm = BE_16(AMR_DEFAULT_ROTATIONS); 2044 2045 ncyl = capacity / (AMR_DEFAULT_HEADS*AMR_DEFAULT_CYLINDERS); 2046 page4p->cyl_lb = BE_8(ncyl & 0xff); 2047 page4p->cyl_mb = BE_8((ncyl >> 8) & 0xff); 2048 page4p->cyl_ub = BE_8((ncyl >> 16) & 0xff); 2049 2050 return; 2051 default: 2052 bzero(bp->b_un.b_addr, bp->b_bcount); 2053 return; 2054 } 2055 } 2056 2057 static void 2058 amr_set_arq_data(struct scsi_pkt *pkt, uchar_t key) 2059 { 2060 struct scsi_arq_status *arqstat; 2061 2062 arqstat = (struct scsi_arq_status *)(pkt->pkt_scbp); 2063 arqstat->sts_status.sts_chk = 1; /* CHECK CONDITION */ 2064 arqstat->sts_rqpkt_reason = CMD_CMPLT; 2065 arqstat->sts_rqpkt_resid = 0; 2066 arqstat->sts_rqpkt_state = STATE_GOT_BUS | STATE_GOT_TARGET | 2067 STATE_SENT_CMD | STATE_XFERRED_DATA; 2068 arqstat->sts_rqpkt_statistics = 0; 2069 arqstat->sts_sensedata.es_valid = 1; 2070 arqstat->sts_sensedata.es_class = CLASS_EXTENDED_SENSE; 2071 arqstat->sts_sensedata.es_key = key; 2072 } 2073 2074 static void 2075 amr_start_waiting_queue(void *softp) 2076 { 2077 uint32_t slot; 2078 struct amr_command *ac; 2079 volatile uint32_t done_flag; 2080 struct amr_softs *softs = (struct amr_softs *)softp; 2081 2082 /* only one command allowed at the same time */ 2083 mutex_enter(&softs->queue_mutex); 2084 mutex_enter(&softs->cmd_mutex); 2085 2086 while ((ac = softs->waiting_q_head) != NULL) { 2087 /* 2088 * Find an available slot, the last slot is 2089 * occupied by poll I/O command. 2090 */ 2091 for (slot = 0; slot < (softs->sg_max_count - 1); slot++) { 2092 if (softs->busycmd[slot] == NULL) { 2093 if (AMR_QGET_IDB(softs) & AMR_QIDB_SUBMIT) { 2094 /* 2095 * only one command allowed at the 2096 * same time 2097 */ 2098 mutex_exit(&softs->cmd_mutex); 2099 mutex_exit(&softs->queue_mutex); 2100 return; 2101 } 2102 2103 ac->ac_timestamp = ddi_get_time(); 2104 2105 if (!(ac->ac_flags & AMR_CMD_GOT_SLOT)) { 2106 2107 softs->busycmd[slot] = ac; 2108 ac->ac_slot = slot; 2109 softs->amr_busyslots++; 2110 2111 bcopy(ac->sgtable, 2112 softs->sg_items[slot].sg_table, 2113 sizeof (struct amr_sgentry) * 2114 AMR_NSEG); 2115 2116 (void) ddi_dma_sync( 2117 softs->sg_items[slot].sg_handle, 2118 0, 0, DDI_DMA_SYNC_FORDEV); 2119 2120 ac->mailbox.mb_physaddr = 2121 softs->sg_items[slot].sg_phyaddr; 2122 } 2123 2124 /* take the cmd from the queue */ 2125 softs->waiting_q_head = ac->ac_next; 2126 2127 ac->mailbox.mb_ident = ac->ac_slot + 1; 2128 ac->mailbox.mb_busy = 1; 2129 ac->ac_next = NULL; 2130 ac->ac_prev = NULL; 2131 ac->ac_flags |= AMR_CMD_GOT_SLOT; 2132 2133 /* clear the poll/ack fields in the mailbox */ 2134 softs->mailbox->mb_poll = 0; 2135 softs->mailbox->mb_ack = 0; 2136 2137 AMR_DELAY((softs->mailbox->mb_busy == 0), 2138 AMR_RETRYCOUNT, done_flag); 2139 if (!done_flag) { 2140 /* 2141 * command not completed, indicate the 2142 * problem and continue get ac 2143 */ 2144 cmn_err(CE_WARN, 2145 "AMR command is not completed"); 2146 break; 2147 } 2148 2149 bcopy(&ac->mailbox, (void *)softs->mailbox, 2150 AMR_MBOX_CMDSIZE); 2151 ac->ac_flags |= AMR_CMD_BUSY; 2152 2153 (void) ddi_dma_sync(softs->mbox_dma_handle, 2154 0, 0, DDI_DMA_SYNC_FORDEV); 2155 2156 AMR_QPUT_IDB(softs, 2157 softs->mbox_phyaddr | AMR_QIDB_SUBMIT); 2158 2159 /* 2160 * current ac is submitted 2161 * so quit 'for-loop' to get next ac 2162 */ 2163 break; 2164 } 2165 } 2166 2167 /* no slot, finish our task */ 2168 if (slot == softs->maxio) 2169 break; 2170 } 2171 2172 /* only one command allowed at the same time */ 2173 mutex_exit(&softs->cmd_mutex); 2174 mutex_exit(&softs->queue_mutex); 2175 } 2176 2177 static void 2178 amr_done(struct amr_softs *softs) 2179 { 2180 2181 uint32_t i, idx; 2182 volatile uint32_t done_flag; 2183 struct amr_mailbox *mbox, mbsave; 2184 struct amr_command *ac, *head, *tail; 2185 2186 head = tail = NULL; 2187 2188 AMR_QPUT_ODB(softs, AMR_QODB_READY); 2189 2190 /* acknowledge interrupt */ 2191 (void) AMR_QGET_ODB(softs); 2192 2193 mutex_enter(&softs->cmd_mutex); 2194 2195 if (softs->mailbox->mb_nstatus != 0) { 2196 (void) ddi_dma_sync(softs->mbox_dma_handle, 2197 0, 0, DDI_DMA_SYNC_FORCPU); 2198 2199 /* save mailbox, which contains a list of completed commands */ 2200 bcopy((void *)(uintptr_t)(volatile void *)softs->mailbox, 2201 &mbsave, sizeof (mbsave)); 2202 2203 mbox = &mbsave; 2204 2205 AMR_QPUT_IDB(softs, softs->mbox_phyaddr | AMR_QIDB_ACK); 2206 2207 /* wait for the acknowledge from hardware */ 2208 AMR_BUSYWAIT(!(AMR_QGET_IDB(softs) & AMR_QIDB_ACK), 2209 AMR_RETRYCOUNT, done_flag); 2210 if (!done_flag) { 2211 /* 2212 * command is not completed, return from the current 2213 * interrupt and wait for the next one 2214 */ 2215 cmn_err(CE_WARN, "No answer from the hardware"); 2216 2217 mutex_exit(&softs->cmd_mutex); 2218 return; 2219 } 2220 2221 for (i = 0; i < mbox->mb_nstatus; i++) { 2222 idx = mbox->mb_completed[i] - 1; 2223 ac = softs->busycmd[idx]; 2224 2225 if (ac != NULL) { 2226 /* pull the command from the busy index */ 2227 softs->busycmd[idx] = NULL; 2228 if (softs->amr_busyslots > 0) 2229 softs->amr_busyslots--; 2230 if (softs->amr_busyslots == 0) 2231 cv_broadcast(&softs->cmd_cv); 2232 2233 ac->ac_flags &= ~AMR_CMD_BUSY; 2234 ac->ac_flags &= ~AMR_CMD_GOT_SLOT; 2235 ac->ac_status = mbox->mb_status; 2236 2237 /* enqueue here */ 2238 if (head) { 2239 tail->ac_next = ac; 2240 tail = ac; 2241 tail->ac_next = NULL; 2242 } else { 2243 tail = head = ac; 2244 ac->ac_next = NULL; 2245 } 2246 } else { 2247 AMRDB_PRINT((CE_WARN, 2248 "ac in mailbox is NULL!")); 2249 } 2250 } 2251 } else { 2252 AMRDB_PRINT((CE_WARN, "mailbox is not ready for copy out!")); 2253 } 2254 2255 mutex_exit(&softs->cmd_mutex); 2256 2257 if (head != NULL) { 2258 amr_call_pkt_comp(head); 2259 } 2260 2261 /* dispatch a thread to process the pending I/O if there is any */ 2262 if ((ddi_taskq_dispatch(softs->amr_taskq, amr_start_waiting_queue, 2263 (void *)softs, DDI_NOSLEEP)) != DDI_SUCCESS) { 2264 cmn_err(CE_WARN, "No memory available to dispatch taskq"); 2265 } 2266 } 2267 2268 static void 2269 amr_call_pkt_comp(register struct amr_command *head) 2270 { 2271 register struct scsi_pkt *pkt; 2272 register struct amr_command *ac, *localhead; 2273 2274 localhead = head; 2275 2276 while (localhead) { 2277 ac = localhead; 2278 localhead = ac->ac_next; 2279 ac->ac_next = NULL; 2280 2281 pkt = ac->pkt; 2282 *pkt->pkt_scbp = 0; 2283 2284 if (ac->ac_status == AMR_STATUS_SUCCESS) { 2285 pkt->pkt_state |= (STATE_GOT_BUS 2286 | STATE_GOT_TARGET 2287 | STATE_SENT_CMD 2288 | STATE_XFERRED_DATA); 2289 pkt->pkt_reason = CMD_CMPLT; 2290 } else { 2291 pkt->pkt_state |= STATE_GOT_BUS 2292 | STATE_ARQ_DONE; 2293 pkt->pkt_reason = CMD_INCOMPLETE; 2294 amr_set_arq_data(pkt, KEY_HARDWARE_ERROR); 2295 } 2296 if (!(pkt->pkt_flags & FLAG_NOINTR)) { 2297 scsi_hba_pkt_comp(pkt); 2298 } 2299 } 2300 }