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