amr.c (152817) | amr.c (153409) |
---|---|
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 --- 42 unchanged lines hidden (view full) --- 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> | 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 --- 42 unchanged lines hidden (view full) --- 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> | 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> |
|
69 70#include <sys/bio.h> 71#include <sys/bus.h> 72#include <sys/conf.h> 73#include <sys/stat.h> 74 75#include <machine/bus.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> |
|
76#include <machine/resource.h> 77#include <sys/rman.h> 78 79#include <dev/pci/pcireg.h> 80#include <dev/pci/pcivar.h> 81 82#include <dev/amr/amrio.h> 83#include <dev/amr/amrreg.h> 84#include <dev/amr/amrvar.h> 85#define AMR_DEFINE_TABLES 86#include <dev/amr/amr_tables.h> 87 88/* 89 * The CAM interface appears to be completely broken. Disable it. 90 */ 91#ifndef AMR_ENABLE_CAM 92#define AMR_ENABLE_CAM 0 93#endif 94 | 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 |
|
95static d_open_t amr_open; 96static d_close_t amr_close; 97static d_ioctl_t amr_ioctl; 98 99static struct cdevsw amr_cdevsw = { 100 .d_version = D_VERSION, 101 .d_flags = D_NEEDGIANT, 102 .d_open = amr_open, --- 7 unchanged lines hidden (view full) --- 110 */ 111static void amr_startup(void *arg); 112 113/* 114 * Command wrappers 115 */ 116static int amr_query_controller(struct amr_softc *sc); 117static void *amr_enquiry(struct amr_softc *sc, size_t bufsize, | 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, --- 7 unchanged lines hidden (view full) --- 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); |
119static void amr_completeio(struct amr_command *ac); 120static int amr_support_ext_cdb(struct amr_softc *sc); 121 122/* 123 * Command buffer allocation. 124 */ 125static void amr_alloccmd_cluster(struct amr_softc *sc); 126static void amr_freecmd_cluster(struct amr_command_cluster *acc); 127 128/* 129 * Command processing. 130 */ 131static int amr_bio_command(struct amr_softc *sc, struct amr_command **acp); 132static int amr_wait_command(struct amr_command *ac) __unused; | 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); | |
134static int amr_mapcmd(struct amr_command *ac); 135static void amr_unmapcmd(struct amr_command *ac); 136static int amr_start(struct amr_command *ac); 137static int amr_start1(struct amr_softc *sc, struct amr_command *ac); 138static void amr_complete(void *context, int pending); 139static void amr_setup_dmamap(void *arg, bus_dma_segment_t *segs, int nsegments, int error); | 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); |
|
140static void amr_setup_data_dmamap(void *arg, bus_dma_segment_t *segs, int nsegments, int error); 141 142/* 143 * Status monitoring 144 */ 145static void amr_periodic(void *data); 146 147/* --- 19 unchanged lines hidden (view full) --- 167 */ 168static void amr_describe_controller(struct amr_softc *sc); 169#ifdef AMR_DEBUG 170#if 0 171static void amr_printcommand(struct amr_command *ac); 172#endif 173#endif 174 | 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/* --- 19 unchanged lines hidden (view full) --- 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 |
|
175/******************************************************************************** 176 ******************************************************************************** 177 Inline Glue 178 ******************************************************************************** 179 ********************************************************************************/ 180 181/******************************************************************************** 182 ******************************************************************************** --- 44 unchanged lines hidden (view full) --- 227 /* 228 * Quiz controller for features and limits. 229 */ 230 if (amr_query_controller(sc)) 231 return(ENXIO); 232 233 debug(2, "controller query complete"); 234 | 182/******************************************************************************** 183 ******************************************************************************** 184 Inline Glue 185 ******************************************************************************** 186 ********************************************************************************/ 187 188/******************************************************************************** 189 ******************************************************************************** --- 44 unchanged lines hidden (view full) --- 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 |
|
235#if AMR_ENABLE_CAM != 0 236 /* 237 * Attach our 'real' SCSI channels to CAM. 238 */ 239 if (amr_cam_attach(sc)) 240 return(ENXIO); 241 debug(2, "CAM attach done"); 242#endif --- 34 unchanged lines hidden (view full) --- 277{ 278 struct amr_softc *sc = (struct amr_softc *)arg; 279 struct amr_logdrive *dr; 280 int i, error; 281 282 debug_called(1); 283 284 /* pull ourselves off the intrhook chain */ | 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 --- 34 unchanged lines hidden (view full) --- 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; |
286 287 /* get up-to-date drive information */ 288 if (amr_query_controller(sc)) { 289 device_printf(sc->amr_dev, "can't scan controller for drives\n"); 290 return; 291 } 292 293 /* iterate over available drives */ --- 29 unchanged lines hidden (view full) --- 323 /* 324 * Start the timeout routine. 325 */ 326/* sc->amr_timeout = timeout(amr_periodic, sc, hz);*/ 327 328 return; 329} 330 | 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 */ --- 29 unchanged lines hidden (view full) --- 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 |
|
331/******************************************************************************* 332 * Free resources associated with a controller instance 333 */ 334void 335amr_free(struct amr_softc *sc) 336{ 337 struct amr_command_cluster *acc; 338 --- 10 unchanged lines hidden (view full) --- 349 TAILQ_REMOVE(&sc->amr_cmd_clusters, acc, acc_link); 350 amr_freecmd_cluster(acc); 351 } 352 353 /* destroy control device */ 354 if( sc->amr_dev_t != (struct cdev *)NULL) 355 destroy_dev(sc->amr_dev_t); 356 | 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 --- 10 unchanged lines hidden (view full) --- 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); |
359} 360 361/******************************************************************************* 362 * Receive a bio structure from a child device and queue it on a particular 363 * disk resource, then poke the disk resource to start as much work as it can. 364 */ 365int 366amr_submit_bio(struct amr_softc *sc, struct bio *bio) 367{ 368 debug_called(2); 369 | 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); |
371 amr_enqueue_bio(sc, bio); 372 amr_startio(sc); | 399 amr_enqueue_bio(sc, bio); 400 amr_startio(sc); |
373 mtx_unlock(&sc->amr_io_lock); | 401 mtx_unlock(&sc->amr_list_lock); |
374 return(0); 375} 376 377/******************************************************************************** 378 * Accept an open operation on the control device. 379 */ 380static int 381amr_open(struct cdev *dev, int flags, int fmt, d_thread_t *td) 382{ 383 int unit = minor(dev); 384 struct amr_softc *sc = devclass_get_softc(devclass_find("amr"), unit); 385 386 debug_called(1); 387 388 sc->amr_state |= AMR_STATE_OPEN; 389 return(0); 390} 391 | 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 |
|
392/******************************************************************************** 393 * Accept the last close on the control device. 394 */ 395static int 396amr_close(struct cdev *dev, int flags, int fmt, d_thread_t *td) 397{ 398 int unit = minor(dev); 399 struct amr_softc *sc = devclass_get_softc(devclass_find("amr"), unit); 400 401 debug_called(1); 402 403 sc->amr_state &= ~AMR_STATE_OPEN; 404 return (0); 405} 406 407/******************************************************************************** 408 * Handle controller-specific control operations. 409 */ | 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 |
|
410static int 411amr_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int32_t flag, d_thread_t *td) 412{ 413 struct amr_softc *sc = (struct amr_softc *)dev->si_drv1; 414 union { 415 void *_p; 416 struct amr_user_ioctl *au; 417#ifdef AMR_IO_COMMAND32 418 struct amr_user_ioctl32 *au32; 419#endif 420 int *result; 421 } arg; 422 struct amr_command *ac; 423 struct amr_mailbox_ioctl *mbi; 424 void *dp, *au_buffer; 425 unsigned long au_length; 426 unsigned char *au_cmd; 427 int *au_statusp, au_direction; | 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; |
429 struct amr_passthrough *ap; /* 60 bytes */ | 725 struct amr_passthrough *ap; /* 60 bytes */ |
726 int logical_drives_changed = 0; |
|
430 431 debug_called(1); 432 433 arg._p = (void *)addr; 434 | 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 |
|
435 switch(cmd) { 436 437 case AMR_IO_VERSION: 438 debug(1, "AMR_IO_VERSION"); 439 *arg.result = AMR_IO_VERSION_NUMBER; 440 return(0); 441 442#ifdef AMR_IO_COMMAND32 --- 16 unchanged lines hidden (view full) --- 459 debug(1, "AMR_IO_COMMAND 0x%x", arg.au->au_cmd[0]); 460 au_cmd = arg.au->au_cmd; 461 au_buffer = (void *)arg.au->au_buffer; 462 au_length = arg.au->au_length; 463 au_direction = arg.au->au_direction; 464 au_statusp = &arg.au->au_status; 465 break; 466 | 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 --- 16 unchanged lines hidden (view full) --- 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 |
|
467 default: 468 debug(1, "unknown ioctl 0x%lx", cmd); 469 return(ENOIOCTL); 470 } 471 | 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 } |
476 | 791 |
477 /* Logical Drive not supported by the driver */ 478 if (au_cmd[0] == 0xa4 && au_cmd[1] == 0x1c) 479 return (ENOIOCTL); 480 | |
481 /* handle inbound data buffer */ 482 if (au_length != 0 && au_cmd[0] != 0x06) { | 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 } |
485 if ((error = copyin(au_buffer, dp, au_length)) != 0) { 486 free(dp, M_DEVBUF); 487 return (error); 488 } 489 debug(2, "copyin %ld bytes from %p -> %p", au_length, au_buffer, dp); 490 } 491 492 /* Allocate this now before the mutex gets held */ 493 if (au_cmd[0] == AMR_CMD_PASS) 494 ap = malloc(sizeof(struct amr_passthrough), M_DEVBUF, M_WAITOK|M_ZERO); 495 | 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); |
501 502 /* handle SCSI passthrough command */ 503 if (au_cmd[0] == AMR_CMD_PASS) { 504 int len; 505 506 /* copy cdb */ 507 len = au_cmd[2]; 508 ap->ap_cdb_length = len; --- 8 unchanged lines hidden (view full) --- 517 ap->ap_scsi_id = au_cmd[len + 6]; 518 ap->ap_request_sense_length = 14; 519 ap->ap_data_transfer_length = au_length; 520 /* XXX what about the request-sense area? does the caller want it? */ 521 522 /* build command */ 523 ac->ac_data = ap; 524 ac->ac_length = sizeof(struct amr_passthrough); | 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; --- 8 unchanged lines hidden (view full) --- 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; | |
526 ac->ac_ccb_data = dp; 527 ac->ac_ccb_length = au_length; | 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; | |
532 533 ac->ac_mailbox.mb_command = AMR_CMD_PASS; | 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; |
|
534 535 } else { 536 /* direct command to controller */ 537 mbi = (struct amr_mailbox_ioctl *)&ac->ac_mailbox; 538 539 /* copy pertinent mailbox items */ 540 mbi->mb_command = au_cmd[0]; 541 mbi->mb_channel = au_cmd[1]; 542 mbi->mb_param = au_cmd[2]; 543 mbi->mb_pad[0] = au_cmd[3]; 544 mbi->mb_drive = au_cmd[4]; 545 546 /* build the command */ 547 ac->ac_data = dp; 548 ac->ac_length = au_length; | 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; |
553 } 554 | 858 } 859 |
860 ac->ac_flags = ac_flags; 861 |
|
555 /* run the command */ 556 if ((error = amr_wait_command(ac)) != 0) 557 goto out; 558 559 /* copy out data and set status */ 560 if (au_length != 0) { | 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); | |
562 error = copyout(dp, au_buffer, au_length); | 868 error = copyout(dp, au_buffer, au_length); |
563 mtx_lock(&sc->amr_io_lock); | |
564 } 565 debug(2, "copyout %ld bytes from %p -> %p", au_length, dp, au_buffer); 566 if (dp != NULL) 567 debug(2, "%16d", (int)dp); 568 *au_statusp = ac->ac_status; 569 570out: 571 /* 572 * At this point, we know that there is a lock held and that these 573 * objects have been allocated. 574 */ | 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); |
|
575 if (ac != NULL) 576 amr_releasecmd(ac); | 881 if (ac != NULL) 882 amr_releasecmd(ac); |
577 mtx_unlock(&sc->amr_io_lock); | 883 mtx_unlock(&sc->amr_list_lock); |
578 if (dp != NULL) 579 free(dp, M_DEVBUF); 580 if (ap != NULL) 581 free(ap, M_DEVBUF); | 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 |
|
582 return(error); 583} 584 585/******************************************************************************** 586 ******************************************************************************** 587 Status Monitoring 588 ******************************************************************************** 589 ********************************************************************************/ --- 28 unchanged lines hidden (view full) --- 618 */ 619static int 620amr_query_controller(struct amr_softc *sc) 621{ 622 struct amr_enquiry3 *aex; 623 struct amr_prodinfo *ap; 624 struct amr_enquiry *ae; 625 int ldrv; | 894 return(error); 895} 896 897/******************************************************************************** 898 ******************************************************************************** 899 Status Monitoring 900 ******************************************************************************** 901 ********************************************************************************/ --- 28 unchanged lines hidden (view full) --- 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; |
|
626 | 939 |
627 mtx_lock(&sc->amr_io_lock); 628 | |
629 /* 630 * If we haven't found the real limit yet, let us have a couple of commands in 631 * order to be able to probe. 632 */ 633 if (sc->amr_maxio == 0) 634 sc->amr_maxio = 2; 635 636 /* --- 4 unchanged lines hidden (view full) --- 641 if(sc->support_ext_cdb) { 642 debug(2,"supports extended CDBs."); 643 } 644 645 /* 646 * Try to issue an ENQUIRY3 command 647 */ 648 if ((aex = amr_enquiry(sc, 2048, AMR_CMD_CONFIG, AMR_CONFIG_ENQ3, | 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 /* --- 4 unchanged lines hidden (view full) --- 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) { |
650 651 /* 652 * Fetch current state of logical drives. 653 */ 654 for (ldrv = 0; ldrv < aex->ae_numldrives; ldrv++) { 655 sc->amr_drive[ldrv].al_size = aex->ae_drivesize[ldrv]; 656 sc->amr_drive[ldrv].al_state = aex->ae_drivestate[ldrv]; 657 sc->amr_drive[ldrv].al_properties = aex->ae_driveprop[ldrv]; 658 debug(2, " drive %d: %d state %x properties %x\n", ldrv, sc->amr_drive[ldrv].al_size, 659 sc->amr_drive[ldrv].al_state, sc->amr_drive[ldrv].al_properties); 660 } 661 free(aex, M_DEVBUF); 662 663 /* 664 * Get product info for channel count. 665 */ | 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) { |
667 device_printf(sc->amr_dev, "can't obtain product data from controller\n"); | 978 device_printf(sc->amr_dev, "can't obtain product data from controller\n"); |
668 mtx_unlock(&sc->amr_io_lock); | |
669 return(1); 670 } 671 sc->amr_maxdrives = 40; 672 sc->amr_maxchan = ap->ap_nschan; 673 sc->amr_maxio = ap->ap_maxio; 674 sc->amr_type |= AMR_TYPE_40LD; 675 free(ap, M_DEVBUF); 676 | 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 } |
|
677 } else { 678 679 /* failed, try the 8LD ENQUIRY commands */ | 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) { |
682 device_printf(sc->amr_dev, "can't obtain configuration data from controller\n"); | 998 device_printf(sc->amr_dev, "can't obtain configuration data from controller\n"); |
683 mtx_unlock(&sc->amr_io_lock); | |
684 return(1); 685 } 686 ae->ae_signature = 0; 687 } 688 689 /* 690 * Fetch current state of logical drives. 691 */ --- 18 unchanged lines hidden (view full) --- 710 sc->amr_drive[ldrv].al_size = 0xffffffff; 711 712 /* 713 * Cap the maximum number of outstanding I/Os. AMI's Linux driver doesn't trust 714 * the controller's reported value, and lockups have been seen when we do. 715 */ 716 sc->amr_maxio = imin(sc->amr_maxio, AMR_LIMITCMD); 717 | 999 return(1); 1000 } 1001 ae->ae_signature = 0; 1002 } 1003 1004 /* 1005 * Fetch current state of logical drives. 1006 */ --- 18 unchanged lines hidden (view full) --- 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); | |
719 return(0); 720} 721 722/******************************************************************************** 723 * Run a generic enquiry-style command. 724 */ 725static void * | 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) |
727{ 728 struct amr_command *ac; 729 void *result; 730 u_int8_t *mbox; 731 int error; 732 733 debug_called(1); 734 735 error = 1; 736 result = NULL; 737 738 /* get ourselves a command buffer */ | 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) |
740 goto out; 741 /* allocate the response structure */ 742 if ((result = malloc(bufsize, M_DEVBUF, M_ZERO|M_NOWAIT)) == NULL) 743 goto out; 744 /* set command flags */ 745 746 ac->ac_flags |= AMR_CMD_PRIORITY | AMR_CMD_DATAIN; 747 748 /* point the command at our data */ 749 ac->ac_data = result; 750 ac->ac_length = bufsize; 751 752 /* build the command proper */ 753 mbox = (u_int8_t *)&ac->ac_mailbox; /* XXX want a real structure for this? */ 754 mbox[0] = cmd; 755 mbox[2] = cmdsub; 756 mbox[3] = cmdqual; | 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; |
|
757 758 /* can't assume that interrupts are going to work here, so play it safe */ 759 if (sc->amr_poll_command(ac)) 760 goto out; 761 error = ac->ac_status; | 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; |
|
762 763 out: | 1081 1082 out: |
1083 mtx_lock(&sc->amr_list_lock); |
|
764 if (ac != NULL) 765 amr_releasecmd(ac); | 1084 if (ac != NULL) 1085 amr_releasecmd(ac); |
1086 mtx_unlock(&sc->amr_list_lock); |
|
766 if ((error != 0) && (result != NULL)) { 767 free(result, M_DEVBUF); 768 result = NULL; 769 } 770 return(result); 771} 772 773/******************************************************************************** 774 * Flush the controller's internal cache, return status. 775 */ 776int 777amr_flush(struct amr_softc *sc) 778{ 779 struct amr_command *ac; 780 int error; 781 782 /* get ourselves a command buffer */ 783 error = 1; | 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) |
786 goto out; 787 /* set command flags */ 788 ac->ac_flags |= AMR_CMD_PRIORITY | AMR_CMD_DATAOUT; 789 790 /* build the command proper */ 791 ac->ac_mailbox.mb_command = AMR_CMD_FLUSH; 792 793 /* we have to poll, as the system may be going down or otherwise damaged */ 794 if (sc->amr_poll_command(ac)) 795 goto out; 796 error = ac->ac_status; 797 798 out: | 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); |
|
799 if (ac != NULL) 800 amr_releasecmd(ac); | 1123 if (ac != NULL) 1124 amr_releasecmd(ac); |
801 mtx_unlock(&sc->amr_io_lock); | 1125 mtx_unlock(&sc->amr_list_lock); |
802 return(error); 803} 804 805/******************************************************************************** 806 * Detect extented cdb >> greater than 10 byte cdb support 807 * returns '1' means this support exist 808 * returns '0' means this support doesn't exist 809 */ 810static int 811amr_support_ext_cdb(struct amr_softc *sc) 812{ 813 struct amr_command *ac; 814 u_int8_t *mbox; 815 int error; 816 817 /* get ourselves a command buffer */ 818 error = 0; | 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) |
820 goto out; 821 /* set command flags */ 822 ac->ac_flags |= AMR_CMD_PRIORITY | AMR_CMD_DATAOUT; 823 824 /* build the command proper */ 825 mbox = (u_int8_t *)&ac->ac_mailbox; /* XXX want a real structure for this? */ 826 mbox[0] = 0xA4; 827 mbox[2] = 0x16; 828 829 830 /* we have to poll, as the system may be going down or otherwise damaged */ 831 if (sc->amr_poll_command(ac)) 832 goto out; 833 if( ac->ac_status == AMR_STATUS_SUCCESS ) { 834 error = 1; 835 } 836 837out: | 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); |
|
838 if (ac != NULL) 839 amr_releasecmd(ac); | 1166 if (ac != NULL) 1167 amr_releasecmd(ac); |
1168 mtx_unlock(&sc->amr_list_lock); |
|
840 return(error); 841} 842 843/******************************************************************************** 844 * Try to find I/O work for the controller from one or more of the work queues. 845 * 846 * We make the assumption that if the controller is not ready to take a command 847 * at some given time, it will generate an interrupt at some later time when --- 38 unchanged lines hidden (view full) --- 886} 887 888/******************************************************************************** 889 * Handle completion of an I/O command. 890 */ 891static void 892amr_completeio(struct amr_command *ac) 893{ | 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 --- 38 unchanged lines hidden (view full) --- 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; |
895 896 if (ac->ac_status != AMR_STATUS_SUCCESS) { /* could be more verbose here? */ 897 ac->ac_bio->bio_error = EIO; 898 ac->ac_bio->bio_flags |= BIO_ERROR; 899 | 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); |
901/* amr_printcommand(ac);*/ 902 } 903 amrd_intr(ac->ac_bio); | 1233/* amr_printcommand(ac);*/ 1234 } 1235 amrd_intr(ac->ac_bio); |
1236 mtx_lock(&ac->ac_sc->amr_list_lock); |
|
904 amr_releasecmd(ac); | 1237 amr_releasecmd(ac); |
1238 mtx_unlock(&ac->ac_sc->amr_list_lock); |
|
905} 906 907/******************************************************************************** 908 ******************************************************************************** 909 Command Processing 910 ******************************************************************************** 911 ********************************************************************************/ 912 --- 26 unchanged lines hidden (view full) --- 939 940 /* connect the bio to the command */ 941 ac->ac_complete = amr_completeio; 942 ac->ac_bio = bio; 943 ac->ac_data = bio->bio_data; 944 ac->ac_length = bio->bio_bcount; 945 if (bio->bio_cmd == BIO_READ) { 946 ac->ac_flags |= AMR_CMD_DATAIN; | 1239} 1240 1241/******************************************************************************** 1242 ******************************************************************************** 1243 Command Processing 1244 ******************************************************************************** 1245 ********************************************************************************/ 1246 --- 26 unchanged lines hidden (view full) --- 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; |
948 } else { 949 ac->ac_flags |= AMR_CMD_DATAOUT; | 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; |
951 } 952 amrd = (struct amrd_softc *)bio->bio_disk->d_drv1; 953 driveno = amrd->amrd_drive - sc->amr_drive; 954 blkcount = (bio->bio_bcount + AMR_BLKSIZE - 1) / AMR_BLKSIZE; 955 956 ac->ac_mailbox.mb_command = cmd; 957 ac->ac_mailbox.mb_blkcount = blkcount; 958 ac->ac_mailbox.mb_lba = bio->bio_pblkno; 959 ac->ac_mailbox.mb_drive = driveno; | 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 |
|
960 /* we fill in the s/g related data when the command is mapped */ 961 962 if ((bio->bio_pblkno + blkcount) > sc->amr_drive[driveno].al_size) 963 device_printf(sc->amr_dev, "I/O beyond end of unit (%lld,%d > %lu)\n", 964 (long long)bio->bio_pblkno, blkcount, 965 (u_long)sc->amr_drive[driveno].al_size); 966 967 *acp = ac; --- 8 unchanged lines hidden (view full) --- 976amr_wait_command(struct amr_command *ac) 977{ 978 int error = 0; 979 980 debug_called(1); 981 982 ac->ac_complete = NULL; 983 ac->ac_flags |= AMR_CMD_SLEEP; | 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; --- 8 unchanged lines hidden (view full) --- 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) { |
985 return(error); | 1330 return(error); |
1331 } |
|
986 987 while ((ac->ac_flags & AMR_CMD_BUSY) && (error != EWOULDBLOCK)) { | 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); |
989 } 990 return(error); 991} 992 993/******************************************************************************** 994 * Take a command, submit it to the controller and busy-wait for it to return. 995 * Returns nonzero on error. Can be safely called with interrupts enabled. 996 */ --- 28 unchanged lines hidden (view full) --- 1025 return(error); 1026} 1027 1028static void 1029amr_setup_polled_dmamap(void *arg, bus_dma_segment_t *segs, int nsegs, int err) 1030{ 1031 struct amr_command *ac = arg; 1032 struct amr_softc *sc = ac->ac_sc; | 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 */ --- 28 unchanged lines hidden (view full) --- 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; |
|
1033 | 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); |
1038 } | 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 } | |
1043 sc->amr_poll_command1(sc, ac); 1044} 1045 1046/******************************************************************************** 1047 * Take a command, submit it to the controller and busy-wait for it to return. 1048 * Returns nonzero on error. Can be safely called with interrupts enabled. 1049 */ 1050static int 1051amr_quartz_poll_command(struct amr_command *ac) 1052{ | 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; |
|
1053 struct amr_softc *sc = ac->ac_sc; 1054 int error; 1055 1056 debug_called(2); 1057 1058 error = 0; 1059 | 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 |
|
1060 /* now we have a slot, we can map the command (unmapped in amr_complete) */ 1061 if (ac->ac_data != 0) { | 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) { |
1064 error = 1; 1065 } 1066 } else { 1067 error = amr_quartz_poll_command1(sc, ac); 1068 } 1069 1070 return (error); 1071} 1072 1073static int 1074amr_quartz_poll_command1(struct amr_softc *sc, struct amr_command *ac) 1075{ 1076 int count, error; 1077 | 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); |
|
1078 if ((sc->amr_state & AMR_STATE_INTEN) == 0) { 1079 count=0; 1080 while (sc->amr_busyslots) { | 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); |
1082 if(count++>10) { 1083 break; 1084 } 1085 } 1086 1087 if(sc->amr_busyslots) { 1088 device_printf(sc->amr_dev, "adapter is busy\n"); | 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 } |
1091 ac->ac_status=0; 1092 return(1); 1093 } 1094 } 1095 1096 bcopy(&ac->ac_mailbox, (void *)(uintptr_t)(volatile void *)sc->amr_mailbox, AMR_MBOX_CMDSIZE); 1097 1098 /* clear the poll/ack fields in the mailbox */ --- 12 unchanged lines hidden (view full) --- 1111 error = (ac->ac_status !=AMR_STATUS_SUCCESS) ? 1:0; 1112 while(sc->amr_mailbox->mb_poll != 0x77); 1113 sc->amr_mailbox->mb_poll = 0; 1114 sc->amr_mailbox->mb_ack = 0x77; 1115 1116 /* acknowledge that we have the commands */ 1117 AMR_QPUT_IDB(sc, sc->amr_mailboxphys | AMR_QIDB_ACK); 1118 while(AMR_QGET_IDB(sc) & AMR_QIDB_ACK); | 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 */ --- 12 unchanged lines hidden (view full) --- 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); |
|
1119 1120 /* unmap the command's data buffer */ 1121 if (ac->ac_flags & AMR_CMD_DATAIN) { 1122 bus_dmamap_sync(sc->amr_buffer_dmat,ac->ac_dmamap, 1123 BUS_DMASYNC_POSTREAD); 1124 } 1125 if (ac->ac_flags & AMR_CMD_DATAOUT) { 1126 bus_dmamap_sync(sc->amr_buffer_dmat,ac->ac_dmamap, 1127 BUS_DMASYNC_POSTWRITE); 1128 } | 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); |
1130 1131 return(error); 1132} 1133 | 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) |
1141{ | 1507{ |
1142 struct amr_softc *sc = ac->ac_sc; 1143 int slot; | 1508 struct amr_softc *sc = ac->ac_sc; 1509 int slot; |
1144 1145 debug_called(3); 1146 1147 slot = ac->ac_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); |
1150 | 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); |
1153 1154 return (0); 1155} 1156 1157/******************************************************************************** 1158 * Map/unmap (ac)'s data in the controller's addressable space as required. 1159 * 1160 * These functions may be safely called multiple times on a given command. 1161 */ 1162static void 1163amr_setup_dmamap(void *arg, bus_dma_segment_t *segs, int nsegments, int error) 1164{ 1165 struct amr_command *ac = (struct amr_command *)arg; | 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; | |
1167 struct amr_sgentry *sg; 1168 int i; 1169 u_int8_t *sgc; 1170 1171 debug_called(3); 1172 1173 /* get base address of s/g table */ | 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; |
1175 1176 /* save data physical address */ | 1540 1541 /* save data physical address */ |
1177 ac->ac_dataphys = segs[0].ds_addr; | |
1178 | 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)) { |
1181 sgc = &(((struct amr_mailbox_ioctl *)&ac->ac_mailbox)->mb_param); 1182 } else { 1183 sgc = &ac->ac_mailbox.mb_nsgelem; 1184 } 1185 1186 /* decide whether we need to populate the s/g table */ 1187 if (nsegments < 2) { 1188 *sgc = 0; 1189 ac->ac_mailbox.mb_nsgelem = 0; | 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; |
1191 } else { 1192 ac->ac_mailbox.mb_nsgelem = nsegments; 1193 *sgc = nsegments; | 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; |
1196 for (i = 0; i < nsegments; i++, sg++) { 1197 sg->sg_addr = segs[i].ds_addr; 1198 sg->sg_count = segs[i].ds_len; 1199 } 1200 } 1201 1202} 1203 1204static void | 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 |
|
1205amr_setup_ccbmap(void *arg, bus_dma_segment_t *segs, int nsegments, int error) 1206{ 1207 struct amr_command *ac = (struct amr_command *)arg; 1208 struct amr_softc *sc = ac->ac_sc; 1209 struct amr_sgentry *sg; 1210 struct amr_passthrough *ap = (struct amr_passthrough *)ac->ac_data; 1211 struct amr_ext_passthrough *aep = (struct amr_ext_passthrough *)ac->ac_data; 1212 int i; 1213 1214 /* get base address of s/g table */ | 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; |
1216 1217 /* decide whether we need to populate the s/g table */ 1218 if( ac->ac_mailbox.mb_command == AMR_CMD_EXTPASS ) { 1219 if (nsegments < 2) { 1220 aep->ap_no_sg_elements = 0; 1221 aep->ap_data_transfer_address = segs[0].ds_addr; 1222 } else { 1223 /* save s/g table information in passthrough */ 1224 aep->ap_no_sg_elements = nsegments; | 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; |
1227 /* 1228 * populate s/g table (overwrites previous call which mapped the 1229 * passthrough) 1230 */ 1231 for (i = 0; i < nsegments; i++, sg++) { 1232 sg->sg_addr = segs[i].ds_addr; 1233 sg->sg_count = segs[i].ds_len; 1234 debug(3, " %d: 0x%x/%d", i, sg->sg_addr, sg->sg_count); 1235 } 1236 } | 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); |
1240 } else { 1241 if (nsegments < 2) { 1242 ap->ap_no_sg_elements = 0; 1243 ap->ap_data_transfer_address = segs[0].ds_addr; 1244 } else { 1245 /* save s/g table information in passthrough */ 1246 ap->ap_no_sg_elements = nsegments; | 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; |
1249 /* 1250 * populate s/g table (overwrites previous call which mapped the 1251 * passthrough) 1252 */ 1253 for (i = 0; i < nsegments; i++, sg++) { 1254 sg->sg_addr = segs[i].ds_addr; 1255 sg->sg_count = segs[i].ds_len; 1256 debug(3, " %d: 0x%x/%d", i, sg->sg_addr, sg->sg_count); 1257 } 1258 } | 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); |
1262 } 1263 if (ac->ac_flags & AMR_CMD_CCB_DATAIN) 1264 bus_dmamap_sync(sc->amr_buffer_dmat, ac->ac_ccb_dmamap, 1265 BUS_DMASYNC_PREREAD); 1266 if (ac->ac_flags & AMR_CMD_CCB_DATAOUT) 1267 bus_dmamap_sync(sc->amr_buffer_dmat, ac->ac_ccb_dmamap, 1268 BUS_DMASYNC_PREWRITE); 1269 if ((ac->ac_flags & (AMR_CMD_CCB_DATAIN | AMR_CMD_CCB_DATAOUT)) == 0) 1270 panic("no direction for ccb?\n"); 1271 1272 if (ac->ac_flags & AMR_CMD_DATAIN) 1273 bus_dmamap_sync(sc->amr_buffer_dmat,ac->ac_dmamap,BUS_DMASYNC_PREREAD); 1274 if (ac->ac_flags & AMR_CMD_DATAOUT) 1275 bus_dmamap_sync(sc->amr_buffer_dmat,ac->ac_dmamap,BUS_DMASYNC_PREWRITE); 1276 1277 ac->ac_flags |= AMR_CMD_MAPPED; 1278 | 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 } |
1280} 1281 | 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 |
|
1282static int 1283amr_mapcmd(struct amr_command *ac) 1284{ | 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; |
|
1285 struct amr_softc *sc = ac->ac_sc; 1286 1287 debug_called(3); 1288 | 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 |
|
1289 /* if the command involves data at all, and hasn't been mapped */ 1290 if ((ac->ac_flags & AMR_CMD_MAPPED) == 0 && (ac->ac_data != NULL)) { 1291 if (ac->ac_ccb_data == NULL) { 1292 /* map the data buffers into bus space and build the s/g list */ | 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) { |
1295 sc->amr_state |= AMR_STATE_QUEUE_FRZN; 1296 } 1297 } else { | 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) { |
1300 return (ENOMEM); 1301 } | 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) { |
1305 sc->amr_state |= AMR_STATE_QUEUE_FRZN; 1306 } 1307 } | 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 } |
1310 } 1311 1312 return (0); 1313} 1314 1315static void 1316amr_unmapcmd(struct amr_command *ac) 1317{ 1318 struct amr_softc *sc = ac->ac_sc; | 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; |
|
1319 1320 debug_called(3); 1321 1322 /* if the command involved data at all and was mapped */ 1323 if (ac->ac_flags & AMR_CMD_MAPPED) { 1324 1325 if (ac->ac_data != NULL) { | 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; |
|
1326 if (ac->ac_flags & AMR_CMD_DATAIN) | 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; |
1329 if (ac->ac_flags & AMR_CMD_DATAOUT) | 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 } |
1333 } 1334 1335 if (ac->ac_ccb_data != NULL) { | 1832 } 1833 1834 if (ac->ac_ccb_data != NULL) { |
1835 1836 flag = 0; |
|
1336 if (ac->ac_flags & AMR_CMD_CCB_DATAIN) | 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; |
1339 if (ac->ac_flags & AMR_CMD_CCB_DATAOUT) | 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 } |
1343 } 1344 ac->ac_flags &= ~AMR_CMD_MAPPED; 1345 } 1346} 1347 1348static void 1349amr_setup_data_dmamap(void *arg, bus_dma_segment_t *segs, int nsegs, int err) 1350{ 1351 struct amr_command *ac = arg; 1352 struct amr_softc *sc = ac->ac_sc; | 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; |
|
1353 | 1860 |
1354 amr_setup_dmamap(arg, segs, nsegs, err); 1355 | 1861 flags = 0; |
1356 if (ac->ac_flags & AMR_CMD_DATAIN) | 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; |
1358 if (ac->ac_flags & AMR_CMD_DATAOUT) | 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 } |
1360 ac->ac_flags |= AMR_CMD_MAPPED; 1361 | 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 } |
1363} 1364 1365/******************************************************************************** 1366 * Take a command and give it to the controller, returns 0 if successful, or 1367 * EBUSY if the command should be retried later. 1368 */ 1369static int 1370amr_start(struct amr_command *ac) 1371{ 1372 struct amr_softc *sc; 1373 int error = 0; | 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; |
|
1374 1375 debug_called(3); 1376 1377 /* mark command as busy so that polling consumer can tell */ 1378 sc = ac->ac_sc; 1379 ac->ac_flags |= AMR_CMD_BUSY; 1380 1381 /* get a command slot (freed in amr_done) */ | 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); |
1385 1386 /* Now we have a slot, we can map the command (unmapped in amr_complete). */ 1387 if ((error = amr_mapcmd(ac)) == ENOMEM) { 1388 /* 1389 * Memroy resources are short, so free the slot and let this be tried 1390 * later. 1391 */ | 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); |
1394 } 1395 1396 return (error); 1397} 1398 1399 1400static int 1401amr_start1(struct amr_softc *sc, struct amr_command *ac) 1402{ | 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 } |
1404 | 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 | |
1412 /* 1413 * Save the slot number so that we can locate this command when complete. 1414 * Note that ident = 0 seems to be special, so we don't use it. 1415 */ | 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; |
1417 | 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); |
1441 } 1442 | 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); |
1461} 1462 1463/******************************************************************************** 1464 * Extract one or more completed commands from the controller (sc) 1465 * 1466 * Returns nonzero if any commands on the work queue were marked as completed. 1467 */ 1468 --- 20 unchanged lines hidden (view full) --- 1489 /* get pointer to busy command */ 1490 idx = mbox.mb_completed[i] - 1; 1491 ac = sc->amr_busycmd[idx]; 1492 1493 /* really a busy command? */ 1494 if (ac != NULL) { 1495 1496 /* pull the command from the busy index */ | 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 --- 20 unchanged lines hidden (view full) --- 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); |
1499 1500 /* save status for later use */ 1501 ac->ac_status = mbox.mb_status; 1502 amr_enqueue_completed(ac); 1503 debug(3, "completed command with status %x", mbox.mb_status); 1504 } else { 1505 device_printf(sc->amr_dev, "bad slot %d completed\n", idx); 1506 } 1507 } | 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 |
1509 break; /* no work */ | 2000 break; /* no work */ |
1510 } | |
1511 } 1512 1513 /* handle completion and timeouts */ 1514 amr_complete(sc, 0); 1515 1516 return(result); 1517} 1518 --- 34 unchanged lines hidden (view full) --- 1553 wakeup(ac); 1554 } 1555 1556 if(!sc->amr_busyslots) { 1557 wakeup(sc); 1558 } 1559 } 1560 | 2001 } 2002 2003 /* handle completion and timeouts */ 2004 amr_complete(sc, 0); 2005 2006 return(result); 2007} 2008 --- 34 unchanged lines hidden (view full) --- 2043 wakeup(ac); 2044 } 2045 2046 if(!sc->amr_busyslots) { 2047 wakeup(sc); 2048 } 2049 } 2050 |
2051 mtx_lock(&sc->amr_list_lock); |
|
1561 sc->amr_state &= ~AMR_STATE_QUEUE_FRZN; 1562 amr_startio(sc); | 2052 sc->amr_state &= ~AMR_STATE_QUEUE_FRZN; 2053 amr_startio(sc); |
2054 mtx_unlock(&sc->amr_list_lock); |
|
1563} 1564 1565/******************************************************************************** 1566 ******************************************************************************** 1567 Command Buffer Management 1568 ******************************************************************************** 1569 ********************************************************************************/ 1570 --- 58 unchanged lines hidden (view full) --- 1629 acc = malloc(AMR_CMD_CLUSTERSIZE, M_DEVBUF, M_NOWAIT | M_ZERO); 1630 if (acc != NULL) { 1631 nextslot = sc->amr_nextslot; 1632 TAILQ_INSERT_TAIL(&sc->amr_cmd_clusters, acc, acc_link); 1633 for (i = 0; i < AMR_CMD_CLUSTERCOUNT; i++) { 1634 ac = &acc->acc_command[i]; 1635 ac->ac_sc = sc; 1636 ac->ac_slot = nextslot; | 2055} 2056 2057/******************************************************************************** 2058 ******************************************************************************** 2059 Command Buffer Management 2060 ******************************************************************************** 2061 ********************************************************************************/ 2062 --- 58 unchanged lines hidden (view full) --- 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); |
1640 if (++nextslot > sc->amr_maxio) 1641 break; 1642 } 1643 sc->amr_nextslot = nextslot; 1644 } 1645} 1646 1647/******************************************************************************** 1648 * Free a command cluster 1649 */ 1650static void 1651amr_freecmd_cluster(struct amr_command_cluster *acc) 1652{ 1653 struct amr_softc *sc = acc->acc_command[0].ac_sc; 1654 int i; 1655 | 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++) { |
1657 bus_dmamap_destroy(sc->amr_buffer_dmat, acc->acc_command[i].ac_dmamap); | 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 } |
|
1658 free(acc, M_DEVBUF); 1659} 1660 1661/******************************************************************************** 1662 ******************************************************************************** 1663 Interface-specific Shims 1664 ******************************************************************************** 1665 ********************************************************************************/ 1666 1667/******************************************************************************** 1668 * Tell the controller that the mailbox contains a valid command 1669 */ 1670static int 1671amr_quartz_submit_command(struct amr_softc *sc) 1672{ 1673 debug_called(3); 1674 | 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 |
|
1675 if (AMR_QGET_IDB(sc) & AMR_QIDB_SUBMIT) 1676 return(EBUSY); | 2194 if (AMR_QGET_IDB(sc) & AMR_QIDB_SUBMIT) 2195 return(EBUSY); |
2196#endif |
|
1677 AMR_QPUT_IDB(sc, sc->amr_mailboxphys | AMR_QIDB_SUBMIT); 1678 return(0); 1679} 1680 1681static int 1682amr_std_submit_command(struct amr_softc *sc) 1683{ 1684 debug_called(3); --- 6 unchanged lines hidden (view full) --- 1691 1692/******************************************************************************** 1693 * Claim any work that the controller has completed; acknowledge completion, 1694 * save details of the completion in (mbsave) 1695 */ 1696static int 1697amr_quartz_get_work(struct amr_softc *sc, struct amr_mailbox *mbsave) 1698{ | 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); --- 6 unchanged lines hidden (view full) --- 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; |
1700 u_int32_t outd; | 2220 u_int32_t outd; |
1701 u_int8_t nstatus; | 2221 u_int8_t nstatus ,status; 2222 u_int8_t completed[46]; |
1702 1703 debug_called(3); 1704 1705 worked = 0; 1706 1707 /* work waiting for us? */ 1708 if ((outd = AMR_QGET_ODB(sc)) == AMR_QODB_READY) { 1709 1710 /* acknowledge interrupt */ 1711 AMR_QPUT_ODB(sc, AMR_QODB_READY); 1712 1713 while ((nstatus = sc->amr_mailbox->mb_nstatus) == 0xff) | 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(); |
1715 sc->amr_mailbox->mb_nstatus = 0xff; 1716 | 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 */ |
1719 mbsave->mb_nstatus = nstatus; | 2253 mbsave->mb_nstatus = nstatus; |
2254 mbsave->mb_status = status; 2255 for (i = 0; i < nstatus; i++) 2256 mbsave->mb_completed[i] = completed[i]; |
|
1720 1721 /* acknowledge that we have the commands */ 1722 AMR_QPUT_IDB(sc, AMR_QIDB_ACK); 1723 | 2257 2258 /* acknowledge that we have the commands */ 2259 AMR_QPUT_IDB(sc, AMR_QIDB_ACK); 2260 |
2261#if 0 |
|
1724#ifndef AMR_QUARTZ_GOFASTER 1725 /* 1726 * This waits for the controller to notice that we've taken the 1727 * command from it. It's very inefficient, and we shouldn't do it, 1728 * but if we remove this code, we stop completing commands under 1729 * load. 1730 * 1731 * Peter J says we shouldn't do this. The documentation says we 1732 * should. Who is right? 1733 */ 1734 while(AMR_QGET_IDB(sc) & AMR_QIDB_ACK) 1735 ; /* XXX aiee! what if it dies? */ 1736#endif | 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 |
|
1737 1738 worked = 1; /* got some work */ 1739 } 1740 1741 return(worked); 1742} 1743 1744static int --- 109 unchanged lines hidden (view full) --- 1854 * Identify the controller and print some information about it. 1855 */ 1856static void 1857amr_describe_controller(struct amr_softc *sc) 1858{ 1859 struct amr_prodinfo *ap; 1860 struct amr_enquiry *ae; 1861 char *prod; | 2276 2277 worked = 1; /* got some work */ 2278 } 2279 2280 return(worked); 2281} 2282 2283static int --- 109 unchanged lines hidden (view full) --- 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; |
|
1862 | 2402 |
1863 mtx_lock(&sc->amr_io_lock); | |
1864 /* 1865 * Try to get 40LD product info, which tells us what the card is labelled as. 1866 */ | 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) { |
1868 device_printf(sc->amr_dev, "<LSILogic %.80s> Firmware %.16s, BIOS %.16s, %dMB RAM\n", 1869 ap->ap_product, ap->ap_firmware, ap->ap_bios, 1870 ap->ap_memsize); 1871 1872 free(ap, M_DEVBUF); | 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); | |
1874 return; 1875 } 1876 1877 /* 1878 * Try 8LD extended ENQUIRY to get controller signature, and use lookup table. 1879 */ | 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) { |
1881 prod = amr_describe_code(amr_table_adaptertype, ae->ae_signature); 1882 | 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) { |
1884 1885 /* 1886 * Try to work it out based on the PCI signatures. 1887 */ 1888 switch (pci_get_device(sc->amr_dev)) { 1889 case 0x9010: 1890 prod = "Series 428"; 1891 break; 1892 case 0x9060: 1893 prod = "Series 434"; 1894 break; 1895 default: 1896 prod = "unknown controller"; 1897 break; 1898 } 1899 } else { 1900 device_printf(sc->amr_dev, "<unsupported controller>\n"); | 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); | |
1902 return; 1903 } 1904 1905 /* 1906 * HP NetRaid controllers have a special encoding of the firmware and 1907 * BIOS versions. The AMI version seems to have it as strings whereas 1908 * the HP version does it with a leading uppercase character and two 1909 * binary numbers. --- 24 unchanged lines hidden (view full) --- 1934 ae->ae_adapter.aa_bios[0], 1935 ae->ae_adapter.aa_memorysize); 1936 } else { 1937 device_printf(sc->amr_dev, "<%s> Firmware %.4s, BIOS %.4s, %dMB RAM\n", 1938 prod, ae->ae_adapter.aa_firmware, ae->ae_adapter.aa_bios, 1939 ae->ae_adapter.aa_memorysize); 1940 } 1941 free(ae, M_DEVBUF); | 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. --- 24 unchanged lines hidden (view full) --- 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); | |
1943} 1944 1945int 1946amr_dump_blocks(struct amr_softc *sc, int unit, u_int32_t lba, void *data, int blks) 1947{ 1948 struct amr_command *ac; 1949 int error = EIO; 1950 --- 63 unchanged lines hidden --- | 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 --- 63 unchanged lines hidden --- |