| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: ips.c,v 1.4 2021/08/07 16:19:14 thorpej Exp $ */ | | 1 | /* $NetBSD: ips.c,v 1.5 2022/02/12 02:40:39 riastradh Exp $ */ |
2 | /* $OpenBSD: ips.c,v 1.113 2016/08/14 04:08:03 dlg Exp $ */ | | 2 | /* $OpenBSD: ips.c,v 1.113 2016/08/14 04:08:03 dlg Exp $ */ |
3 | | | 3 | |
4 | /*- | | 4 | /*- |
5 | * Copyright (c) 2017 The NetBSD Foundation, Inc. | | 5 | * Copyright (c) 2017 The NetBSD Foundation, Inc. |
6 | * All rights reserved. | | 6 | * All rights reserved. |
7 | * | | 7 | * |
8 | * Redistribution and use in source and binary forms, with or without | | 8 | * Redistribution and use in source and binary forms, with or without |
9 | * modification, are permitted provided that the following conditions | | 9 | * modification, are permitted provided that the following conditions |
10 | * are met: | | 10 | * are met: |
11 | * 1. Redistributions of source code must retain the above copyright | | 11 | * 1. Redistributions of source code must retain the above copyright |
12 | * notice, this list of conditions and the following disclaimer. | | 12 | * notice, this list of conditions and the following disclaimer. |
13 | * 2. Redistributions in binary form must reproduce the above copyright | | 13 | * 2. Redistributions in binary form must reproduce the above copyright |
14 | * notice, this list of conditions and the following disclaimer in the | | 14 | * notice, this list of conditions and the following disclaimer in the |
| @@ -38,27 +38,27 @@ | | | @@ -38,27 +38,27 @@ |
38 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | | 38 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
39 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | | 39 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
40 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | | 40 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
41 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | | 41 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
42 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | | 42 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
43 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | | 43 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
44 | */ | | 44 | */ |
45 | | | 45 | |
46 | /* | | 46 | /* |
47 | * IBM (Adaptec) ServeRAID controllers driver. | | 47 | * IBM (Adaptec) ServeRAID controllers driver. |
48 | */ | | 48 | */ |
49 | | | 49 | |
50 | #include <sys/cdefs.h> | | 50 | #include <sys/cdefs.h> |
51 | __KERNEL_RCSID(0, "$NetBSD: ips.c,v 1.4 2021/08/07 16:19:14 thorpej Exp $"); | | 51 | __KERNEL_RCSID(0, "$NetBSD: ips.c,v 1.5 2022/02/12 02:40:39 riastradh Exp $"); |
52 | | | 52 | |
53 | #include "bio.h" | | 53 | #include "bio.h" |
54 | | | 54 | |
55 | #include <sys/param.h> | | 55 | #include <sys/param.h> |
56 | #include <sys/systm.h> | | 56 | #include <sys/systm.h> |
57 | #include <sys/device.h> | | 57 | #include <sys/device.h> |
58 | #include <sys/kernel.h> | | 58 | #include <sys/kernel.h> |
59 | #include <sys/queue.h> | | 59 | #include <sys/queue.h> |
60 | #include <sys/buf.h> | | 60 | #include <sys/buf.h> |
61 | #include <sys/endian.h> | | 61 | #include <sys/endian.h> |
62 | #include <sys/conf.h> | | 62 | #include <sys/conf.h> |
63 | #include <sys/malloc.h> | | 63 | #include <sys/malloc.h> |
64 | #include <sys/ioctl.h> | | 64 | #include <sys/ioctl.h> |
| @@ -409,27 +409,27 @@ struct ips_ccb { | | | @@ -409,27 +409,27 @@ struct ips_ccb { |
409 | SLIST_HEAD(ips_ccbq, ips_ccb); | | 409 | SLIST_HEAD(ips_ccbq, ips_ccb); |
410 | | | 410 | |
411 | /* DMA-able chunk of memory */ | | 411 | /* DMA-able chunk of memory */ |
412 | struct dmamem { | | 412 | struct dmamem { |
413 | bus_dma_tag_t dm_tag; | | 413 | bus_dma_tag_t dm_tag; |
414 | bus_dmamap_t dm_map; | | 414 | bus_dmamap_t dm_map; |
415 | bus_dma_segment_t dm_seg; | | 415 | bus_dma_segment_t dm_seg; |
416 | bus_size_t dm_size; | | 416 | bus_size_t dm_size; |
417 | void * dm_vaddr; | | 417 | void * dm_vaddr; |
418 | #define dm_paddr dm_seg.ds_addr | | 418 | #define dm_paddr dm_seg.ds_addr |
419 | }; | | 419 | }; |
420 | | | 420 | |
421 | struct ips_softc { | | 421 | struct ips_softc { |
422 | struct device sc_dev; | | 422 | device_t sc_dev; |
423 | | | 423 | |
424 | /* SCSI mid-layer connection. */ | | 424 | /* SCSI mid-layer connection. */ |
425 | struct scsipi_adapter sc_adapt; | | 425 | struct scsipi_adapter sc_adapt; |
426 | | | 426 | |
427 | struct ips_pt { | | 427 | struct ips_pt { |
428 | struct scsipi_channel pt_chan; | | 428 | struct scsipi_channel pt_chan; |
429 | int pt_nchan; | | 429 | int pt_nchan; |
430 | struct ips_softc * pt_sc; | | 430 | struct ips_softc * pt_sc; |
431 | | | 431 | |
432 | int pt_proctgt; | | 432 | int pt_proctgt; |
433 | char pt_procdev[16]; | | 433 | char pt_procdev[16]; |
434 | } sc_pt[IPS_MAXCHANS]; | | 434 | } sc_pt[IPS_MAXCHANS]; |
435 | | | 435 | |
| @@ -624,26 +624,27 @@ ips_attach(struct device *parent, struct | | | @@ -624,26 +624,27 @@ ips_attach(struct device *parent, struct |
624 | struct ips_ccb ccb0; | | 624 | struct ips_ccb ccb0; |
625 | struct ips_adapterinfo *ai; | | 625 | struct ips_adapterinfo *ai; |
626 | struct ips_driveinfo *di; | | 626 | struct ips_driveinfo *di; |
627 | struct ips_pg5 *pg5; | | 627 | struct ips_pg5 *pg5; |
628 | pcireg_t maptype; | | 628 | pcireg_t maptype; |
629 | bus_size_t iosize; | | 629 | bus_size_t iosize; |
630 | pci_intr_handle_t ih; | | 630 | pci_intr_handle_t ih; |
631 | const char *intrstr; | | 631 | const char *intrstr; |
632 | int type, i; | | 632 | int type, i; |
633 | struct scsipi_adapter *adapt; | | 633 | struct scsipi_adapter *adapt; |
634 | struct scsipi_channel *chan; | | 634 | struct scsipi_channel *chan; |
635 | char intrbuf[PCI_INTRSTR_LEN]; | | 635 | char intrbuf[PCI_INTRSTR_LEN]; |
636 | | | 636 | |
| | | 637 | sc->sc_dev = self; |
637 | sc->sc_dmat = pa->pa_dmat; | | 638 | sc->sc_dmat = pa->pa_dmat; |
638 | | | 639 | |
639 | /* Identify chipset */ | | 640 | /* Identify chipset */ |
640 | if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_IBM_SERVERAID) | | 641 | if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_IBM_SERVERAID) |
641 | sc->sc_chip = &ips_chips[IPS_CHIP_COPPERHEAD]; | | 642 | sc->sc_chip = &ips_chips[IPS_CHIP_COPPERHEAD]; |
642 | else | | 643 | else |
643 | sc->sc_chip = &ips_chips[IPS_CHIP_MORPHEUS]; | | 644 | sc->sc_chip = &ips_chips[IPS_CHIP_MORPHEUS]; |
644 | | | 645 | |
645 | /* Map registers */ | | 646 | /* Map registers */ |
646 | // XXX check IPS_IOSIZE as old code used to do? | | 647 | // XXX check IPS_IOSIZE as old code used to do? |
647 | maptype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, sc->sc_chip->ic_bar); | | 648 | maptype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, sc->sc_chip->ic_bar); |
648 | if (pci_mapreg_map(pa, sc->sc_chip->ic_bar, maptype, 0, &sc->sc_iot, | | 649 | if (pci_mapreg_map(pa, sc->sc_chip->ic_bar, maptype, 0, &sc->sc_iot, |
649 | &sc->sc_ioh, NULL, &iosize)) { | | 650 | &sc->sc_ioh, NULL, &iosize)) { |
| @@ -728,37 +729,37 @@ ips_attach(struct device *parent, struct | | | @@ -728,37 +729,37 @@ ips_attach(struct device *parent, struct |
728 | } | | 729 | } |
729 | SLIST_INIT(&sc->sc_ccbq_free); | | 730 | SLIST_INIT(&sc->sc_ccbq_free); |
730 | for (i = 0; i < sc->sc_nccbs; i++) | | 731 | for (i = 0; i < sc->sc_nccbs; i++) |
731 | SLIST_INSERT_HEAD(&sc->sc_ccbq_free, | | 732 | SLIST_INSERT_HEAD(&sc->sc_ccbq_free, |
732 | &sc->sc_ccb[i], c_link); | | 733 | &sc->sc_ccb[i], c_link); |
733 | | | 734 | |
734 | /* Install interrupt handler */ | | 735 | /* Install interrupt handler */ |
735 | if (pci_intr_map(pa, &ih)) { | | 736 | if (pci_intr_map(pa, &ih)) { |
736 | printf(": can't map interrupt\n"); | | 737 | printf(": can't map interrupt\n"); |
737 | goto fail5; | | 738 | goto fail5; |
738 | } | | 739 | } |
739 | intrstr = pci_intr_string(pa->pa_pc, ih, intrbuf, sizeof(intrbuf)); | | 740 | intrstr = pci_intr_string(pa->pa_pc, ih, intrbuf, sizeof(intrbuf)); |
740 | if (pci_intr_establish_xname(pa->pa_pc, ih, IPL_BIO, ips_intr, sc, | | 741 | if (pci_intr_establish_xname(pa->pa_pc, ih, IPL_BIO, ips_intr, sc, |
741 | sc->sc_dev.dv_xname) == NULL) { | | 742 | device_xname(sc->sc_dev)) == NULL) { |
742 | printf(": can't establish interrupt"); | | 743 | printf(": can't establish interrupt"); |
743 | if (intrstr != NULL) | | 744 | if (intrstr != NULL) |
744 | printf(" at %s", intrstr); | | 745 | printf(" at %s", intrstr); |
745 | printf("\n"); | | 746 | printf("\n"); |
746 | goto fail5; | | 747 | goto fail5; |
747 | } | | 748 | } |
748 | printf(": %s\n", intrstr); | | 749 | printf(": %s\n", intrstr); |
749 | | | 750 | |
750 | /* Display adapter info */ | | 751 | /* Display adapter info */ |
751 | printf("%s: ServeRAID", sc->sc_dev.dv_xname); | | 752 | device_printf(sc->sc_dev, "ServeRAID"); |
752 | type = htole16(pg5->type); | | 753 | type = htole16(pg5->type); |
753 | if (type < sizeof(ips_names) / sizeof(ips_names[0]) && ips_names[type]) | | 754 | if (type < sizeof(ips_names) / sizeof(ips_names[0]) && ips_names[type]) |
754 | printf(" %s", ips_names[type]); | | 755 | printf(" %s", ips_names[type]); |
755 | printf(", FW %c%c%c%c%c%c%c", ai->firmware[0], ai->firmware[1], | | 756 | printf(", FW %c%c%c%c%c%c%c", ai->firmware[0], ai->firmware[1], |
756 | ai->firmware[2], ai->firmware[3], ai->firmware[4], ai->firmware[5], | | 757 | ai->firmware[2], ai->firmware[3], ai->firmware[4], ai->firmware[5], |
757 | ai->firmware[6]); | | 758 | ai->firmware[6]); |
758 | printf(", BIOS %c%c%c%c%c%c%c", ai->bios[0], ai->bios[1], ai->bios[2], | | 759 | printf(", BIOS %c%c%c%c%c%c%c", ai->bios[0], ai->bios[1], ai->bios[2], |
759 | ai->bios[3], ai->bios[4], ai->bios[5], ai->bios[6]); | | 760 | ai->bios[3], ai->bios[4], ai->bios[5], ai->bios[6]); |
760 | printf(", %d cmds, %d LD%s", sc->sc_nccbs, sc->sc_nunits, | | 761 | printf(", %d cmds, %d LD%s", sc->sc_nccbs, sc->sc_nunits, |
761 | (sc->sc_nunits == 1 ? "" : "s")); | | 762 | (sc->sc_nunits == 1 ? "" : "s")); |
762 | printf("\n"); | | 763 | printf("\n"); |
763 | | | 764 | |
764 | /* | | 765 | /* |
| @@ -812,27 +813,27 @@ ips_attach(struct device *parent, struct | | | @@ -812,27 +813,27 @@ ips_attach(struct device *parent, struct |
812 | chan->chan_ntargets = IPS_MAXTARGETS; | | 813 | chan->chan_ntargets = IPS_MAXTARGETS; |
813 | chan->chan_nluns = lastarget + 1; | | 814 | chan->chan_nluns = lastarget + 1; |
814 | chan->chan_id = i; | | 815 | chan->chan_id = i; |
815 | chan->chan_flags = SCSIPI_CHAN_NOSETTLE; | | 816 | chan->chan_flags = SCSIPI_CHAN_NOSETTLE; |
816 | config_found(self, chan, scsiprint, CFARGS_NONE); | | 817 | config_found(self, chan, scsiprint, CFARGS_NONE); |
817 | } | | 818 | } |
818 | | | 819 | |
819 | /* Enable interrupts */ | | 820 | /* Enable interrupts */ |
820 | ips_intren(sc); | | 821 | ips_intren(sc); |
821 | | | 822 | |
822 | #if NBIO > 0 | | 823 | #if NBIO > 0 |
823 | /* Install ioctl handler */ | | 824 | /* Install ioctl handler */ |
824 | if (bio_register(&sc->sc_dev, ips_ioctl)) | | 825 | if (bio_register(&sc->sc_dev, ips_ioctl)) |
825 | printf("%s: no ioctl support\n", sc->sc_dev.dv_xname); | | 826 | device_printf(sc->sc_dev, "no ioctl support\n"); |
826 | #endif | | 827 | #endif |
827 | | | 828 | |
828 | return; | | 829 | return; |
829 | fail5: | | 830 | fail5: |
830 | ips_ccb_free(sc, sc->sc_ccb, sc->sc_nccbs); | | 831 | ips_ccb_free(sc, sc->sc_ccb, sc->sc_nccbs); |
831 | fail4: | | 832 | fail4: |
832 | if (sc->sc_chip->ic_id == IPS_CHIP_COPPERHEAD) | | 833 | if (sc->sc_chip->ic_id == IPS_CHIP_COPPERHEAD) |
833 | ips_dmamem_free(&sc->sc_sqm); | | 834 | ips_dmamem_free(&sc->sc_sqm); |
834 | fail3: | | 835 | fail3: |
835 | ips_dmamem_free(&sc->sc_infom); | | 836 | ips_dmamem_free(&sc->sc_infom); |
836 | fail2: | | 837 | fail2: |
837 | ips_dmamem_free(&sc->sc_cmdbm); | | 838 | ips_dmamem_free(&sc->sc_cmdbm); |
838 | fail1: | | 839 | fail1: |
| @@ -844,32 +845,32 @@ ips_scsi_cmd(struct ips_ccb *ccb) | | | @@ -844,32 +845,32 @@ ips_scsi_cmd(struct ips_ccb *ccb) |
844 | { | | 845 | { |
845 | struct scsipi_xfer *xs = ccb->c_xfer; | | 846 | struct scsipi_xfer *xs = ccb->c_xfer; |
846 | struct scsipi_periph *periph = xs->xs_periph; | | 847 | struct scsipi_periph *periph = xs->xs_periph; |
847 | struct scsipi_channel *chan = periph->periph_channel; | | 848 | struct scsipi_channel *chan = periph->periph_channel; |
848 | struct ips_softc *sc = device_private(chan->chan_adapter->adapt_dev); | | 849 | struct ips_softc *sc = device_private(chan->chan_adapter->adapt_dev); |
849 | struct ips_driveinfo *di = &sc->sc_info->drive; | | 850 | struct ips_driveinfo *di = &sc->sc_info->drive; |
850 | struct ips_drive *drive; | | 851 | struct ips_drive *drive; |
851 | struct ips_cmd *cmd; | | 852 | struct ips_cmd *cmd; |
852 | int target = periph->periph_target; | | 853 | int target = periph->periph_target; |
853 | u_int32_t blkno, blkcnt; | | 854 | u_int32_t blkno, blkcnt; |
854 | int code; | | 855 | int code; |
855 | | | 856 | |
856 | DPRINTF(IPS_D_XFER, ("%s: ips_scsi_cmd: xs %p, target %d, " | | 857 | DPRINTF(IPS_D_XFER, ("%s: ips_scsi_cmd: xs %p, target %d, " |
857 | "opcode 0x%02x, flags 0x%x\n", sc->sc_dev.dv_xname, xs, target, | | 858 | "opcode 0x%02x, flags 0x%x\n", device_xname(sc->sc_dev), xs, target, |
858 | xs->cmd->opcode, xs->xs_control)); | | 859 | xs->cmd->opcode, xs->xs_control)); |
859 | | | 860 | |
860 | if (target >= sc->sc_nunits || periph->periph_lun != 0) { | | 861 | if (target >= sc->sc_nunits || periph->periph_lun != 0) { |
861 | DPRINTF(IPS_D_INFO, ("%s: ips_scsi_cmd: invalid params " | | 862 | DPRINTF(IPS_D_INFO, ("%s: ips_scsi_cmd: invalid params " |
862 | "target %d, lun %d\n", sc->sc_dev.dv_xname, | | 863 | "target %d, lun %d\n", device_xname(sc->sc_dev), |
863 | target, periph->periph_lun)); | | 864 | target, periph->periph_lun)); |
864 | xs->error = XS_DRIVER_STUFFUP; | | 865 | xs->error = XS_DRIVER_STUFFUP; |
865 | ips_ccb_put(sc, ccb); | | 866 | ips_ccb_put(sc, ccb); |
866 | scsipi_done(xs); | | 867 | scsipi_done(xs); |
867 | return; | | 868 | return; |
868 | } | | 869 | } |
869 | | | 870 | |
870 | drive = &di->drive[target]; | | 871 | drive = &di->drive[target]; |
871 | xs->error = XS_NOERROR; | | 872 | xs->error = XS_NOERROR; |
872 | | | 873 | |
873 | /* Fake SCSI commands */ | | 874 | /* Fake SCSI commands */ |
874 | switch (xs->cmd->opcode) { | | 875 | switch (xs->cmd->opcode) { |
875 | case READ_10: | | 876 | case READ_10: |
| @@ -883,46 +884,46 @@ ips_scsi_cmd(struct ips_ccb *ccb) | | | @@ -883,46 +884,46 @@ ips_scsi_cmd(struct ips_ccb *ccb) |
883 | rw = (void *)xs->cmd; | | 884 | rw = (void *)xs->cmd; |
884 | blkno = _3btol(rw->addr) & | | 885 | blkno = _3btol(rw->addr) & |
885 | (SRW_TOPADDR << 16 | 0xffff); | | 886 | (SRW_TOPADDR << 16 | 0xffff); |
886 | blkcnt = rw->length ? rw->length : 0x100; | | 887 | blkcnt = rw->length ? rw->length : 0x100; |
887 | } else { | | 888 | } else { |
888 | rwb = (void *)xs->cmd; | | 889 | rwb = (void *)xs->cmd; |
889 | blkno = _4btol(rwb->addr); | | 890 | blkno = _4btol(rwb->addr); |
890 | blkcnt = _2btol(rwb->length); | | 891 | blkcnt = _2btol(rwb->length); |
891 | } | | 892 | } |
892 | | | 893 | |
893 | if (blkno >= htole32(drive->seccnt) || blkno + blkcnt > | | 894 | if (blkno >= htole32(drive->seccnt) || blkno + blkcnt > |
894 | htole32(drive->seccnt)) { | | 895 | htole32(drive->seccnt)) { |
895 | DPRINTF(IPS_D_ERR, ("%s: ips_scsi_cmd: invalid params " | | 896 | DPRINTF(IPS_D_ERR, ("%s: ips_scsi_cmd: invalid params " |
896 | "blkno %u, blkcnt %u\n", sc->sc_dev.dv_xname, | | 897 | "blkno %u, blkcnt %u\n", device_xname(sc->sc_dev), |
897 | blkno, blkcnt)); | | 898 | blkno, blkcnt)); |
898 | xs->error = XS_DRIVER_STUFFUP; | | 899 | xs->error = XS_DRIVER_STUFFUP; |
899 | break; | | 900 | break; |
900 | } | | 901 | } |
901 | | | 902 | |
902 | if (xs->xs_control & XS_CTL_DATA_IN) | | 903 | if (xs->xs_control & XS_CTL_DATA_IN) |
903 | code = IPS_CMD_READ; | | 904 | code = IPS_CMD_READ; |
904 | else | | 905 | else |
905 | code = IPS_CMD_WRITE; | | 906 | code = IPS_CMD_WRITE; |
906 | | | 907 | |
907 | cmd = ccb->c_cmdbva; | | 908 | cmd = ccb->c_cmdbva; |
908 | cmd->code = code; | | 909 | cmd->code = code; |
909 | cmd->drive = target; | | 910 | cmd->drive = target; |
910 | cmd->lba = htole32(blkno); | | 911 | cmd->lba = htole32(blkno); |
911 | cmd->seccnt = htole16(blkcnt); | | 912 | cmd->seccnt = htole16(blkcnt); |
912 | | | 913 | |
913 | if (ips_load_xs(sc, ccb, xs)) { | | 914 | if (ips_load_xs(sc, ccb, xs)) { |
914 | DPRINTF(IPS_D_ERR, ("%s: ips_scsi_cmd: ips_load_xs " | | 915 | DPRINTF(IPS_D_ERR, ("%s: ips_scsi_cmd: ips_load_xs " |
915 | "failed\n", sc->sc_dev.dv_xname)); | | 916 | "failed\n", device_xname(sc->sc_dev))); |
916 | xs->error = XS_DRIVER_STUFFUP; | | 917 | xs->error = XS_DRIVER_STUFFUP; |
917 | ips_ccb_put(sc, ccb); | | 918 | ips_ccb_put(sc, ccb); |
918 | scsipi_done(xs); | | 919 | scsipi_done(xs); |
919 | return; | | 920 | return; |
920 | } | | 921 | } |
921 | | | 922 | |
922 | if (cmd->sgcnt > 0) | | 923 | if (cmd->sgcnt > 0) |
923 | cmd->code |= IPS_CMD_SG; | | 924 | cmd->code |= IPS_CMD_SG; |
924 | | | 925 | |
925 | ccb->c_done = ips_done_xs; | | 926 | ccb->c_done = ips_done_xs; |
926 | ips_start_xs(sc, ccb, xs); | | 927 | ips_start_xs(sc, ccb, xs); |
927 | return; | | 928 | return; |
928 | } | | 929 | } |
| @@ -963,27 +964,27 @@ ips_scsi_cmd(struct ips_ccb *ccb) | | | @@ -963,27 +964,27 @@ ips_scsi_cmd(struct ips_ccb *ccb) |
963 | case SCSI_SYNCHRONIZE_CACHE_10: | | 964 | case SCSI_SYNCHRONIZE_CACHE_10: |
964 | cmd = ccb->c_cmdbva; | | 965 | cmd = ccb->c_cmdbva; |
965 | cmd->code = IPS_CMD_FLUSH; | | 966 | cmd->code = IPS_CMD_FLUSH; |
966 | | | 967 | |
967 | ccb->c_done = ips_done_xs; | | 968 | ccb->c_done = ips_done_xs; |
968 | ips_start_xs(sc, ccb, xs); | | 969 | ips_start_xs(sc, ccb, xs); |
969 | return; | | 970 | return; |
970 | case SCSI_PREVENT_ALLOW_MEDIUM_REMOVAL: | | 971 | case SCSI_PREVENT_ALLOW_MEDIUM_REMOVAL: |
971 | case START_STOP: | | 972 | case START_STOP: |
972 | case SCSI_TEST_UNIT_READY: | | 973 | case SCSI_TEST_UNIT_READY: |
973 | break; | | 974 | break; |
974 | default: | | 975 | default: |
975 | DPRINTF(IPS_D_INFO, ("%s: unsupported scsi command 0x%02x\n", | | 976 | DPRINTF(IPS_D_INFO, ("%s: unsupported scsi command 0x%02x\n", |
976 | sc->sc_dev.dv_xname, xs->cmd->opcode)); | | 977 | device_xname(sc->sc_dev), xs->cmd->opcode)); |
977 | xs->error = XS_DRIVER_STUFFUP; | | 978 | xs->error = XS_DRIVER_STUFFUP; |
978 | } | | 979 | } |
979 | | | 980 | |
980 | ips_ccb_put(sc, ccb); | | 981 | ips_ccb_put(sc, ccb); |
981 | scsipi_done(xs); | | 982 | scsipi_done(xs); |
982 | } | | 983 | } |
983 | | | 984 | |
984 | /* | | 985 | /* |
985 | * Start a SCSI command. | | 986 | * Start a SCSI command. |
986 | */ | | 987 | */ |
987 | static void | | 988 | static void |
988 | ips_scsipi_request(struct scsipi_channel *chan, scsipi_adapter_req_t req, | | 989 | ips_scsipi_request(struct scsipi_channel *chan, scsipi_adapter_req_t req, |
989 | void *arg) | | 990 | void *arg) |
| @@ -1034,49 +1035,49 @@ ips_scsi_ioctl(struct scsipi_channel *ch | | | @@ -1034,49 +1035,49 @@ ips_scsi_ioctl(struct scsipi_channel *ch |
1034 | return (ips_ioctl(chan->chan_adapter->adapt_dev, cmd, data)); | | 1035 | return (ips_ioctl(chan->chan_adapter->adapt_dev, cmd, data)); |
1035 | #else | | 1036 | #else |
1036 | return (ENOTTY); | | 1037 | return (ENOTTY); |
1037 | #endif | | 1038 | #endif |
1038 | } | | 1039 | } |
1039 | | | 1040 | |
1040 | #if NBIO > 0 | | 1041 | #if NBIO > 0 |
1041 | int | | 1042 | int |
1042 | ips_ioctl(device_t dev, u_long cmd, void *data) | | 1043 | ips_ioctl(device_t dev, u_long cmd, void *data) |
1043 | { | | 1044 | { |
1044 | struct ips_softc *sc = (struct ips_softc *)dev; | | 1045 | struct ips_softc *sc = (struct ips_softc *)dev; |
1045 | | | 1046 | |
1046 | DPRINTF(IPS_D_INFO, ("%s: ips_ioctl: cmd %lu\n", | | 1047 | DPRINTF(IPS_D_INFO, ("%s: ips_ioctl: cmd %lu\n", |
1047 | sc->sc_dev.dv_xname, cmd)); | | 1048 | device_xname(sc->sc_dev), cmd)); |
1048 | | | 1049 | |
1049 | switch (cmd) { | | 1050 | switch (cmd) { |
1050 | case BIOCINQ: | | 1051 | case BIOCINQ: |
1051 | return (ips_ioctl_inq(sc, (struct bioc_inq *)data)); | | 1052 | return (ips_ioctl_inq(sc, (struct bioc_inq *)data)); |
1052 | case BIOCVOL: | | 1053 | case BIOCVOL: |
1053 | return (ips_ioctl_vol(sc, (struct bioc_vol *)data)); | | 1054 | return (ips_ioctl_vol(sc, (struct bioc_vol *)data)); |
1054 | case BIOCDISK: | | 1055 | case BIOCDISK: |
1055 | return (ips_ioctl_disk(sc, (struct bioc_disk *)data)); | | 1056 | return (ips_ioctl_disk(sc, (struct bioc_disk *)data)); |
1056 | case BIOCSETSTATE: | | 1057 | case BIOCSETSTATE: |
1057 | return (ips_ioctl_setstate(sc, (struct bioc_setstate *)data)); | | 1058 | return (ips_ioctl_setstate(sc, (struct bioc_setstate *)data)); |
1058 | default: | | 1059 | default: |
1059 | return (ENOTTY); | | 1060 | return (ENOTTY); |
1060 | } | | 1061 | } |
1061 | } | | 1062 | } |
1062 | | | 1063 | |
1063 | int | | 1064 | int |
1064 | ips_ioctl_inq(struct ips_softc *sc, struct bioc_inq *bi) | | 1065 | ips_ioctl_inq(struct ips_softc *sc, struct bioc_inq *bi) |
1065 | { | | 1066 | { |
1066 | struct ips_conf *conf = &sc->sc_info->conf; | | 1067 | struct ips_conf *conf = &sc->sc_info->conf; |
1067 | int i; | | 1068 | int i; |
1068 | | | 1069 | |
1069 | strlcpy(bi->bi_dev, sc->sc_dev.dv_xname, sizeof(bi->bi_dev)); | | 1070 | strlcpy(bi->bi_dev, device_xname(sc->sc_dev), sizeof(bi->bi_dev)); |
1070 | bi->bi_novol = sc->sc_nunits; | | 1071 | bi->bi_novol = sc->sc_nunits; |
1071 | for (i = 0, bi->bi_nodisk = 0; i < sc->sc_nunits; i++) | | 1072 | for (i = 0, bi->bi_nodisk = 0; i < sc->sc_nunits; i++) |
1072 | bi->bi_nodisk += conf->ld[i].chunkcnt; | | 1073 | bi->bi_nodisk += conf->ld[i].chunkcnt; |
1073 | | | 1074 | |
1074 | DPRINTF(IPS_D_INFO, ("%s: ips_ioctl_inq: novol %d, nodisk %d\n", | | 1075 | DPRINTF(IPS_D_INFO, ("%s: ips_ioctl_inq: novol %d, nodisk %d\n", |
1075 | bi->bi_dev, bi->bi_novol, bi->bi_nodisk)); | | 1076 | bi->bi_dev, bi->bi_novol, bi->bi_nodisk)); |
1076 | | | 1077 | |
1077 | return (0); | | 1078 | return (0); |
1078 | } | | 1079 | } |
1079 | | | 1080 | |
1080 | int | | 1081 | int |
1081 | ips_ioctl_vol(struct ips_softc *sc, struct bioc_vol *bv) | | 1082 | ips_ioctl_vol(struct ips_softc *sc, struct bioc_vol *bv) |
1082 | { | | 1083 | { |
| @@ -1129,32 +1130,32 @@ ips_ioctl_vol(struct ips_softc *sc, stru | | | @@ -1129,32 +1130,32 @@ ips_ioctl_vol(struct ips_softc *sc, stru |
1129 | int chan, target; | | 1130 | int chan, target; |
1130 | | | 1131 | |
1131 | for (chan = 0; chan < IPS_MAXCHANS; chan++) | | 1132 | for (chan = 0; chan < IPS_MAXCHANS; chan++) |
1132 | for (target = 0; target < IPS_MAXTARGETS; target++) { | | 1133 | for (target = 0; target < IPS_MAXTARGETS; target++) { |
1133 | dev = &conf->dev[chan][target]; | | 1134 | dev = &conf->dev[chan][target]; |
1134 | if (dev->state && !(dev->state & | | 1135 | if (dev->state && !(dev->state & |
1135 | IPS_DVS_MEMBER) && | | 1136 | IPS_DVS_MEMBER) && |
1136 | (dev->params & SID_TYPE) == T_DIRECT) | | 1137 | (dev->params & SID_TYPE) == T_DIRECT) |
1137 | bv->bv_nodisk++; | | 1138 | bv->bv_nodisk++; |
1138 | } | | 1139 | } |
1139 | } | | 1140 | } |
1140 | | | 1141 | |
1141 | dv = &sc->sc_dev; | | 1142 | dv = &sc->sc_dev; |
1142 | strlcpy(bv->bv_dev, dv->dv_xname, sizeof(bv->bv_dev)); | | 1143 | strlcpy(bv->bv_dev, device_xname(dv), sizeof(bv->bv_dev)); |
1143 | strlcpy(bv->bv_vendor, "IBM", sizeof(bv->bv_vendor)); | | 1144 | strlcpy(bv->bv_vendor, "IBM", sizeof(bv->bv_vendor)); |
1144 | | | 1145 | |
1145 | DPRINTF(IPS_D_INFO, ("%s: ips_ioctl_vol: vid %d, state 0x%02x, " | | 1146 | DPRINTF(IPS_D_INFO, ("%s: ips_ioctl_vol: vid %d, state 0x%02x, " |
1146 | "total %u, done %u, size %llu, level %d, nodisk %d, dev %s\n", | | 1147 | "total %u, done %u, size %llu, level %d, nodisk %d, dev %s\n", |
1147 | sc->sc_dev.dv_xname, vid, ld->state, total, done, bv->bv_size, | | 1148 | device_xname(sc->sc_dev), vid, ld->state, total, done, bv->bv_size, |
1148 | bv->bv_level, bv->bv_nodisk, bv->bv_dev)); | | 1149 | bv->bv_level, bv->bv_nodisk, bv->bv_dev)); |
1149 | | | 1150 | |
1150 | return (0); | | 1151 | return (0); |
1151 | } | | 1152 | } |
1152 | | | 1153 | |
1153 | int | | 1154 | int |
1154 | ips_ioctl_disk(struct ips_softc *sc, struct bioc_disk *bd) | | 1155 | ips_ioctl_disk(struct ips_softc *sc, struct bioc_disk *bd) |
1155 | { | | 1156 | { |
1156 | struct ips_conf *conf = &sc->sc_info->conf; | | 1157 | struct ips_conf *conf = &sc->sc_info->conf; |
1157 | struct ips_ld *ld; | | 1158 | struct ips_ld *ld; |
1158 | struct ips_chunk *chunk; | | 1159 | struct ips_chunk *chunk; |
1159 | struct ips_dev *dev; | | 1160 | struct ips_dev *dev; |
1160 | int vid = bd->bd_volid, did = bd->bd_diskid; | | 1161 | int vid = bd->bd_volid, did = bd->bd_diskid; |
| @@ -1206,27 +1207,27 @@ out: | | | @@ -1206,27 +1207,27 @@ out: |
1206 | if (dev->state & IPS_DVS_READY) { | | 1207 | if (dev->state & IPS_DVS_READY) { |
1207 | bd->bd_status = BIOC_SDUNUSED; | | 1208 | bd->bd_status = BIOC_SDUNUSED; |
1208 | if (dev->state & IPS_DVS_MEMBER) | | 1209 | if (dev->state & IPS_DVS_MEMBER) |
1209 | bd->bd_status = BIOC_SDONLINE; | | 1210 | bd->bd_status = BIOC_SDONLINE; |
1210 | if (dev->state & IPS_DVS_SPARE) | | 1211 | if (dev->state & IPS_DVS_SPARE) |
1211 | bd->bd_status = BIOC_SDHOTSPARE; | | 1212 | bd->bd_status = BIOC_SDHOTSPARE; |
1212 | if (dev->state & IPS_DVS_REBUILD) | | 1213 | if (dev->state & IPS_DVS_REBUILD) |
1213 | bd->bd_status = BIOC_SDREBUILD; | | 1214 | bd->bd_status = BIOC_SDREBUILD; |
1214 | } else { | | 1215 | } else { |
1215 | bd->bd_status = BIOC_SDOFFLINE; | | 1216 | bd->bd_status = BIOC_SDOFFLINE; |
1216 | } | | 1217 | } |
1217 | | | 1218 | |
1218 | DPRINTF(IPS_D_INFO, ("%s: ips_ioctl_disk: vid %d, did %d, channel %d, " | | 1219 | DPRINTF(IPS_D_INFO, ("%s: ips_ioctl_disk: vid %d, did %d, channel %d, " |
1219 | "target %d, size %llu, state 0x%02x\n", sc->sc_dev.dv_xname, | | 1220 | "target %d, size %llu, state 0x%02x\n", device_xname(sc->sc_dev), |
1220 | vid, did, bd->bd_channel, bd->bd_target, bd->bd_size, dev->state)); | | 1221 | vid, did, bd->bd_channel, bd->bd_target, bd->bd_size, dev->state)); |
1221 | | | 1222 | |
1222 | return (0); | | 1223 | return (0); |
1223 | } | | 1224 | } |
1224 | | | 1225 | |
1225 | int | | 1226 | int |
1226 | ips_ioctl_setstate(struct ips_softc *sc, struct bioc_setstate *bs) | | 1227 | ips_ioctl_setstate(struct ips_softc *sc, struct bioc_setstate *bs) |
1227 | { | | 1228 | { |
1228 | struct ips_conf *conf = &sc->sc_info->conf; | | 1229 | struct ips_conf *conf = &sc->sc_info->conf; |
1229 | struct ips_dev *dev; | | 1230 | struct ips_dev *dev; |
1230 | int state, error; | | 1231 | int state, error; |
1231 | | | 1232 | |
1232 | if (bs->bs_channel >= IPS_MAXCHANS || bs->bs_target >= IPS_MAXTARGETS) | | 1233 | if (bs->bs_channel >= IPS_MAXCHANS || bs->bs_target >= IPS_MAXTARGETS) |
| @@ -1318,92 +1319,93 @@ ips_start_xs(struct ips_softc *sc, struc | | | @@ -1318,92 +1319,93 @@ ips_start_xs(struct ips_softc *sc, struc |
1318 | * errors. | | 1319 | * errors. |
1319 | */ | | 1320 | */ |
1320 | ips_cmd(sc, ccb); | | 1321 | ips_cmd(sc, ccb); |
1321 | } | | 1322 | } |
1322 | | | 1323 | |
1323 | int | | 1324 | int |
1324 | ips_cmd(struct ips_softc *sc, struct ips_ccb *ccb) | | 1325 | ips_cmd(struct ips_softc *sc, struct ips_ccb *ccb) |
1325 | { | | 1326 | { |
1326 | struct ips_cmd *cmd = ccb->c_cmdbva; | | 1327 | struct ips_cmd *cmd = ccb->c_cmdbva; |
1327 | int s, error = 0; | | 1328 | int s, error = 0; |
1328 | | | 1329 | |
1329 | DPRINTF(IPS_D_XFER, ("%s: ips_cmd: id 0x%02x, flags 0x%x, xs %p, " | | 1330 | DPRINTF(IPS_D_XFER, ("%s: ips_cmd: id 0x%02x, flags 0x%x, xs %p, " |
1330 | "code 0x%02x, drive %d, sgcnt %d, lba %d, sgaddr 0x%08x, " | | 1331 | "code 0x%02x, drive %d, sgcnt %d, lba %d, sgaddr 0x%08x, " |
1331 | "seccnt %d\n", sc->sc_dev.dv_xname, ccb->c_id, ccb->c_flags, | | 1332 | "seccnt %d\n", device_xname(sc->sc_dev), ccb->c_id, ccb->c_flags, |
1332 | ccb->c_xfer, cmd->code, cmd->drive, cmd->sgcnt, htole32(cmd->lba), | | 1333 | ccb->c_xfer, cmd->code, cmd->drive, cmd->sgcnt, htole32(cmd->lba), |
1333 | htole32(cmd->sgaddr), htole16(cmd->seccnt))); | | 1334 | htole32(cmd->sgaddr), htole16(cmd->seccnt))); |
1334 | | | 1335 | |
1335 | cmd->id = ccb->c_id; | | 1336 | cmd->id = ccb->c_id; |
1336 | | | 1337 | |
1337 | /* Post command to controller and optionally wait for completion */ | | 1338 | /* Post command to controller and optionally wait for completion */ |
1338 | s = splbio(); | | 1339 | s = splbio(); |
1339 | ips_exec(sc, ccb); | | 1340 | ips_exec(sc, ccb); |
1340 | ccb->c_state = IPS_CCB_QUEUED; | | 1341 | ccb->c_state = IPS_CCB_QUEUED; |
1341 | if (ccb->c_flags & XS_CTL_POLL) | | 1342 | if (ccb->c_flags & XS_CTL_POLL) |
1342 | error = ips_poll(sc, ccb); | | 1343 | error = ips_poll(sc, ccb); |
1343 | splx(s); | | 1344 | splx(s); |
1344 | | | 1345 | |
1345 | return (error); | | 1346 | return (error); |
1346 | } | | 1347 | } |
1347 | | | 1348 | |
1348 | int | | 1349 | int |
1349 | ips_poll(struct ips_softc *sc, struct ips_ccb *ccb) | | 1350 | ips_poll(struct ips_softc *sc, struct ips_ccb *ccb) |
1350 | { | | 1351 | { |
1351 | struct timeval tv; | | 1352 | struct timeval tv; |
1352 | int error, timo; | | 1353 | int error, timo; |
1353 | | | 1354 | |
1354 | if (ccb->c_flags & XS_CTL_NOSLEEP) { | | 1355 | if (ccb->c_flags & XS_CTL_NOSLEEP) { |
1355 | /* busy-wait */ | | 1356 | /* busy-wait */ |
1356 | DPRINTF(IPS_D_XFER, ("%s: ips_poll: busy-wait\n", | | 1357 | DPRINTF(IPS_D_XFER, ("%s: ips_poll: busy-wait\n", |
1357 | sc->sc_dev.dv_xname)); | | 1358 | device_xname(sc->sc_dev))); |
1358 | | | 1359 | |
1359 | for (timo = 10000; timo > 0; timo--) { | | 1360 | for (timo = 10000; timo > 0; timo--) { |
1360 | delay(100); | | 1361 | delay(100); |
1361 | ips_intr(sc); | | 1362 | ips_intr(sc); |
1362 | if (ccb->c_state == IPS_CCB_DONE) | | 1363 | if (ccb->c_state == IPS_CCB_DONE) |
1363 | break; | | 1364 | break; |
1364 | } | | 1365 | } |
1365 | } else { | | 1366 | } else { |
1366 | /* sleep */ | | 1367 | /* sleep */ |
1367 | timo = ccb->c_xfer ? ccb->c_xfer->timeout : IPS_TIMEOUT; | | 1368 | timo = ccb->c_xfer ? ccb->c_xfer->timeout : IPS_TIMEOUT; |
1368 | tv.tv_sec = timo / 1000; | | 1369 | tv.tv_sec = timo / 1000; |
1369 | tv.tv_usec = (timo % 1000) * 1000; | | 1370 | tv.tv_usec = (timo % 1000) * 1000; |
1370 | timo = tvtohz(&tv); | | 1371 | timo = tvtohz(&tv); |
1371 | | | 1372 | |
1372 | DPRINTF(IPS_D_XFER, ("%s: ips_poll: sleep %d hz\n", | | 1373 | DPRINTF(IPS_D_XFER, ("%s: ips_poll: sleep %d hz\n", |
1373 | sc->sc_dev.dv_xname, timo)); | | 1374 | device_xname(sc->sc_dev), timo)); |
1374 | tsleep(ccb, PRIBIO + 1, "ipscmd", timo); | | 1375 | tsleep(ccb, PRIBIO + 1, "ipscmd", timo); |
1375 | } | | 1376 | } |
1376 | DPRINTF(IPS_D_XFER, ("%s: ips_poll: state %d\n", sc->sc_dev.dv_xname, | | 1377 | DPRINTF(IPS_D_XFER, ("%s: ips_poll: state %d\n", |
| | | 1378 | device_xname(sc->sc_dev), |
1377 | ccb->c_state)); | | 1379 | ccb->c_state)); |
1378 | | | 1380 | |
1379 | if (ccb->c_state != IPS_CCB_DONE) | | 1381 | if (ccb->c_state != IPS_CCB_DONE) |
1380 | /* | | 1382 | /* |
1381 | * Command never completed. Fake hardware status byte | | 1383 | * Command never completed. Fake hardware status byte |
1382 | * to indicate timeout. | | 1384 | * to indicate timeout. |
1383 | */ | | 1385 | */ |
1384 | ccb->c_stat = IPS_STAT_TIMO; | | 1386 | ccb->c_stat = IPS_STAT_TIMO; |
1385 | | | 1387 | |
1386 | ips_done(sc, ccb); | | 1388 | ips_done(sc, ccb); |
1387 | error = ccb->c_error; | | 1389 | error = ccb->c_error; |
1388 | | | 1390 | |
1389 | return (error); | | 1391 | return (error); |
1390 | } | | 1392 | } |
1391 | | | 1393 | |
1392 | void | | 1394 | void |
1393 | ips_done(struct ips_softc *sc, struct ips_ccb *ccb) | | 1395 | ips_done(struct ips_softc *sc, struct ips_ccb *ccb) |
1394 | { | | 1396 | { |
1395 | DPRINTF(IPS_D_XFER, ("%s: ips_done: id 0x%02x, flags 0x%x, xs %p\n", | | 1397 | DPRINTF(IPS_D_XFER, ("%s: ips_done: id 0x%02x, flags 0x%x, xs %p\n", |
1396 | sc->sc_dev.dv_xname, ccb->c_id, ccb->c_flags, ccb->c_xfer)); | | 1398 | device_xname(sc->sc_dev), ccb->c_id, ccb->c_flags, ccb->c_xfer)); |
1397 | | | 1399 | |
1398 | ccb->c_error = ips_error(sc, ccb); | | 1400 | ccb->c_error = ips_error(sc, ccb); |
1399 | ccb->c_done(sc, ccb); | | 1401 | ccb->c_done(sc, ccb); |
1400 | } | | 1402 | } |
1401 | | | 1403 | |
1402 | void | | 1404 | void |
1403 | ips_done_xs(struct ips_softc *sc, struct ips_ccb *ccb) | | 1405 | ips_done_xs(struct ips_softc *sc, struct ips_ccb *ccb) |
1404 | { | | 1406 | { |
1405 | struct scsipi_xfer *xs = ccb->c_xfer; | | 1407 | struct scsipi_xfer *xs = ccb->c_xfer; |
1406 | | | 1408 | |
1407 | if (!(xs->xs_control & XS_CTL_POLL)) | | 1409 | if (!(xs->xs_control & XS_CTL_POLL)) |
1408 | callout_stop(&xs->xs_callout); | | 1410 | callout_stop(&xs->xs_callout); |
1409 | | | 1411 | |
| @@ -1478,27 +1480,27 @@ int | | | @@ -1478,27 +1480,27 @@ int |
1478 | ips_error(struct ips_softc *sc, struct ips_ccb *ccb) | | 1480 | ips_error(struct ips_softc *sc, struct ips_ccb *ccb) |
1479 | { | | 1481 | { |
1480 | struct ips_cmdb *cmdb = ccb->c_cmdbva; | | 1482 | struct ips_cmdb *cmdb = ccb->c_cmdbva; |
1481 | struct ips_cmd *cmd = &cmdb->cmd; | | 1483 | struct ips_cmd *cmd = &cmdb->cmd; |
1482 | struct ips_dcdb *dcdb = &cmdb->dcdb; | | 1484 | struct ips_dcdb *dcdb = &cmdb->dcdb; |
1483 | struct scsipi_xfer *xs = ccb->c_xfer; | | 1485 | struct scsipi_xfer *xs = ccb->c_xfer; |
1484 | u_int8_t gsc = IPS_STAT_GSC(ccb->c_stat); | | 1486 | u_int8_t gsc = IPS_STAT_GSC(ccb->c_stat); |
1485 | | | 1487 | |
1486 | if (gsc == IPS_STAT_OK) | | 1488 | if (gsc == IPS_STAT_OK) |
1487 | return (0); | | 1489 | return (0); |
1488 | | | 1490 | |
1489 | DPRINTF(IPS_D_ERR, ("%s: ips_error: stat 0x%02x, estat 0x%02x, " | | 1491 | DPRINTF(IPS_D_ERR, ("%s: ips_error: stat 0x%02x, estat 0x%02x, " |
1490 | "cmd code 0x%02x, drive %d, sgcnt %d, lba %u, seccnt %d", | | 1492 | "cmd code 0x%02x, drive %d, sgcnt %d, lba %u, seccnt %d", |
1491 | sc->sc_dev.dv_xname, ccb->c_stat, ccb->c_estat, cmd->code, | | 1493 | device_xname(sc->sc_dev), ccb->c_stat, ccb->c_estat, cmd->code, |
1492 | cmd->drive, cmd->sgcnt, htole32(cmd->lba), htole16(cmd->seccnt))); | | 1494 | cmd->drive, cmd->sgcnt, htole32(cmd->lba), htole16(cmd->seccnt))); |
1493 | if (cmd->code == IPS_CMD_DCDB || cmd->code == IPS_CMD_DCDB_SG) { | | 1495 | if (cmd->code == IPS_CMD_DCDB || cmd->code == IPS_CMD_DCDB_SG) { |
1494 | int i; | | 1496 | int i; |
1495 | | | 1497 | |
1496 | DPRINTF(IPS_D_ERR, (", dcdb device 0x%02x, attr 0x%02x, " | | 1498 | DPRINTF(IPS_D_ERR, (", dcdb device 0x%02x, attr 0x%02x, " |
1497 | "datalen %d, sgcnt %d, status 0x%02x", | | 1499 | "datalen %d, sgcnt %d, status 0x%02x", |
1498 | dcdb->device, dcdb->attr, htole16(dcdb->datalen), | | 1500 | dcdb->device, dcdb->attr, htole16(dcdb->datalen), |
1499 | dcdb->sgcnt, dcdb->status)); | | 1501 | dcdb->sgcnt, dcdb->status)); |
1500 | | | 1502 | |
1501 | DPRINTF(IPS_D_ERR, (", cdb")); | | 1503 | DPRINTF(IPS_D_ERR, (", cdb")); |
1502 | for (i = 0; i < dcdb->cdblen; i++) | | 1504 | for (i = 0; i < dcdb->cdblen; i++) |
1503 | DPRINTF(IPS_D_ERR, (" %x", dcdb->cdb[i])); | | 1505 | DPRINTF(IPS_D_ERR, (" %x", dcdb->cdb[i])); |
1504 | if (ccb->c_estat == IPS_ESTAT_CKCOND) { | | 1506 | if (ccb->c_estat == IPS_ESTAT_CKCOND) { |
| @@ -1576,50 +1578,50 @@ ips_error_xs(struct ips_softc *sc, struc | | | @@ -1576,50 +1578,50 @@ ips_error_xs(struct ips_softc *sc, struc |
1576 | } | | 1578 | } |
1577 | | | 1579 | |
1578 | return (XS_DRIVER_STUFFUP); | | 1580 | return (XS_DRIVER_STUFFUP); |
1579 | } | | 1581 | } |
1580 | | | 1582 | |
1581 | int | | 1583 | int |
1582 | ips_intr(void *arg) | | 1584 | ips_intr(void *arg) |
1583 | { | | 1585 | { |
1584 | struct ips_softc *sc = arg; | | 1586 | struct ips_softc *sc = arg; |
1585 | struct ips_ccb *ccb; | | 1587 | struct ips_ccb *ccb; |
1586 | u_int32_t status; | | 1588 | u_int32_t status; |
1587 | int id; | | 1589 | int id; |
1588 | | | 1590 | |
1589 | DPRINTF(IPS_D_XFER, ("%s: ips_intr", sc->sc_dev.dv_xname)); | | 1591 | DPRINTF(IPS_D_XFER, ("%s: ips_intr", device_xname(sc->sc_dev))); |
1590 | if (!ips_isintr(sc)) { | | 1592 | if (!ips_isintr(sc)) { |
1591 | DPRINTF(IPS_D_XFER, (": not ours\n")); | | 1593 | DPRINTF(IPS_D_XFER, (": not ours\n")); |
1592 | return (0); | | 1594 | return (0); |
1593 | } | | 1595 | } |
1594 | DPRINTF(IPS_D_XFER, ("\n")); | | 1596 | DPRINTF(IPS_D_XFER, ("\n")); |
1595 | | | 1597 | |
1596 | /* Process completed commands */ | | 1598 | /* Process completed commands */ |
1597 | while ((status = ips_status(sc)) != 0xffffffff) { | | 1599 | while ((status = ips_status(sc)) != 0xffffffff) { |
1598 | DPRINTF(IPS_D_XFER, ("%s: ips_intr: status 0x%08x\n", | | 1600 | DPRINTF(IPS_D_XFER, ("%s: ips_intr: status 0x%08x\n", |
1599 | sc->sc_dev.dv_xname, status)); | | 1601 | device_xname(sc->sc_dev), status)); |
1600 | | | 1602 | |
1601 | id = IPS_STAT_ID(status); | | 1603 | id = IPS_STAT_ID(status); |
1602 | if (id >= sc->sc_nccbs) { | | 1604 | if (id >= sc->sc_nccbs) { |
1603 | DPRINTF(IPS_D_ERR, ("%s: ips_intr: invalid id %d\n", | | 1605 | DPRINTF(IPS_D_ERR, ("%s: ips_intr: invalid id %d\n", |
1604 | sc->sc_dev.dv_xname, id)); | | 1606 | device_xname(sc->sc_dev), id)); |
1605 | continue; | | 1607 | continue; |
1606 | } | | 1608 | } |
1607 | | | 1609 | |
1608 | ccb = &sc->sc_ccb[id]; | | 1610 | ccb = &sc->sc_ccb[id]; |
1609 | if (ccb->c_state != IPS_CCB_QUEUED) { | | 1611 | if (ccb->c_state != IPS_CCB_QUEUED) { |
1610 | DPRINTF(IPS_D_ERR, ("%s: ips_intr: cmd 0x%02x not " | | 1612 | DPRINTF(IPS_D_ERR, ("%s: ips_intr: cmd 0x%02x not " |
1611 | "queued, state %d, status 0x%08x\n", | | 1613 | "queued, state %d, status 0x%08x\n", |
1612 | sc->sc_dev.dv_xname, ccb->c_id, ccb->c_state, | | 1614 | device_xname(sc->sc_dev), ccb->c_id, ccb->c_state, |
1613 | status)); | | 1615 | status)); |
1614 | continue; | | 1616 | continue; |
1615 | } | | 1617 | } |
1616 | | | 1618 | |
1617 | ccb->c_state = IPS_CCB_DONE; | | 1619 | ccb->c_state = IPS_CCB_DONE; |
1618 | ccb->c_stat = IPS_STAT_BASIC(status); | | 1620 | ccb->c_stat = IPS_STAT_BASIC(status); |
1619 | ccb->c_estat = IPS_STAT_EXT(status); | | 1621 | ccb->c_estat = IPS_STAT_EXT(status); |
1620 | | | 1622 | |
1621 | if (ccb->c_flags & XS_CTL_POLL) { | | 1623 | if (ccb->c_flags & XS_CTL_POLL) { |
1622 | wakeup(ccb); | | 1624 | wakeup(ccb); |
1623 | } else { | | 1625 | } else { |
1624 | ips_done(sc, ccb); | | 1626 | ips_done(sc, ccb); |
1625 | } | | 1627 | } |
| @@ -1630,27 +1632,27 @@ ips_intr(void *arg) | | | @@ -1630,27 +1632,27 @@ ips_intr(void *arg) |
1630 | | | 1632 | |
1631 | void | | 1633 | void |
1632 | ips_timeout(void *arg) | | 1634 | ips_timeout(void *arg) |
1633 | { | | 1635 | { |
1634 | struct ips_ccb *ccb = arg; | | 1636 | struct ips_ccb *ccb = arg; |
1635 | struct ips_softc *sc = ccb->c_sc; | | 1637 | struct ips_softc *sc = ccb->c_sc; |
1636 | struct scsipi_xfer *xs = ccb->c_xfer; | | 1638 | struct scsipi_xfer *xs = ccb->c_xfer; |
1637 | int s; | | 1639 | int s; |
1638 | | | 1640 | |
1639 | s = splbio(); | | 1641 | s = splbio(); |
1640 | if (xs) | | 1642 | if (xs) |
1641 | scsi_print_addr(xs->xs_periph); | | 1643 | scsi_print_addr(xs->xs_periph); |
1642 | else | | 1644 | else |
1643 | printf("%s: ", sc->sc_dev.dv_xname); | | 1645 | printf("%s: ", device_xname(sc->sc_dev)); |
1644 | printf("timeout\n"); | | 1646 | printf("timeout\n"); |
1645 | | | 1647 | |
1646 | /* | | 1648 | /* |
1647 | * Command never completed. Fake hardware status byte | | 1649 | * Command never completed. Fake hardware status byte |
1648 | * to indicate timeout. | | 1650 | * to indicate timeout. |
1649 | * XXX: need to remove command from controller. | | 1651 | * XXX: need to remove command from controller. |
1650 | */ | | 1652 | */ |
1651 | ccb->c_stat = IPS_STAT_TIMO; | | 1653 | ccb->c_stat = IPS_STAT_TIMO; |
1652 | ips_done(sc, ccb); | | 1654 | ips_done(sc, ccb); |
1653 | splx(s); | | 1655 | splx(s); |
1654 | } | | 1656 | } |
1655 | | | 1657 | |
1656 | int | | 1658 | int |
| @@ -1808,27 +1810,27 @@ ips_rebuild(struct ips_softc *sc, int ch | | | @@ -1808,27 +1810,27 @@ ips_rebuild(struct ips_softc *sc, int ch |
1808 | | | 1810 | |
1809 | void | | 1811 | void |
1810 | ips_copperhead_exec(struct ips_softc *sc, struct ips_ccb *ccb) | | 1812 | ips_copperhead_exec(struct ips_softc *sc, struct ips_ccb *ccb) |
1811 | { | | 1813 | { |
1812 | u_int32_t reg; | | 1814 | u_int32_t reg; |
1813 | int timeout; | | 1815 | int timeout; |
1814 | | | 1816 | |
1815 | for (timeout = 100; timeout-- > 0; delay(100)) { | | 1817 | for (timeout = 100; timeout-- > 0; delay(100)) { |
1816 | reg = bus_space_read_4(sc->sc_iot, sc->sc_ioh, IPS_REG_CCC); | | 1818 | reg = bus_space_read_4(sc->sc_iot, sc->sc_ioh, IPS_REG_CCC); |
1817 | if ((reg & IPS_REG_CCC_SEM) == 0) | | 1819 | if ((reg & IPS_REG_CCC_SEM) == 0) |
1818 | break; | | 1820 | break; |
1819 | } | | 1821 | } |
1820 | if (timeout < 0) { | | 1822 | if (timeout < 0) { |
1821 | printf("%s: semaphore timeout\n", sc->sc_dev.dv_xname); | | 1823 | device_printf(sc->sc_dev, "semaphore timeout\n"); |
1822 | return; | | 1824 | return; |
1823 | } | | 1825 | } |
1824 | | | 1826 | |
1825 | bus_space_write_4(sc->sc_iot, sc->sc_ioh, IPS_REG_CCSA, ccb->c_cmdbpa); | | 1827 | bus_space_write_4(sc->sc_iot, sc->sc_ioh, IPS_REG_CCSA, ccb->c_cmdbpa); |
1826 | bus_space_write_2(sc->sc_iot, sc->sc_ioh, IPS_REG_CCC, | | 1828 | bus_space_write_2(sc->sc_iot, sc->sc_ioh, IPS_REG_CCC, |
1827 | IPS_REG_CCC_START); | | 1829 | IPS_REG_CCC_START); |
1828 | } | | 1830 | } |
1829 | | | 1831 | |
1830 | void | | 1832 | void |
1831 | ips_copperhead_intren(struct ips_softc *sc) | | 1833 | ips_copperhead_intren(struct ips_softc *sc) |
1832 | { | | 1834 | { |
1833 | bus_space_write_1(sc->sc_iot, sc->sc_ioh, IPS_REG_HIS, IPS_REG_HIS_EN); | | 1835 | bus_space_write_1(sc->sc_iot, sc->sc_ioh, IPS_REG_HIS, IPS_REG_HIS_EN); |
1834 | } | | 1836 | } |
| @@ -1843,27 +1845,27 @@ ips_copperhead_isintr(struct ips_softc * | | | @@ -1843,27 +1845,27 @@ ips_copperhead_isintr(struct ips_softc * |
1843 | if (reg != 0xff && (reg & IPS_REG_HIS_SCE)) | | 1845 | if (reg != 0xff && (reg & IPS_REG_HIS_SCE)) |
1844 | return (1); | | 1846 | return (1); |
1845 | | | 1847 | |
1846 | return (0); | | 1848 | return (0); |
1847 | } | | 1849 | } |
1848 | | | 1850 | |
1849 | u_int32_t | | 1851 | u_int32_t |
1850 | ips_copperhead_status(struct ips_softc *sc) | | 1852 | ips_copperhead_status(struct ips_softc *sc) |
1851 | { | | 1853 | { |
1852 | u_int32_t sqhead, sqtail, status; | | 1854 | u_int32_t sqhead, sqtail, status; |
1853 | | | 1855 | |
1854 | sqhead = bus_space_read_4(sc->sc_iot, sc->sc_ioh, IPS_REG_SQH); | | 1856 | sqhead = bus_space_read_4(sc->sc_iot, sc->sc_ioh, IPS_REG_SQH); |
1855 | DPRINTF(IPS_D_XFER, ("%s: sqhead 0x%08x, sqtail 0x%08x\n", | | 1857 | DPRINTF(IPS_D_XFER, ("%s: sqhead 0x%08x, sqtail 0x%08x\n", |
1856 | sc->sc_dev.dv_xname, sqhead, sc->sc_sqtail)); | | 1858 | device_xname(sc->sc_dev), sqhead, sc->sc_sqtail)); |
1857 | | | 1859 | |
1858 | sqtail = sc->sc_sqtail + sizeof(u_int32_t); | | 1860 | sqtail = sc->sc_sqtail + sizeof(u_int32_t); |
1859 | if (sqtail == sc->sc_sqm.dm_paddr + IPS_SQSZ) | | 1861 | if (sqtail == sc->sc_sqm.dm_paddr + IPS_SQSZ) |
1860 | sqtail = sc->sc_sqm.dm_paddr; | | 1862 | sqtail = sc->sc_sqm.dm_paddr; |
1861 | if (sqtail == sqhead) | | 1863 | if (sqtail == sqhead) |
1862 | return (0xffffffff); | | 1864 | return (0xffffffff); |
1863 | | | 1865 | |
1864 | sc->sc_sqtail = sqtail; | | 1866 | sc->sc_sqtail = sqtail; |
1865 | if (++sc->sc_sqidx == IPS_MAXCMDS) | | 1867 | if (++sc->sc_sqidx == IPS_MAXCMDS) |
1866 | sc->sc_sqidx = 0; | | 1868 | sc->sc_sqidx = 0; |
1867 | status = htole32(sc->sc_sqbuf[sc->sc_sqidx]); | | 1869 | status = htole32(sc->sc_sqbuf[sc->sc_sqidx]); |
1868 | bus_space_write_4(sc->sc_iot, sc->sc_ioh, IPS_REG_SQT, sqtail); | | 1870 | bus_space_write_4(sc->sc_iot, sc->sc_ioh, IPS_REG_SQT, sqtail); |
1869 | | | 1871 | |
| @@ -1889,27 +1891,28 @@ ips_morpheus_intren(struct ips_softc *sc | | | @@ -1889,27 +1891,28 @@ ips_morpheus_intren(struct ips_softc *sc |
1889 | int | | 1891 | int |
1890 | ips_morpheus_isintr(struct ips_softc *sc) | | 1892 | ips_morpheus_isintr(struct ips_softc *sc) |
1891 | { | | 1893 | { |
1892 | return (bus_space_read_4(sc->sc_iot, sc->sc_ioh, IPS_REG_OIS) & | | 1894 | return (bus_space_read_4(sc->sc_iot, sc->sc_ioh, IPS_REG_OIS) & |
1893 | IPS_REG_OIS_PEND); | | 1895 | IPS_REG_OIS_PEND); |
1894 | } | | 1896 | } |
1895 | | | 1897 | |
1896 | u_int32_t | | 1898 | u_int32_t |
1897 | ips_morpheus_status(struct ips_softc *sc) | | 1899 | ips_morpheus_status(struct ips_softc *sc) |
1898 | { | | 1900 | { |
1899 | u_int32_t reg; | | 1901 | u_int32_t reg; |
1900 | | | 1902 | |
1901 | reg = bus_space_read_4(sc->sc_iot, sc->sc_ioh, IPS_REG_OQP); | | 1903 | reg = bus_space_read_4(sc->sc_iot, sc->sc_ioh, IPS_REG_OQP); |
1902 | DPRINTF(IPS_D_XFER, ("%s: status 0x%08x\n", sc->sc_dev.dv_xname, reg)); | | 1904 | DPRINTF(IPS_D_XFER, ("%s: status 0x%08x\n", device_xname(sc->sc_dev), |
| | | 1905 | reg)); |
1903 | | | 1906 | |
1904 | return (reg); | | 1907 | return (reg); |
1905 | } | | 1908 | } |
1906 | | | 1909 | |
1907 | struct ips_ccb * | | 1910 | struct ips_ccb * |
1908 | ips_ccb_alloc(struct ips_softc *sc, int n) | | 1911 | ips_ccb_alloc(struct ips_softc *sc, int n) |
1909 | { | | 1912 | { |
1910 | struct ips_ccb *ccb; | | 1913 | struct ips_ccb *ccb; |
1911 | int i; | | 1914 | int i; |
1912 | | | 1915 | |
1913 | ccb = malloc(n * sizeof(*ccb), M_DEVBUF, M_WAITOK | M_ZERO); | | 1916 | ccb = malloc(n * sizeof(*ccb), M_DEVBUF, M_WAITOK | M_ZERO); |
1914 | for (i = 0; i < n; i++) { | | 1917 | for (i = 0; i < n; i++) { |
1915 | ccb[i].c_sc = sc; | | 1918 | ccb[i].c_sc = sc; |