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