Deleted Added
full compact
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 ---