amr.c (174194) | amr.c (174544) |
---|---|
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 174194 2007-12-02 19:54:45Z scottl $"); | 59__FBSDID("$FreeBSD: head/sys/dev/amr/amr.c 174544 2007-12-12 05:55:03Z 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> --- 67 unchanged lines hidden (view full) --- 135 * Command processing. 136 */ 137static int amr_bio_command(struct amr_softc *sc, struct amr_command **acp); 138static int amr_wait_command(struct amr_command *ac) __unused; 139static int amr_mapcmd(struct amr_command *ac); 140static void amr_unmapcmd(struct amr_command *ac); 141static int amr_start(struct amr_command *ac); 142static void amr_complete(void *context, int pending); | 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> --- 67 unchanged lines hidden (view full) --- 135 * Command processing. 136 */ 137static int amr_bio_command(struct amr_softc *sc, struct amr_command **acp); 138static int amr_wait_command(struct amr_command *ac) __unused; 139static int amr_mapcmd(struct amr_command *ac); 140static void amr_unmapcmd(struct amr_command *ac); 141static int amr_start(struct amr_command *ac); 142static void amr_complete(void *context, int pending); |
143static void amr_setup_dmamap(void *arg, bus_dma_segment_t *segs, int nsegments, int error); 144static void amr_setup_dma64map(void *arg, bus_dma_segment_t *segs, int nsegments, int error); 145static void amr_setup_data_dmamap(void *arg, bus_dma_segment_t *segs, int nsegments, int error); | 143static void amr_setup_sg(void *arg, bus_dma_segment_t *segs, int nsegments, int error); 144static void amr_setup_data(void *arg, bus_dma_segment_t *segs, int nsegments, int error); 145static void amr_setup_ccb(void *arg, bus_dma_segment_t *segs, int nsegments, int error); |
146 147/* 148 * Status monitoring 149 */ 150static void amr_periodic(void *data); 151 152/* 153 * Interface-specific shims --- 413 unchanged lines hidden (view full) --- 567 case 0x81: 568 if (ali.ui.fcs.opcode == 0x80) 569 len = max(ali.outlen, ali.inlen); 570 else 571 len = ali.ui.fcs.length; 572 573 adapter = (ali.ui.fcs.adapno) ^ 'm' << 8; 574 | 146 147/* 148 * Status monitoring 149 */ 150static void amr_periodic(void *data); 151 152/* 153 * Interface-specific shims --- 413 unchanged lines hidden (view full) --- 567 case 0x81: 568 if (ali.ui.fcs.opcode == 0x80) 569 len = max(ali.outlen, ali.inlen); 570 else 571 len = ali.ui.fcs.length; 572 573 adapter = (ali.ui.fcs.adapno) ^ 'm' << 8; 574 |
575 ap = malloc(sizeof(struct amr_passthrough), 576 M_AMR, M_WAITOK | M_ZERO); 577 | |
578 mb = (void *)&ali.mbox[0]; 579 580 if ((ali.mbox[0] == FC_DEL_LOGDRV && ali.mbox[2] == OP_DEL_LOGDRV) || /* delete */ 581 (ali.mbox[0] == AMR_CMD_CONFIG && ali.mbox[2] == 0x0d)) { /* create */ 582 if (sc->amr_allow_vol_config == 0) { 583 error = EPERM; 584 break; 585 } 586 logical_drives_changed = 1; 587 } 588 589 if (ali.mbox[0] == AMR_CMD_PASS) { | 575 mb = (void *)&ali.mbox[0]; 576 577 if ((ali.mbox[0] == FC_DEL_LOGDRV && ali.mbox[2] == OP_DEL_LOGDRV) || /* delete */ 578 (ali.mbox[0] == AMR_CMD_CONFIG && ali.mbox[2] == 0x0d)) { /* create */ 579 if (sc->amr_allow_vol_config == 0) { 580 error = EPERM; 581 break; 582 } 583 logical_drives_changed = 1; 584 } 585 586 if (ali.mbox[0] == AMR_CMD_PASS) { |
587 mtx_lock(&sc->amr_list_lock); 588 while ((ac = amr_alloccmd(sc)) == NULL) 589 msleep(sc, &sc->amr_list_lock, PPAUSE, "amrioc", hz); 590 mtx_unlock(&sc->amr_list_lock); 591 ap = &ac->ac_ccb->ccb_pthru; 592 |
|
590 error = copyin((void *)(uintptr_t)mb->mb_physaddr, ap, 591 sizeof(struct amr_passthrough)); 592 if (error) 593 break; 594 595 if (ap->ap_data_transfer_length) 596 dp = malloc(ap->ap_data_transfer_length, M_AMR, 597 M_WAITOK | M_ZERO); 598 599 if (ali.inlen) { 600 error = copyin((void *)(uintptr_t)ap->ap_data_transfer_address, 601 dp, ap->ap_data_transfer_length); 602 if (error) 603 break; 604 } 605 | 593 error = copyin((void *)(uintptr_t)mb->mb_physaddr, ap, 594 sizeof(struct amr_passthrough)); 595 if (error) 596 break; 597 598 if (ap->ap_data_transfer_length) 599 dp = malloc(ap->ap_data_transfer_length, M_AMR, 600 M_WAITOK | M_ZERO); 601 602 if (ali.inlen) { 603 error = copyin((void *)(uintptr_t)ap->ap_data_transfer_address, 604 dp, ap->ap_data_transfer_length); 605 if (error) 606 break; 607 } 608 |
606 mtx_lock(&sc->amr_list_lock); 607 while ((ac = amr_alloccmd(sc)) == NULL) 608 msleep(sc, &sc->amr_list_lock, PPAUSE, "amrioc", hz); 609 610 ac_flags = AMR_CMD_DATAIN|AMR_CMD_DATAOUT|AMR_CMD_CCB_DATAIN|AMR_CMD_CCB_DATAOUT; | 609 ac_flags = AMR_CMD_DATAIN|AMR_CMD_DATAOUT|AMR_CMD_CCB; |
611 bzero(&ac->ac_mailbox, sizeof(ac->ac_mailbox)); 612 ac->ac_mailbox.mb_command = AMR_CMD_PASS; 613 ac->ac_flags = ac_flags; 614 | 610 bzero(&ac->ac_mailbox, sizeof(ac->ac_mailbox)); 611 ac->ac_mailbox.mb_command = AMR_CMD_PASS; 612 ac->ac_flags = ac_flags; 613 |
615 ac->ac_data = ap; 616 ac->ac_length = sizeof(struct amr_passthrough); 617 ac->ac_ccb_data = dp; 618 ac->ac_ccb_length = ap->ap_data_transfer_length; | 614 ac->ac_data = dp; 615 ac->ac_length = ap->ap_data_transfer_length; |
619 temp = (void *)(uintptr_t)ap->ap_data_transfer_address; 620 | 616 temp = (void *)(uintptr_t)ap->ap_data_transfer_address; 617 |
618 mtx_lock(&sc->amr_list_lock); |
|
621 error = amr_wait_command(ac); 622 mtx_unlock(&sc->amr_list_lock); 623 if (error) 624 break; 625 626 status = ac->ac_status; 627 error = copyout(&status, &((struct amr_passthrough *)(uintptr_t)mb->mb_physaddr)->ap_scsi_status, sizeof(status)); 628 if (error) --- 72 unchanged lines hidden (view full) --- 701 * objects have been allocated. 702 */ 703 mtx_lock(&sc->amr_list_lock); 704 if (ac != NULL) 705 amr_releasecmd(ac); 706 mtx_unlock(&sc->amr_list_lock); 707 if (dp != NULL) 708 free(dp, M_AMR); | 619 error = amr_wait_command(ac); 620 mtx_unlock(&sc->amr_list_lock); 621 if (error) 622 break; 623 624 status = ac->ac_status; 625 error = copyout(&status, &((struct amr_passthrough *)(uintptr_t)mb->mb_physaddr)->ap_scsi_status, sizeof(status)); 626 if (error) --- 72 unchanged lines hidden (view full) --- 699 * objects have been allocated. 700 */ 701 mtx_lock(&sc->amr_list_lock); 702 if (ac != NULL) 703 amr_releasecmd(ac); 704 mtx_unlock(&sc->amr_list_lock); 705 if (dp != NULL) 706 free(dp, M_AMR); |
709 if (ap != NULL) 710 free(ap, M_AMR); | |
711 return(error); 712} 713 714static int 715amr_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int32_t flag, d_thread_t *td) 716{ 717 struct amr_softc *sc = (struct amr_softc *)dev->si_drv1; 718 union { --- 5 unchanged lines hidden (view full) --- 724 int *result; 725 } arg; 726 struct amr_command *ac; 727 struct amr_mailbox_ioctl *mbi; 728 void *dp, *au_buffer; 729 unsigned long au_length; 730 unsigned char *au_cmd; 731 int *au_statusp, au_direction; | 707 return(error); 708} 709 710static int 711amr_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int32_t flag, d_thread_t *td) 712{ 713 struct amr_softc *sc = (struct amr_softc *)dev->si_drv1; 714 union { --- 5 unchanged lines hidden (view full) --- 720 int *result; 721 } arg; 722 struct amr_command *ac; 723 struct amr_mailbox_ioctl *mbi; 724 void *dp, *au_buffer; 725 unsigned long au_length; 726 unsigned char *au_cmd; 727 int *au_statusp, au_direction; |
732 int error, ac_flags = 0; | 728 int error; |
733 struct amr_passthrough *ap; /* 60 bytes */ 734 int logical_drives_changed = 0; 735 736 debug_called(1); 737 738 arg._p = (void *)addr; 739 740 error = 0; --- 86 unchanged lines hidden (view full) --- 827 if ((error = copyin(au_buffer, dp, au_length)) != 0) { 828 free(dp, M_AMR); 829 return (error); 830 } 831 debug(2, "copyin %ld bytes from %p -> %p", au_length, au_buffer, dp); 832 } 833 834 /* Allocate this now before the mutex gets held */ | 729 struct amr_passthrough *ap; /* 60 bytes */ 730 int logical_drives_changed = 0; 731 732 debug_called(1); 733 734 arg._p = (void *)addr; 735 736 error = 0; --- 86 unchanged lines hidden (view full) --- 823 if ((error = copyin(au_buffer, dp, au_length)) != 0) { 824 free(dp, M_AMR); 825 return (error); 826 } 827 debug(2, "copyin %ld bytes from %p -> %p", au_length, au_buffer, dp); 828 } 829 830 /* Allocate this now before the mutex gets held */ |
835 if (au_cmd[0] == AMR_CMD_PASS) 836 ap = malloc(sizeof(struct amr_passthrough), M_AMR, M_WAITOK|M_ZERO); | |
837 838 mtx_lock(&sc->amr_list_lock); 839 while ((ac = amr_alloccmd(sc)) == NULL) 840 msleep(sc, &sc->amr_list_lock, PPAUSE, "amrioc", hz); 841 842 /* handle SCSI passthrough command */ 843 if (au_cmd[0] == AMR_CMD_PASS) { 844 int len; 845 | 831 832 mtx_lock(&sc->amr_list_lock); 833 while ((ac = amr_alloccmd(sc)) == NULL) 834 msleep(sc, &sc->amr_list_lock, PPAUSE, "amrioc", hz); 835 836 /* handle SCSI passthrough command */ 837 if (au_cmd[0] == AMR_CMD_PASS) { 838 int len; 839 |
840 ap = &ac->ac_ccb->ccb_pthru; 841 bzero(ap, sizeof(struct amr_passthrough)); 842 |
|
846 /* copy cdb */ 847 len = au_cmd[2]; 848 ap->ap_cdb_length = len; 849 bcopy(au_cmd + 3, ap->ap_cdb, len); 850 851 /* build passthrough */ 852 ap->ap_timeout = au_cmd[len + 3] & 0x07; 853 ap->ap_ars = (au_cmd[len + 3] & 0x08) ? 1 : 0; 854 ap->ap_islogical = (au_cmd[len + 3] & 0x80) ? 1 : 0; 855 ap->ap_logical_drive_no = au_cmd[len + 4]; 856 ap->ap_channel = au_cmd[len + 5]; 857 ap->ap_scsi_id = au_cmd[len + 6]; 858 ap->ap_request_sense_length = 14; 859 ap->ap_data_transfer_length = au_length; 860 /* XXX what about the request-sense area? does the caller want it? */ 861 862 /* build command */ | 843 /* copy cdb */ 844 len = au_cmd[2]; 845 ap->ap_cdb_length = len; 846 bcopy(au_cmd + 3, ap->ap_cdb, len); 847 848 /* build passthrough */ 849 ap->ap_timeout = au_cmd[len + 3] & 0x07; 850 ap->ap_ars = (au_cmd[len + 3] & 0x08) ? 1 : 0; 851 ap->ap_islogical = (au_cmd[len + 3] & 0x80) ? 1 : 0; 852 ap->ap_logical_drive_no = au_cmd[len + 4]; 853 ap->ap_channel = au_cmd[len + 5]; 854 ap->ap_scsi_id = au_cmd[len + 6]; 855 ap->ap_request_sense_length = 14; 856 ap->ap_data_transfer_length = au_length; 857 /* XXX what about the request-sense area? does the caller want it? */ 858 859 /* build command */ |
863 ac->ac_data = ap; 864 ac->ac_length = sizeof(struct amr_passthrough); 865 ac->ac_ccb_data = dp; 866 ac->ac_ccb_length = au_length; 867 | |
868 ac->ac_mailbox.mb_command = AMR_CMD_PASS; | 860 ac->ac_mailbox.mb_command = AMR_CMD_PASS; |
869 ac_flags = AMR_CMD_DATAIN|AMR_CMD_DATAOUT|AMR_CMD_CCB_DATAIN|AMR_CMD_CCB_DATAOUT; | 861 ac->ac_flags = AMR_CMD_CCB; |
870 871 } else { 872 /* direct command to controller */ 873 mbi = (struct amr_mailbox_ioctl *)&ac->ac_mailbox; 874 875 /* copy pertinent mailbox items */ 876 mbi->mb_command = au_cmd[0]; 877 mbi->mb_channel = au_cmd[1]; 878 mbi->mb_param = au_cmd[2]; 879 mbi->mb_pad[0] = au_cmd[3]; 880 mbi->mb_drive = au_cmd[4]; | 862 863 } else { 864 /* direct command to controller */ 865 mbi = (struct amr_mailbox_ioctl *)&ac->ac_mailbox; 866 867 /* copy pertinent mailbox items */ 868 mbi->mb_command = au_cmd[0]; 869 mbi->mb_channel = au_cmd[1]; 870 mbi->mb_param = au_cmd[2]; 871 mbi->mb_pad[0] = au_cmd[3]; 872 mbi->mb_drive = au_cmd[4]; |
881 882 /* build the command */ 883 ac->ac_data = dp; 884 ac->ac_length = au_length; 885 ac_flags = AMR_CMD_DATAIN|AMR_CMD_DATAOUT; | 873 ac->ac_flags = 0; |
886 } 887 | 874 } 875 |
888 ac->ac_flags = ac_flags; | 876 /* build the command */ 877 ac->ac_data = dp; 878 ac->ac_length = au_length; 879 ac->ac_flags |= AMR_CMD_DATAIN|AMR_CMD_DATAOUT; |
889 890 /* run the command */ 891 error = amr_wait_command(ac); 892 mtx_unlock(&sc->amr_list_lock); 893 if (error) 894 goto out; 895 896 /* copy out data and set status */ 897 if (au_length != 0) { 898 error = copyout(dp, au_buffer, au_length); 899 } 900 debug(2, "copyout %ld bytes from %p -> %p", au_length, dp, au_buffer); 901 if (dp != NULL) | 880 881 /* run the command */ 882 error = amr_wait_command(ac); 883 mtx_unlock(&sc->amr_list_lock); 884 if (error) 885 goto out; 886 887 /* copy out data and set status */ 888 if (au_length != 0) { 889 error = copyout(dp, au_buffer, au_length); 890 } 891 debug(2, "copyout %ld bytes from %p -> %p", au_length, dp, au_buffer); 892 if (dp != NULL) |
902 debug(2, "%jd", (uintptr_t)dp); | 893 debug(2, "%p status 0x%x", dp, ac->ac_status); |
903 *au_statusp = ac->ac_status; 904 905out: 906 /* 907 * At this point, we know that there is a lock held and that these 908 * objects have been allocated. 909 */ 910 mtx_lock(&sc->amr_list_lock); 911 if (ac != NULL) 912 amr_releasecmd(ac); 913 mtx_unlock(&sc->amr_list_lock); 914 if (dp != NULL) 915 free(dp, M_AMR); | 894 *au_statusp = ac->ac_status; 895 896out: 897 /* 898 * At this point, we know that there is a lock held and that these 899 * objects have been allocated. 900 */ 901 mtx_lock(&sc->amr_list_lock); 902 if (ac != NULL) 903 amr_releasecmd(ac); 904 mtx_unlock(&sc->amr_list_lock); 905 if (dp != NULL) 906 free(dp, M_AMR); |
916 if (ap != NULL) 917 free(ap, M_AMR); | |
918 919#ifndef LSI 920 if (logical_drives_changed) 921 amr_rescan_drives(dev); 922#endif 923 924 return(error); 925} --- 489 unchanged lines hidden (view full) --- 1415 return(error); 1416} 1417 1418static void 1419amr_setup_polled_dmamap(void *arg, bus_dma_segment_t *segs, int nsegs, int err) 1420{ 1421 struct amr_command *ac = arg; 1422 struct amr_softc *sc = ac->ac_sc; | 907 908#ifndef LSI 909 if (logical_drives_changed) 910 amr_rescan_drives(dev); 911#endif 912 913 return(error); 914} --- 489 unchanged lines hidden (view full) --- 1404 return(error); 1405} 1406 1407static void 1408amr_setup_polled_dmamap(void *arg, bus_dma_segment_t *segs, int nsegs, int err) 1409{ 1410 struct amr_command *ac = arg; 1411 struct amr_softc *sc = ac->ac_sc; |
1423 int flags; | 1412 int mb_channel; |
1424 | 1413 |
1425 flags = 0; 1426 if (ac->ac_flags & AMR_CMD_DATAIN) 1427 flags |= BUS_DMASYNC_PREREAD; 1428 if (ac->ac_flags & AMR_CMD_DATAOUT) 1429 flags |= BUS_DMASYNC_PREWRITE; | 1414 amr_setup_sg(arg, segs, nsegs, err); |
1430 | 1415 |
1416 /* for AMR_CMD_CONFIG Read/Write the s/g count goes elsewhere */ 1417 mb_channel = ((struct amr_mailbox_ioctl *)&ac->ac_mailbox)->mb_channel; 1418 if (ac->ac_mailbox.mb_command == AMR_CMD_CONFIG && 1419 ((mb_channel == AMR_CONFIG_READ_NVRAM_CONFIG) || 1420 (mb_channel == AMR_CONFIG_WRITE_NVRAM_CONFIG))) 1421 ((struct amr_mailbox_ioctl *)&ac->ac_mailbox)->mb_param = ac->ac_nsegments; 1422 1423 ac->ac_mailbox.mb_nsgelem = ac->ac_nsegments; 1424 ac->ac_mailbox.mb_physaddr = ac->ac_mb_physaddr; |
|
1431 if (AC_IS_SG64(ac)) { | 1425 if (AC_IS_SG64(ac)) { |
1432 amr_setup_dma64map(arg, segs, nsegs, err); 1433 bus_dmamap_sync(sc->amr_buffer64_dmat,ac->ac_dma64map, flags); 1434 } else { 1435 amr_setup_dmamap(arg, segs, nsegs, err); 1436 bus_dmamap_sync(sc->amr_buffer_dmat,ac->ac_dmamap, flags); | 1426 ac->ac_sg64_hi = 0; 1427 ac->ac_sg64_lo = ac->ac_sgbusaddr; |
1437 } | 1428 } |
1429 |
|
1438 sc->amr_poll_command1(sc, ac); 1439} 1440 1441/******************************************************************************** 1442 * Take a command, submit it to the controller and busy-wait for it to return. 1443 * Returns nonzero on error. Can be safely called with interrupts enabled. 1444 */ 1445static int 1446amr_quartz_poll_command(struct amr_command *ac) 1447{ | 1430 sc->amr_poll_command1(sc, ac); 1431} 1432 1433/******************************************************************************** 1434 * Take a command, submit it to the controller and busy-wait for it to return. 1435 * Returns nonzero on error. Can be safely called with interrupts enabled. 1436 */ 1437static int 1438amr_quartz_poll_command(struct amr_command *ac) 1439{ |
1448 bus_dma_tag_t tag; 1449 bus_dmamap_t datamap; | |
1450 struct amr_softc *sc = ac->ac_sc; 1451 int error; 1452 1453 debug_called(2); 1454 1455 error = 0; 1456 1457 if (AC_IS_SG64(ac)) { | 1440 struct amr_softc *sc = ac->ac_sc; 1441 int error; 1442 1443 debug_called(2); 1444 1445 error = 0; 1446 1447 if (AC_IS_SG64(ac)) { |
1458 tag = sc->amr_buffer64_dmat; 1459 datamap = ac->ac_dma64map; | 1448 ac->ac_tag = sc->amr_buffer64_dmat; 1449 ac->ac_datamap = ac->ac_dma64map; |
1460 } else { | 1450 } else { |
1461 tag = sc->amr_buffer_dmat; 1462 datamap = ac->ac_dmamap; | 1451 ac->ac_tag = sc->amr_buffer_dmat; 1452 ac->ac_datamap = ac->ac_dmamap; |
1463 } 1464 1465 /* now we have a slot, we can map the command (unmapped in amr_complete) */ 1466 if (ac->ac_data != 0) { | 1453 } 1454 1455 /* now we have a slot, we can map the command (unmapped in amr_complete) */ 1456 if (ac->ac_data != 0) { |
1467 if (bus_dmamap_load(tag, datamap, ac->ac_data, ac->ac_length, 1468 amr_setup_polled_dmamap, ac, BUS_DMA_NOWAIT) != 0) { | 1457 if (bus_dmamap_load(ac->ac_tag, ac->ac_datamap, ac->ac_data, 1458 ac->ac_length, amr_setup_polled_dmamap, ac, BUS_DMA_NOWAIT) != 0) { |
1469 error = 1; 1470 } 1471 } else { 1472 error = amr_quartz_poll_command1(sc, ac); 1473 } 1474 1475 return (error); 1476} --- 12 unchanged lines hidden (view full) --- 1489 break; 1490 } 1491 } 1492 1493 if(sc->amr_busyslots) { 1494 device_printf(sc->amr_dev, "adapter is busy\n"); 1495 mtx_unlock(&sc->amr_hw_lock); 1496 if (ac->ac_data != NULL) { | 1459 error = 1; 1460 } 1461 } else { 1462 error = amr_quartz_poll_command1(sc, ac); 1463 } 1464 1465 return (error); 1466} --- 12 unchanged lines hidden (view full) --- 1479 break; 1480 } 1481 } 1482 1483 if(sc->amr_busyslots) { 1484 device_printf(sc->amr_dev, "adapter is busy\n"); 1485 mtx_unlock(&sc->amr_hw_lock); 1486 if (ac->ac_data != NULL) { |
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); | 1487 bus_dmamap_unload(ac->ac_tag, ac->ac_datamap); |
1501 } 1502 ac->ac_status=0; 1503 return(1); 1504 } 1505 } 1506 1507 bcopy(&ac->ac_mailbox, (void *)(uintptr_t)(volatile void *)sc->amr_mailbox, AMR_MBOX_CMDSIZE); 1508 --- 21 unchanged lines hidden (view full) --- 1530 /* acknowledge that we have the commands */ 1531 AMR_QPUT_IDB(sc, sc->amr_mailboxphys | AMR_QIDB_ACK); 1532 while(AMR_QGET_IDB(sc) & AMR_QIDB_ACK) 1533 DELAY(1); 1534 mtx_unlock(&sc->amr_hw_lock); 1535 1536 /* unmap the command's data buffer */ 1537 if (ac->ac_flags & AMR_CMD_DATAIN) { | 1488 } 1489 ac->ac_status=0; 1490 return(1); 1491 } 1492 } 1493 1494 bcopy(&ac->ac_mailbox, (void *)(uintptr_t)(volatile void *)sc->amr_mailbox, AMR_MBOX_CMDSIZE); 1495 --- 21 unchanged lines hidden (view full) --- 1517 /* acknowledge that we have the commands */ 1518 AMR_QPUT_IDB(sc, sc->amr_mailboxphys | AMR_QIDB_ACK); 1519 while(AMR_QGET_IDB(sc) & AMR_QIDB_ACK) 1520 DELAY(1); 1521 mtx_unlock(&sc->amr_hw_lock); 1522 1523 /* unmap the command's data buffer */ 1524 if (ac->ac_flags & AMR_CMD_DATAIN) { |
1538 bus_dmamap_sync(sc->amr_buffer_dmat,ac->ac_dmamap, 1539 BUS_DMASYNC_POSTREAD); | 1525 bus_dmamap_sync(ac->ac_tag, ac->ac_datamap, BUS_DMASYNC_POSTREAD); |
1540 } 1541 if (ac->ac_flags & AMR_CMD_DATAOUT) { | 1526 } 1527 if (ac->ac_flags & AMR_CMD_DATAOUT) { |
1542 bus_dmamap_sync(sc->amr_buffer_dmat,ac->ac_dmamap, 1543 BUS_DMASYNC_POSTWRITE); | 1528 bus_dmamap_sync(ac->ac_tag, ac->ac_datamap, BUS_DMASYNC_POSTWRITE); |
1544 } | 1529 } |
1545 if (AC_IS_SG64(ac)) 1546 bus_dmamap_unload(sc->amr_buffer64_dmat, ac->ac_dma64map); 1547 else 1548 bus_dmamap_unload(sc->amr_buffer_dmat, ac->ac_dmamap); | 1530 bus_dmamap_unload(ac->ac_tag, ac->ac_datamap); |
1549 1550 return(error); 1551} 1552 1553static __inline int 1554amr_freeslot(struct amr_command *ac) 1555{ 1556 struct amr_softc *sc = ac->ac_sc; --- 12 unchanged lines hidden (view full) --- 1569} 1570 1571/******************************************************************************** 1572 * Map/unmap (ac)'s data in the controller's addressable space as required. 1573 * 1574 * These functions may be safely called multiple times on a given command. 1575 */ 1576static void | 1531 1532 return(error); 1533} 1534 1535static __inline int 1536amr_freeslot(struct amr_command *ac) 1537{ 1538 struct amr_softc *sc = ac->ac_sc; --- 12 unchanged lines hidden (view full) --- 1551} 1552 1553/******************************************************************************** 1554 * Map/unmap (ac)'s data in the controller's addressable space as required. 1555 * 1556 * These functions may be safely called multiple times on a given command. 1557 */ 1558static void |
1577amr_setup_dmamap(void *arg, bus_dma_segment_t *segs, int nsegments, int error) | 1559amr_setup_sg(void *arg, bus_dma_segment_t *segs, int nsegments, int error) |
1578{ 1579 struct amr_command *ac = (struct amr_command *)arg; 1580 struct amr_sgentry *sg; | 1560{ 1561 struct amr_command *ac = (struct amr_command *)arg; 1562 struct amr_sgentry *sg; |
1581 int i; 1582 u_int8_t *sgc; | 1563 struct amr_sg64entry *sg64; 1564 int flags, i; |
1583 1584 debug_called(3); 1585 | 1565 1566 debug_called(3); 1567 |
1586 /* get base address of s/g table */ 1587 sg = ac->ac_sg.sg32; | 1568 if (error) 1569 printf("amr_setup_sg: error %d\n", error); |
1588 | 1570 |
1589 /* save data physical address */ 1590 1591 /* for AMR_CMD_CONFIG Read/Write the s/g count goes elsewhere */ 1592 if (ac->ac_mailbox.mb_command == AMR_CMD_CONFIG && ( 1593 ((struct amr_mailbox_ioctl *)&ac->ac_mailbox)->mb_channel == AMR_CONFIG_READ_NVRAM_CONFIG || 1594 ((struct amr_mailbox_ioctl *)&ac->ac_mailbox)->mb_channel == AMR_CONFIG_WRITE_NVRAM_CONFIG)) { 1595 sgc = &(((struct amr_mailbox_ioctl *)&ac->ac_mailbox)->mb_param); 1596 } else { 1597 sgc = &ac->ac_mailbox.mb_nsgelem; 1598 } 1599 1600 /* decide whether we need to populate the s/g table */ 1601 if (nsegments < 2) { 1602 *sgc = 0; 1603 ac->ac_mailbox.mb_nsgelem = 0; 1604 ac->ac_mailbox.mb_physaddr = segs[0].ds_addr; 1605 } else { 1606 ac->ac_mailbox.mb_nsgelem = nsegments; 1607 *sgc = nsegments; 1608 /* XXX Setting these to 0 might not be needed. */ 1609 ac->ac_sg64_lo = 0; 1610 ac->ac_sg64_hi = 0; 1611 ac->ac_mailbox.mb_physaddr = ac->ac_sgbusaddr; 1612 for (i = 0; i < nsegments; i++, sg++) { 1613 sg->sg_addr = segs[i].ds_addr; 1614 sg->sg_count = segs[i].ds_len; 1615 } 1616 } 1617 1618} 1619 1620static void 1621amr_setup_dma64map(void *arg, bus_dma_segment_t *segs, int nsegments, int error) 1622{ 1623 struct amr_command *ac = (struct amr_command *)arg; 1624 struct amr_sg64entry *sg; 1625 int i; 1626 u_int8_t *sgc; 1627 1628 debug_called(3); 1629 | |
1630 /* get base address of s/g table */ | 1571 /* get base address of s/g table */ |
1631 sg = ac->ac_sg.sg64; 1632 1633 /* save data physical address */ 1634 1635 /* for AMR_CMD_CONFIG Read/Write the s/g count goes elsewhere */ 1636 if (ac->ac_mailbox.mb_command == AMR_CMD_CONFIG && ( 1637 ((struct amr_mailbox_ioctl *)&ac->ac_mailbox)->mb_channel == AMR_CONFIG_READ_NVRAM_CONFIG || 1638 ((struct amr_mailbox_ioctl *)&ac->ac_mailbox)->mb_channel == AMR_CONFIG_WRITE_NVRAM_CONFIG)) { 1639 sgc = &(((struct amr_mailbox_ioctl *)&ac->ac_mailbox)->mb_param); 1640 } else { 1641 sgc = &ac->ac_mailbox.mb_nsgelem; 1642 } 1643 1644 ac->ac_mailbox.mb_nsgelem = nsegments; 1645 *sgc = nsegments; 1646 ac->ac_sg64_hi = 0; 1647 ac->ac_sg64_lo = ac->ac_sgbusaddr; 1648 ac->ac_mailbox.mb_physaddr = 0xffffffff; 1649 for (i = 0; i < nsegments; i++, sg++) { 1650 sg->sg_addr = segs[i].ds_addr; 1651 sg->sg_count = segs[i].ds_len; 1652 } 1653} 1654 1655static void 1656amr_setup_ccbmap(void *arg, bus_dma_segment_t *segs, int nsegments, int error) 1657{ 1658 struct amr_command *ac = (struct amr_command *)arg; 1659 struct amr_softc *sc = ac->ac_sc; 1660 struct amr_sgentry *sg; 1661 struct amr_passthrough *ap = (struct amr_passthrough *)ac->ac_data; 1662 struct amr_ext_passthrough *aep = (struct amr_ext_passthrough *)ac->ac_data; 1663 int i; 1664 1665 /* get base address of s/g table */ | |
1666 sg = ac->ac_sg.sg32; | 1572 sg = ac->ac_sg.sg32; |
1573 sg64 = ac->ac_sg.sg64; |
|
1667 | 1574 |
1668 /* decide whether we need to populate the s/g table */ 1669 if( ac->ac_mailbox.mb_command == AMR_CMD_EXTPASS ) { 1670 if (nsegments < 2) { 1671 aep->ap_no_sg_elements = 0; 1672 aep->ap_data_transfer_address = segs[0].ds_addr; 1673 } else { 1674 /* save s/g table information in passthrough */ 1675 aep->ap_no_sg_elements = nsegments; 1676 aep->ap_data_transfer_address = ac->ac_sgbusaddr; 1677 /* 1678 * populate s/g table (overwrites previous call which mapped the 1679 * passthrough) 1680 */ 1681 for (i = 0; i < nsegments; i++, sg++) { 1682 sg->sg_addr = segs[i].ds_addr; 1683 sg->sg_count = segs[i].ds_len; 1684 debug(3, " %d: 0x%x/%d", i, sg->sg_addr, sg->sg_count); 1685 } | 1575 if (AC_IS_SG64(ac)) { 1576 ac->ac_nsegments = nsegments; 1577 ac->ac_mb_physaddr = 0xffffffff; 1578 for (i = 0; i < nsegments; i++, sg64++) { 1579 sg64->sg_addr = segs[i].ds_addr; 1580 sg64->sg_count = segs[i].ds_len; |
1686 } | 1581 } |
1687 debug(3, "slot %d %d segments at 0x%x\n", ac->ac_slot, 1688 aep->ap_no_sg_elements, aep->ap_data_transfer_address); | |
1689 } else { | 1582 } else { |
1583 /* decide whether we need to populate the s/g table */ |
|
1690 if (nsegments < 2) { | 1584 if (nsegments < 2) { |
1691 ap->ap_no_sg_elements = 0; 1692 ap->ap_data_transfer_address = segs[0].ds_addr; | 1585 ac->ac_nsegments = 0; 1586 ac->ac_mb_physaddr = segs[0].ds_addr; |
1693 } else { | 1587 } else { |
1694 /* save s/g table information in passthrough */ 1695 ap->ap_no_sg_elements = nsegments; 1696 ap->ap_data_transfer_address = ac->ac_sgbusaddr; 1697 /* 1698 * populate s/g table (overwrites previous call which mapped the 1699 * passthrough) 1700 */ | 1588 ac->ac_nsegments = nsegments; 1589 ac->ac_mb_physaddr = ac->ac_sgbusaddr; |
1701 for (i = 0; i < nsegments; i++, sg++) { 1702 sg->sg_addr = segs[i].ds_addr; 1703 sg->sg_count = segs[i].ds_len; | 1590 for (i = 0; i < nsegments; i++, sg++) { 1591 sg->sg_addr = segs[i].ds_addr; 1592 sg->sg_count = segs[i].ds_len; |
1704 debug(3, " %d: 0x%x/%d", i, sg->sg_addr, sg->sg_count); | |
1705 } 1706 } | 1593 } 1594 } |
1707 debug(3, "slot %d %d segments at 0x%x\n", ac->ac_slot, 1708 ap->ap_no_sg_elements, ap->ap_data_transfer_address); | |
1709 } | 1595 } |
1710 if (ac->ac_flags & AMR_CMD_CCB_DATAIN) 1711 bus_dmamap_sync(sc->amr_buffer_dmat, ac->ac_ccb_dmamap, 1712 BUS_DMASYNC_PREREAD); 1713 if (ac->ac_flags & AMR_CMD_CCB_DATAOUT) 1714 bus_dmamap_sync(sc->amr_buffer_dmat, ac->ac_ccb_dmamap, 1715 BUS_DMASYNC_PREWRITE); 1716 if ((ac->ac_flags & (AMR_CMD_CCB_DATAIN | AMR_CMD_CCB_DATAOUT)) == 0) 1717 panic("no direction for ccb?\n"); | |
1718 | 1596 |
1597 flags = 0; |
|
1719 if (ac->ac_flags & AMR_CMD_DATAIN) | 1598 if (ac->ac_flags & AMR_CMD_DATAIN) |
1720 bus_dmamap_sync(sc->amr_buffer_dmat,ac->ac_dmamap,BUS_DMASYNC_PREREAD); | 1599 flags |= BUS_DMASYNC_PREREAD; |
1721 if (ac->ac_flags & AMR_CMD_DATAOUT) | 1600 if (ac->ac_flags & AMR_CMD_DATAOUT) |
1722 bus_dmamap_sync(sc->amr_buffer_dmat,ac->ac_dmamap,BUS_DMASYNC_PREWRITE); 1723 | 1601 flags |= BUS_DMASYNC_PREWRITE; 1602 bus_dmamap_sync(ac->ac_tag, ac->ac_datamap, flags); |
1724 ac->ac_flags |= AMR_CMD_MAPPED; | 1603 ac->ac_flags |= AMR_CMD_MAPPED; |
1725 1726 if (sc->amr_submit_command(ac) == EBUSY) { 1727 amr_freeslot(ac); 1728 amr_requeue_ready(ac); 1729 } | |
1730} 1731 1732static void | 1604} 1605 1606static void |
1733amr_setup_ccb64map(void *arg, bus_dma_segment_t *segs, int nsegments, int error) | 1607amr_setup_data(void *arg, bus_dma_segment_t *segs, int nsegs, int err) |
1734{ | 1608{ |
1735 struct amr_command *ac = (struct amr_command *)arg; 1736 struct amr_softc *sc = ac->ac_sc; 1737 struct amr_sg64entry *sg; 1738 struct amr_passthrough *ap = (struct amr_passthrough *)ac->ac_data; 1739 struct amr_ext_passthrough *aep = (struct amr_ext_passthrough *)ac->ac_data; 1740 int i; | 1609 struct amr_command *ac = arg; 1610 struct amr_softc *sc = ac->ac_sc; 1611 int mb_channel; |
1741 | 1612 |
1742 /* get base address of s/g table */ 1743 sg = ac->ac_sg.sg64; | 1613 amr_setup_sg(arg, segs, nsegs, err); |
1744 | 1614 |
1745 /* decide whether we need to populate the s/g table */ 1746 if( ac->ac_mailbox.mb_command == AMR_CMD_EXTPASS ) { 1747 /* save s/g table information in passthrough */ 1748 aep->ap_no_sg_elements = nsegments; 1749 aep->ap_data_transfer_address = ac->ac_sgbusaddr; 1750 /* 1751 * populate s/g table (overwrites previous call which mapped the 1752 * passthrough) 1753 */ 1754 for (i = 0; i < nsegments; i++, sg++) { 1755 sg->sg_addr = segs[i].ds_addr; 1756 sg->sg_count = segs[i].ds_len; 1757 debug(3, " %d: 0x%lx/%d", i, (u_long)sg->sg_addr, sg->sg_count); 1758 } 1759 debug(3, "slot %d %d segments at 0x%x\n", ac->ac_slot, 1760 aep->ap_no_sg_elements, aep->ap_data_transfer_address); 1761 } else { 1762 /* save s/g table information in passthrough */ 1763 ap->ap_no_sg_elements = nsegments; 1764 ap->ap_data_transfer_address = ac->ac_sgbusaddr; 1765 /* 1766 * populate s/g table (overwrites previous call which mapped the 1767 * passthrough) 1768 */ 1769 for (i = 0; i < nsegments; i++, sg++) { 1770 sg->sg_addr = segs[i].ds_addr; 1771 sg->sg_count = segs[i].ds_len; 1772 debug(3, " %d: 0x%lx/%d", i, (u_long)sg->sg_addr, sg->sg_count); 1773 } 1774 debug(3, "slot %d %d segments at 0x%x\n", ac->ac_slot, 1775 ap->ap_no_sg_elements, ap->ap_data_transfer_address); | 1615 /* for AMR_CMD_CONFIG Read/Write the s/g count goes elsewhere */ 1616 mb_channel = ((struct amr_mailbox_ioctl *)&ac->ac_mailbox)->mb_channel; 1617 if (ac->ac_mailbox.mb_command == AMR_CMD_CONFIG && 1618 ((mb_channel == AMR_CONFIG_READ_NVRAM_CONFIG) || 1619 (mb_channel == AMR_CONFIG_WRITE_NVRAM_CONFIG))) 1620 ((struct amr_mailbox_ioctl *)&ac->ac_mailbox)->mb_param = ac->ac_nsegments; 1621 1622 ac->ac_mailbox.mb_nsgelem = ac->ac_nsegments; 1623 ac->ac_mailbox.mb_physaddr = ac->ac_mb_physaddr; 1624 if (AC_IS_SG64(ac)) { 1625 ac->ac_sg64_hi = 0; 1626 ac->ac_sg64_lo = ac->ac_sgbusaddr; |
1776 } | 1627 } |
1777 if (ac->ac_flags & AMR_CMD_CCB_DATAIN) 1778 bus_dmamap_sync(sc->amr_buffer64_dmat, ac->ac_ccb_dma64map, 1779 BUS_DMASYNC_PREREAD); 1780 if (ac->ac_flags & AMR_CMD_CCB_DATAOUT) 1781 bus_dmamap_sync(sc->amr_buffer64_dmat, ac->ac_ccb_dma64map, 1782 BUS_DMASYNC_PREWRITE); 1783 if ((ac->ac_flags & (AMR_CMD_CCB_DATAIN | AMR_CMD_CCB_DATAOUT)) == 0) 1784 panic("no direction for ccb?\n"); | |
1785 | 1628 |
1786 if (ac->ac_flags & AMR_CMD_DATAIN) 1787 bus_dmamap_sync(sc->amr_buffer64_dmat, ac->ac_dma64map, 1788 BUS_DMASYNC_PREREAD); 1789 if (ac->ac_flags & AMR_CMD_DATAOUT) 1790 bus_dmamap_sync(sc->amr_buffer64_dmat, ac->ac_dma64map, 1791 BUS_DMASYNC_PREWRITE); 1792 1793 ac->ac_flags |= AMR_CMD_MAPPED; 1794 | |
1795 if (sc->amr_submit_command(ac) == EBUSY) { 1796 amr_freeslot(ac); 1797 amr_requeue_ready(ac); 1798 } 1799} | 1629 if (sc->amr_submit_command(ac) == EBUSY) { 1630 amr_freeslot(ac); 1631 amr_requeue_ready(ac); 1632 } 1633} |
1800 | 1634 |
1801static void | 1635static void |
1802amr_setup_dmamap_cb(void *arg, bus_dma_segment_t *segs, int nsegments, 1803 int error) | 1636amr_setup_ccb(void *arg, bus_dma_segment_t *segs, int nsegs, int err) |
1804{ | 1637{ |
1805 struct amr_command *ac = (struct amr_command *)arg; 1806 struct amr_softc *sc = ac->ac_sc; | 1638 struct amr_command *ac = arg; 1639 struct amr_softc *sc = ac->ac_sc; 1640 struct amr_passthrough *ap = &ac->ac_ccb->ccb_pthru; 1641 struct amr_ext_passthrough *aep = &ac->ac_ccb->ccb_epthru; |
1807 | 1642 |
1808 amr_setup_dmamap(arg, segs, nsegments, error); | 1643 /* Set up the mailbox portion of the command to point at the ccb */ 1644 ac->ac_mailbox.mb_nsgelem = 0; 1645 ac->ac_mailbox.mb_physaddr = ac->ac_ccb_busaddr; |
1809 | 1646 |
1810 if (bus_dmamap_load(sc->amr_buffer_dmat, ac->ac_ccb_dmamap, 1811 ac->ac_ccb_data, ac->ac_ccb_length, amr_setup_ccbmap, ac, 1812 0) == EINPROGRESS) { 1813 sc->amr_state |= AMR_STATE_QUEUE_FRZN; | 1647 amr_setup_sg(arg, segs, nsegs, err); 1648 1649 switch (ac->ac_mailbox.mb_command) { 1650 case AMR_CMD_EXTPASS: 1651 aep->ap_no_sg_elements = ac->ac_nsegments; 1652 aep->ap_data_transfer_address = ac->ac_mb_physaddr; 1653 break; 1654 case AMR_CMD_PASS: 1655 ap->ap_no_sg_elements = ac->ac_nsegments; 1656 ap->ap_data_transfer_address = ac->ac_mb_physaddr; 1657 break; 1658 default: 1659 panic("Unknown ccb command"); |
1814 } | 1660 } |
1815} | |
1816 | 1661 |
1817static void 1818amr_setup_dma64map_cb(void *arg, bus_dma_segment_t *segs, int nsegments, 1819 int error) 1820{ 1821 struct amr_command *ac = (struct amr_command *)arg; 1822 struct amr_softc *sc = ac->ac_sc; 1823 1824 amr_setup_dma64map(arg, segs, nsegments, error); 1825 1826 if (bus_dmamap_load(sc->amr_buffer64_dmat, ac->ac_ccb_dma64map, 1827 ac->ac_ccb_data, ac->ac_ccb_length, amr_setup_ccb64map, ac, 1828 0) == EINPROGRESS) { 1829 sc->amr_state |= AMR_STATE_QUEUE_FRZN; | 1662 if (sc->amr_submit_command(ac) == EBUSY) { 1663 amr_freeslot(ac); 1664 amr_requeue_ready(ac); |
1830 } 1831} 1832 1833static int 1834amr_mapcmd(struct amr_command *ac) 1835{ | 1665 } 1666} 1667 1668static int 1669amr_mapcmd(struct amr_command *ac) 1670{ |
1836 bus_dma_tag_t tag; 1837 bus_dmamap_t datamap; | |
1838 bus_dmamap_callback_t *cb; 1839 struct amr_softc *sc = ac->ac_sc; 1840 1841 debug_called(3); 1842 1843 if (AC_IS_SG64(ac)) { | 1671 bus_dmamap_callback_t *cb; 1672 struct amr_softc *sc = ac->ac_sc; 1673 1674 debug_called(3); 1675 1676 if (AC_IS_SG64(ac)) { |
1844 tag = sc->amr_buffer64_dmat; 1845 datamap = ac->ac_dma64map; 1846 cb = amr_setup_dma64map_cb; | 1677 ac->ac_tag = sc->amr_buffer64_dmat; 1678 ac->ac_datamap = ac->ac_dma64map; |
1847 } else { | 1679 } else { |
1848 tag = sc->amr_buffer_dmat; 1849 datamap = ac->ac_dmamap; 1850 cb = amr_setup_dmamap_cb; | 1680 ac->ac_tag = sc->amr_buffer_dmat; 1681 ac->ac_datamap = ac->ac_dmamap; |
1851 } 1852 | 1682 } 1683 |
1684 if (ac->ac_flags & AMR_CMD_CCB) 1685 cb = amr_setup_ccb; 1686 else 1687 cb = amr_setup_data; 1688 |
|
1853 /* if the command involves data at all, and hasn't been mapped */ 1854 if ((ac->ac_flags & AMR_CMD_MAPPED) == 0 && (ac->ac_data != NULL)) { | 1689 /* if the command involves data at all, and hasn't been mapped */ 1690 if ((ac->ac_flags & AMR_CMD_MAPPED) == 0 && (ac->ac_data != NULL)) { |
1855 if (ac->ac_ccb_data == NULL) 1856 cb = amr_setup_data_dmamap; | |
1857 /* map the data buffers into bus space and build the s/g list */ | 1691 /* map the data buffers into bus space and build the s/g list */ |
1858 if (bus_dmamap_load(tag, datamap, ac->ac_data, ac->ac_length, 1859 cb, ac, 0) == EINPROGRESS) { | 1692 if (bus_dmamap_load(ac->ac_tag, ac->ac_datamap, ac->ac_data, 1693 ac->ac_length, cb, ac, 0) == EINPROGRESS) { |
1860 sc->amr_state |= AMR_STATE_QUEUE_FRZN; 1861 } 1862 } else { 1863 if (sc->amr_submit_command(ac) == EBUSY) { 1864 amr_freeslot(ac); 1865 amr_requeue_ready(ac); 1866 } 1867 } 1868 1869 return (0); 1870} 1871 1872static void 1873amr_unmapcmd(struct amr_command *ac) 1874{ | 1694 sc->amr_state |= AMR_STATE_QUEUE_FRZN; 1695 } 1696 } else { 1697 if (sc->amr_submit_command(ac) == EBUSY) { 1698 amr_freeslot(ac); 1699 amr_requeue_ready(ac); 1700 } 1701 } 1702 1703 return (0); 1704} 1705 1706static void 1707amr_unmapcmd(struct amr_command *ac) 1708{ |
1875 struct amr_softc *sc = ac->ac_sc; | |
1876 int flag; 1877 1878 debug_called(3); 1879 1880 /* if the command involved data at all and was mapped */ 1881 if (ac->ac_flags & AMR_CMD_MAPPED) { 1882 1883 if (ac->ac_data != NULL) { 1884 1885 flag = 0; 1886 if (ac->ac_flags & AMR_CMD_DATAIN) 1887 flag |= BUS_DMASYNC_POSTREAD; 1888 if (ac->ac_flags & AMR_CMD_DATAOUT) 1889 flag |= BUS_DMASYNC_POSTWRITE; 1890 | 1709 int flag; 1710 1711 debug_called(3); 1712 1713 /* if the command involved data at all and was mapped */ 1714 if (ac->ac_flags & AMR_CMD_MAPPED) { 1715 1716 if (ac->ac_data != NULL) { 1717 1718 flag = 0; 1719 if (ac->ac_flags & AMR_CMD_DATAIN) 1720 flag |= BUS_DMASYNC_POSTREAD; 1721 if (ac->ac_flags & AMR_CMD_DATAOUT) 1722 flag |= BUS_DMASYNC_POSTWRITE; 1723 |
1891 if (AC_IS_SG64(ac)) { 1892 bus_dmamap_sync(sc->amr_buffer64_dmat, ac->ac_dma64map, flag); 1893 bus_dmamap_unload(sc->amr_buffer64_dmat, ac->ac_dma64map); 1894 } else { 1895 bus_dmamap_sync(sc->amr_buffer_dmat, ac->ac_dmamap, flag); 1896 bus_dmamap_unload(sc->amr_buffer_dmat, ac->ac_dmamap); 1897 } | 1724 bus_dmamap_sync(ac->ac_tag, ac->ac_datamap, flag); 1725 bus_dmamap_unload(ac->ac_tag, ac->ac_datamap); |
1898 } 1899 | 1726 } 1727 |
1900 if (ac->ac_ccb_data != NULL) { 1901 1902 flag = 0; 1903 if (ac->ac_flags & AMR_CMD_CCB_DATAIN) 1904 flag |= BUS_DMASYNC_POSTREAD; 1905 if (ac->ac_flags & AMR_CMD_CCB_DATAOUT) 1906 flag |= BUS_DMASYNC_POSTWRITE; 1907 1908 if (AC_IS_SG64(ac)) { 1909 bus_dmamap_sync(sc->amr_buffer64_dmat,ac->ac_ccb_dma64map,flag); 1910 bus_dmamap_unload(sc->amr_buffer64_dmat, ac->ac_ccb_dma64map); 1911 } else { 1912 bus_dmamap_sync(sc->amr_buffer_dmat, ac->ac_ccb_dmamap, flag); 1913 bus_dmamap_unload(sc->amr_buffer_dmat, ac->ac_ccb_dmamap); 1914 } 1915 } | |
1916 ac->ac_flags &= ~AMR_CMD_MAPPED; 1917 } 1918} 1919 | 1728 ac->ac_flags &= ~AMR_CMD_MAPPED; 1729 } 1730} 1731 |
1920static void 1921amr_setup_data_dmamap(void *arg, bus_dma_segment_t *segs, int nsegs, int err) 1922{ 1923 struct amr_command *ac = arg; 1924 struct amr_softc *sc = ac->ac_sc; 1925 int flags; 1926 1927 flags = 0; 1928 if (ac->ac_flags & AMR_CMD_DATAIN) 1929 flags |= BUS_DMASYNC_PREREAD; 1930 if (ac->ac_flags & AMR_CMD_DATAOUT) 1931 flags |= BUS_DMASYNC_PREWRITE; 1932 1933 if (AC_IS_SG64(ac)) { 1934 amr_setup_dma64map(arg, segs, nsegs, err); 1935 bus_dmamap_sync(sc->amr_buffer64_dmat,ac->ac_dma64map, flags); 1936 } else { 1937 amr_setup_dmamap(arg, segs, nsegs, err); 1938 bus_dmamap_sync(sc->amr_buffer_dmat,ac->ac_dmamap, flags); 1939 } 1940 ac->ac_flags |= AMR_CMD_MAPPED; 1941 1942 if (sc->amr_submit_command(ac) == EBUSY) { 1943 amr_freeslot(ac); 1944 amr_requeue_ready(ac); 1945 } 1946} 1947 | |
1948/******************************************************************************** 1949 * Take a command and give it to the controller, returns 0 if successful, or 1950 * EBUSY if the command should be retried later. 1951 */ 1952static int 1953amr_start(struct amr_command *ac) 1954{ 1955 struct amr_softc *sc; --- 163 unchanged lines hidden (view full) --- 2119 } 2120 2121 /* clear out significant fields */ 2122 ac->ac_status = 0; 2123 bzero(&ac->ac_mailbox, sizeof(struct amr_mailbox)); 2124 ac->ac_flags = 0; 2125 ac->ac_bio = NULL; 2126 ac->ac_data = NULL; | 1732/******************************************************************************** 1733 * Take a command and give it to the controller, returns 0 if successful, or 1734 * EBUSY if the command should be retried later. 1735 */ 1736static int 1737amr_start(struct amr_command *ac) 1738{ 1739 struct amr_softc *sc; --- 163 unchanged lines hidden (view full) --- 1903 } 1904 1905 /* clear out significant fields */ 1906 ac->ac_status = 0; 1907 bzero(&ac->ac_mailbox, sizeof(struct amr_mailbox)); 1908 ac->ac_flags = 0; 1909 ac->ac_bio = NULL; 1910 ac->ac_data = NULL; |
2127 ac->ac_ccb_data = NULL; | |
2128 ac->ac_complete = NULL; | 1911 ac->ac_complete = NULL; |
1912 ac->ac_tag = NULL; 1913 ac->ac_datamap = NULL; |
|
2129 return(ac); 2130} 2131 2132/******************************************************************************** 2133 * Release a command buffer for recycling. 2134 */ 2135void 2136amr_releasecmd(struct amr_command *ac) --- 35 unchanged lines hidden (view full) --- 2172 (ac->ac_slot * AMR_NSEG * sizeof(struct amr_sg64entry)); 2173 ac->ac_sg.sg64 = sc->amr_sg64table + (ac->ac_slot * AMR_NSEG); 2174 } else { 2175 ac->ac_sgbusaddr = sc->amr_sgbusaddr + 2176 (ac->ac_slot * AMR_NSEG * sizeof(struct amr_sgentry)); 2177 ac->ac_sg.sg32 = sc->amr_sgtable + (ac->ac_slot * AMR_NSEG); 2178 } 2179 | 1914 return(ac); 1915} 1916 1917/******************************************************************************** 1918 * Release a command buffer for recycling. 1919 */ 1920void 1921amr_releasecmd(struct amr_command *ac) --- 35 unchanged lines hidden (view full) --- 1957 (ac->ac_slot * AMR_NSEG * sizeof(struct amr_sg64entry)); 1958 ac->ac_sg.sg64 = sc->amr_sg64table + (ac->ac_slot * AMR_NSEG); 1959 } else { 1960 ac->ac_sgbusaddr = sc->amr_sgbusaddr + 1961 (ac->ac_slot * AMR_NSEG * sizeof(struct amr_sgentry)); 1962 ac->ac_sg.sg32 = sc->amr_sgtable + (ac->ac_slot * AMR_NSEG); 1963 } 1964 |
2180 if (bus_dmamap_create(sc->amr_buffer_dmat, 0, &ac->ac_dmamap) || 2181 bus_dmamap_create(sc->amr_buffer_dmat, 0, &ac->ac_ccb_dmamap) || 2182 (AMR_IS_SG64(sc) && 2183 (bus_dmamap_create(sc->amr_buffer64_dmat, 0,&ac->ac_dma64map) || 2184 bus_dmamap_create(sc->amr_buffer64_dmat, 0, &ac->ac_ccb_dma64map)))) 2185 break; | 1965 ac->ac_ccb = sc->amr_ccb + ac->ac_slot; 1966 ac->ac_ccb_busaddr = sc->amr_ccb_busaddr + 1967 (ac->ac_slot * sizeof(union amr_ccb)); 1968 1969 if (bus_dmamap_create(sc->amr_buffer_dmat, 0, &ac->ac_dmamap)) 1970 break; 1971 if (AMR_IS_SG64(sc) && 1972 (bus_dmamap_create(sc->amr_buffer64_dmat, 0,&ac->ac_dma64map))) 1973 break; |
2186 amr_releasecmd(ac); 2187 if (++nextslot > sc->amr_maxio) 2188 break; 2189 } 2190 sc->amr_nextslot = nextslot; 2191 } 2192} 2193 2194/******************************************************************************** 2195 * Free a command cluster 2196 */ 2197static void 2198amr_freecmd_cluster(struct amr_command_cluster *acc) 2199{ 2200 struct amr_softc *sc = acc->acc_command[0].ac_sc; 2201 int i; 2202 2203 for (i = 0; i < AMR_CMD_CLUSTERCOUNT; i++) { 2204 bus_dmamap_destroy(sc->amr_buffer_dmat, acc->acc_command[i].ac_dmamap); | 1974 amr_releasecmd(ac); 1975 if (++nextslot > sc->amr_maxio) 1976 break; 1977 } 1978 sc->amr_nextslot = nextslot; 1979 } 1980} 1981 1982/******************************************************************************** 1983 * Free a command cluster 1984 */ 1985static void 1986amr_freecmd_cluster(struct amr_command_cluster *acc) 1987{ 1988 struct amr_softc *sc = acc->acc_command[0].ac_sc; 1989 int i; 1990 1991 for (i = 0; i < AMR_CMD_CLUSTERCOUNT; i++) { 1992 bus_dmamap_destroy(sc->amr_buffer_dmat, acc->acc_command[i].ac_dmamap); |
2205 bus_dmamap_destroy(sc->amr_buffer_dmat, acc->acc_command[i].ac_ccb_dmamap); | |
2206 if (AMR_IS_SG64(sc)) 2207 bus_dmamap_destroy(sc->amr_buffer64_dmat, acc->acc_command[i].ac_dma64map); | 1993 if (AMR_IS_SG64(sc)) 1994 bus_dmamap_destroy(sc->amr_buffer64_dmat, acc->acc_command[i].ac_dma64map); |
2208 bus_dmamap_destroy(sc->amr_buffer64_dmat, acc->acc_command[i].ac_ccb_dma64map); | |
2209 } 2210 free(acc, M_AMR); 2211} 2212 2213/******************************************************************************** 2214 ******************************************************************************** 2215 Interface-specific Shims 2216 ******************************************************************************** --- 395 unchanged lines hidden --- | 1995 } 1996 free(acc, M_AMR); 1997} 1998 1999/******************************************************************************** 2000 ******************************************************************************** 2001 Interface-specific Shims 2002 ******************************************************************************** --- 395 unchanged lines hidden --- |