svn commit: r252903 - in stable/9: share/man/man4 sys/amd64/conf sys/conf sys/dev/hpt27xx sys/dev/hptnr sys/i386/conf sys/modules sys/modules/hpt27xx sys/modules/hptnr
Xin LI
delphij at FreeBSD.org
Sat Jul 6 23:26:38 UTC 2013
Author: delphij
Date: Sat Jul 6 23:26:36 2013
New Revision: 252903
URL: http://svnweb.freebsd.org/changeset/base/252903
Log:
MFC r252867:
Import HighPoint DC Series Data Center HBA (DC7280 and R750) driver.
This driver works for FreeBSD/i386 and FreeBSD/amd64 platforms.
Many thanks to HighPoint for providing this driver.
(This changeset have not included changes found in 249468 and 246713)
Added:
stable/9/share/man/man4/hptnr.4
- copied unchanged from r252867, head/share/man/man4/hptnr.4
stable/9/sys/dev/hpt27xx/hpt27xx_os_bsd.c
- copied unchanged from r252867, head/sys/dev/hpt27xx/hpt27xx_os_bsd.c
stable/9/sys/dev/hpt27xx/hpt27xx_osm_bsd.c
- copied unchanged from r252902, stable/9/sys/dev/hpt27xx/osm_bsd.c
stable/9/sys/dev/hptnr/
- copied from r252867, head/sys/dev/hptnr/
stable/9/sys/modules/hptnr/
- copied from r252867, head/sys/modules/hptnr/
Deleted:
stable/9/sys/dev/hpt27xx/os_bsd.c
stable/9/sys/dev/hpt27xx/osm_bsd.c
Modified:
stable/9/share/man/man4/Makefile
stable/9/sys/amd64/conf/GENERIC
stable/9/sys/amd64/conf/NOTES
stable/9/sys/conf/WITHOUT_SOURCELESS_HOST
stable/9/sys/conf/files.amd64
stable/9/sys/conf/files.i386
stable/9/sys/dev/hptnr/hptnr_osm_bsd.c
stable/9/sys/i386/conf/GENERIC
stable/9/sys/i386/conf/NOTES
stable/9/sys/i386/conf/PAE
stable/9/sys/i386/conf/XEN
stable/9/sys/modules/Makefile
stable/9/sys/modules/hpt27xx/Makefile
Directory Properties:
stable/9/share/man/man4/ (props changed)
stable/9/sys/ (props changed)
stable/9/sys/conf/ (props changed)
stable/9/sys/dev/ (props changed)
stable/9/sys/modules/ (props changed)
Modified: stable/9/share/man/man4/Makefile
==============================================================================
--- stable/9/share/man/man4/Makefile Sat Jul 6 23:04:59 2013 (r252902)
+++ stable/9/share/man/man4/Makefile Sat Jul 6 23:26:36 2013 (r252903)
@@ -157,6 +157,7 @@ MAN= aac.4 \
${_hpt27xx.4} \
${_hptiop.4} \
${_hptmv.4} \
+ ${_hptnr.4} \
${_hptrr.4} \
hwpmc.4 \
ichsmb.4 \
@@ -720,6 +721,7 @@ _dpms.4= dpms.4
_hpt27xx.4= hpt27xx.4
_hptiop.4= hptiop.4
_hptmv.4= hptmv.4
+_hptnr.4= hptnr.4
_hptrr.4= hptrr.4
_i8254.4= i8254.4
_ichwd.4= ichwd.4
Copied: stable/9/share/man/man4/hptnr.4 (from r252867, head/share/man/man4/hptnr.4)
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ stable/9/share/man/man4/hptnr.4 Sat Jul 6 23:26:36 2013 (r252903, copy of r252867, head/share/man/man4/hptnr.4)
@@ -0,0 +1,92 @@
+.\"-
+.\" Copyright (c) 2013 iXsystems, Inc.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR
+.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+.\" IN NO EVENT SHALL THE DEVELOPERS BE LIABLE FOR ANY DIRECT, INDIRECT,
+.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd July 5, 2013
+.Dt HPTNR 4
+.Os
+.Sh NAME
+.Nm hptnr
+.Nd "HighPoint DC Series Data Center HBA card driver"
+.Sh SYNOPSIS
+To compile this driver into the kernel,
+place the following line in your
+kernel configuration file:
+.Bd -ragged -offset indent
+.Cd "device hptnr"
+.Ed
+.Pp
+Alternatively, to load the driver as a
+module at boot time, place the following line in
+.Xr loader.conf 5 :
+.Bd -literal -offset indent
+hptnr_load="YES"
+.Ed
+.Sh DESCRIPTION
+The
+.Nm
+driver provides support for HighPoint's DC Series Data Center HBA card.
+.Sh HARDWARE
+The
+.Nm
+driver supports the following SATA
+controllers:
+.Pp
+.Bl -bullet -compact
+.It
+HighPoint's DC7280 series
+.It
+HighPoint's Rocket R750 series
+.El
+.Sh NOTES
+The
+.Nm
+driver only works on the i386 and amd64 platforms as it requires a binary
+blob object from the manufacturer which they only supply for these platforms.
+The
+.Nm
+driver does
+.Em not
+work on i386 with
+.Xr pae 4
+enabled.
+.Sh SEE ALSO
+.Xr kld 4 ,
+.Xr kldload 8 ,
+.Xr loader 8
+.Sh HISTORY
+The
+.Nm
+device driver first appeared in
+.Fx 9.2 .
+.Sh AUTHORS
+.An -nosplit
+The
+.Nm
+device driver was written by
+.An HighPoint Technologies, Inc. .
+This manual page was written by
+.An Xin LI Aq delphij at FreeBSD.org
+for iXsystems, Inc.
Modified: stable/9/sys/amd64/conf/GENERIC
==============================================================================
--- stable/9/sys/amd64/conf/GENERIC Sat Jul 6 23:04:59 2013 (r252902)
+++ stable/9/sys/amd64/conf/GENERIC Sat Jul 6 23:26:36 2013 (r252903)
@@ -134,6 +134,7 @@ device arcmsr # Areca SATA II RAID
device ciss # Compaq Smart RAID 5*
device dpt # DPT Smartcache III, IV - See NOTES for options
device hptmv # Highpoint RocketRAID 182x
+device hptnr # Highpoint DC7280, R750
device hptrr # Highpoint RocketRAID 17xx, 22xx, 23xx, 25xx
device hpt27xx # Highpoint RocketRAID 27xx
device iir # Intel Integrated RAID
Modified: stable/9/sys/amd64/conf/NOTES
==============================================================================
--- stable/9/sys/amd64/conf/NOTES Sat Jul 6 23:04:59 2013 (r252902)
+++ stable/9/sys/amd64/conf/NOTES Sat Jul 6 23:26:36 2013 (r252903)
@@ -419,6 +419,10 @@ device hpt27xx
device hptmv
#
+# Highpoint DC7280 and R750.
+device hptnr
+
+#
# Highpoint RocketRAID. Supports RR172x, RR222x, RR2240, RR232x, RR2340,
# RR2210, RR174x, RR2522, RR231x, RR230x.
device hptrr
Modified: stable/9/sys/conf/WITHOUT_SOURCELESS_HOST
==============================================================================
--- stable/9/sys/conf/WITHOUT_SOURCELESS_HOST Sat Jul 6 23:04:59 2013 (r252902)
+++ stable/9/sys/conf/WITHOUT_SOURCELESS_HOST Sat Jul 6 23:26:36 2013 (r252903)
@@ -6,5 +6,6 @@
nodevice hpt27xx
nodevice hptmv
+nodevice hptnr
nodevice hptrr
nodevice nve
Modified: stable/9/sys/conf/files.amd64
==============================================================================
--- stable/9/sys/conf/files.amd64 Sat Jul 6 23:04:59 2013 (r252902)
+++ stable/9/sys/conf/files.amd64 Sat Jul 6 23:26:36 2013 (r252903)
@@ -62,10 +62,17 @@ hpt27xx_lib.o optional hpt27xx \
dependency "$S/dev/hpt27xx/amd64-elf.hpt27xx_lib.o.uu" \
compile-with "uudecode < $S/dev/hpt27xx/amd64-elf.hpt27xx_lib.o.uu" \
no-implicit-rule
+#
hptmvraid.o optional hptmv \
dependency "$S/dev/hptmv/amd64-elf.raid.o.uu" \
compile-with "uudecode < $S/dev/hptmv/amd64-elf.raid.o.uu" \
no-implicit-rule
+#
+hptnr_lib.o optional hptnr \
+ dependency "$S/dev/hptnr/amd64-elf.hptnr_lib.o.uu" \
+ compile-with "uudecode < $S/dev/hptnr/amd64-elf.hptnr_lib.o.uu" \
+ no-implicit-rule
+#
hptrr_lib.o optional hptrr \
dependency "$S/dev/hptrr/amd64-elf.hptrr_lib.o.uu" \
compile-with "uudecode < $S/dev/hptrr/amd64-elf.hptrr_lib.o.uu" \
@@ -191,14 +198,17 @@ dev/fdc/fdc.c optional fdc
dev/fdc/fdc_acpi.c optional fdc
dev/fdc/fdc_isa.c optional fdc isa
dev/fdc/fdc_pccard.c optional fdc pccard
-dev/hpt27xx/os_bsd.c optional hpt27xx
-dev/hpt27xx/osm_bsd.c optional hpt27xx
+dev/hpt27xx/hpt27xx_os_bsd.c optional hpt27xx
+dev/hpt27xx/hpt27xx_osm_bsd.c optional hpt27xx
dev/hpt27xx/hpt27xx_config.c optional hpt27xx
dev/hptmv/entry.c optional hptmv
dev/hptmv/mv.c optional hptmv
dev/hptmv/gui_lib.c optional hptmv
dev/hptmv/hptproc.c optional hptmv
dev/hptmv/ioctl.c optional hptmv
+dev/hptnr/hptnr_os_bsd.c optional hptnr
+dev/hptnr/hptnr_osm_bsd.c optional hptnr
+dev/hptnr/hptnr_config.c optional hptnr
dev/hptrr/hptrr_os_bsd.c optional hptrr
dev/hptrr/hptrr_osm_bsd.c optional hptrr
dev/hptrr/hptrr_config.c optional hptrr
Modified: stable/9/sys/conf/files.i386
==============================================================================
--- stable/9/sys/conf/files.i386 Sat Jul 6 23:04:59 2013 (r252902)
+++ stable/9/sys/conf/files.i386 Sat Jul 6 23:26:36 2013 (r252903)
@@ -61,11 +61,17 @@ hpt27xx_lib.o optional hpt27xx \
dependency "$S/dev/hpt27xx/i386-elf.hpt27xx_lib.o.uu" \
compile-with "uudecode < $S/dev/hpt27xx/i386-elf.hpt27xx_lib.o.uu" \
no-implicit-rule
+#
hptmvraid.o optional hptmv \
dependency "$S/dev/hptmv/i386-elf.raid.o.uu" \
compile-with "uudecode < $S/dev/hptmv/i386-elf.raid.o.uu" \
no-implicit-rule
#
+hptnr_lib.o optional hptnr \
+ dependency "$S/dev/hptnr/i386-elf.hptnr_lib.o.uu" \
+ compile-with "uudecode < $S/dev/hptnr/i386-elf.hptnr_lib.o.uu" \
+ no-implicit-rule
+#
hptrr_lib.o optional hptrr \
dependency "$S/dev/hptrr/i386-elf.hptrr_lib.o.uu" \
compile-with "uudecode < $S/dev/hptrr/i386-elf.hptrr_lib.o.uu" \
@@ -179,14 +185,17 @@ dev/fe/if_fe_isa.c optional fe isa
dev/glxiic/glxiic.c optional glxiic
dev/glxsb/glxsb.c optional glxsb
dev/glxsb/glxsb_hash.c optional glxsb
-dev/hpt27xx/os_bsd.c optional hpt27xx
-dev/hpt27xx/osm_bsd.c optional hpt27xx
+dev/hpt27xx/hpt27xx_os_bsd.c optional hpt27xx
+dev/hpt27xx/hpt27xx_osm_bsd.c optional hpt27xx
dev/hpt27xx/hpt27xx_config.c optional hpt27xx
dev/hptmv/entry.c optional hptmv
dev/hptmv/mv.c optional hptmv
dev/hptmv/gui_lib.c optional hptmv
dev/hptmv/hptproc.c optional hptmv
dev/hptmv/ioctl.c optional hptmv
+dev/hptnr/hptnr_os_bsd.c optional hptnr
+dev/hptnr/hptnr_osm_bsd.c optional hptnr
+dev/hptnr/hptnr_config.c optional hptnr
dev/hptrr/hptrr_os_bsd.c optional hptrr
dev/hptrr/hptrr_osm_bsd.c optional hptrr
dev/hptrr/hptrr_config.c optional hptrr
Copied: stable/9/sys/dev/hpt27xx/hpt27xx_os_bsd.c (from r252867, head/sys/dev/hpt27xx/hpt27xx_os_bsd.c)
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ stable/9/sys/dev/hpt27xx/hpt27xx_os_bsd.c Sat Jul 6 23:26:36 2013 (r252903, copy of r252867, head/sys/dev/hpt27xx/hpt27xx_os_bsd.c)
@@ -0,0 +1,370 @@
+/*-
+ * Copyright (c) 2011 HighPoint Technologies, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <dev/hpt27xx/hpt27xx_config.h>
+
+#include <dev/hpt27xx/os_bsd.h>
+
+/* hardware access */
+HPT_U8 os_inb (void *port) { return inb((unsigned)(HPT_UPTR)port); }
+HPT_U16 os_inw (void *port) { return inw((unsigned)(HPT_UPTR)port); }
+HPT_U32 os_inl (void *port) { return inl((unsigned)(HPT_UPTR)port); }
+
+void os_outb (void *port, HPT_U8 value) { outb((unsigned)(HPT_UPTR)port, (value)); }
+void os_outw (void *port, HPT_U16 value) { outw((unsigned)(HPT_UPTR)port, (value)); }
+void os_outl (void *port, HPT_U32 value) { outl((unsigned)(HPT_UPTR)port, (value)); }
+
+void os_insw (void *port, HPT_U16 *buffer, HPT_U32 count)
+{ insw((unsigned)(HPT_UPTR)port, (void *)buffer, count); }
+
+void os_outsw(void *port, HPT_U16 *buffer, HPT_U32 count)
+{ outsw((unsigned)(HPT_UPTR)port, (void *)buffer, count); }
+
+HPT_U32 __dummy_reg = 0;
+
+/* PCI configuration space */
+HPT_U8 os_pci_readb (void *osext, HPT_U8 offset)
+{
+ return pci_read_config(((PHBA)osext)->pcidev, offset, 1);
+}
+
+HPT_U16 os_pci_readw (void *osext, HPT_U8 offset)
+{
+ return pci_read_config(((PHBA)osext)->pcidev, offset, 2);
+}
+
+HPT_U32 os_pci_readl (void *osext, HPT_U8 offset)
+{
+ return pci_read_config(((PHBA)osext)->pcidev, offset, 4);
+}
+
+void os_pci_writeb (void *osext, HPT_U8 offset, HPT_U8 value)
+{
+ pci_write_config(((PHBA)osext)->pcidev, offset, value, 1);
+}
+
+void os_pci_writew (void *osext, HPT_U8 offset, HPT_U16 value)
+{
+ pci_write_config(((PHBA)osext)->pcidev, offset, value, 2);
+}
+
+void os_pci_writel (void *osext, HPT_U8 offset, HPT_U32 value)
+{
+ pci_write_config(((PHBA)osext)->pcidev, offset, value, 4);
+}
+
+#if __FreeBSD_version < 500043
+/* PCI space access */
+HPT_U8 pcicfg_read_byte (HPT_U8 bus, HPT_U8 dev, HPT_U8 func, HPT_U8 reg)
+{
+ HPT_U8 v;
+ pcicfgregs pciref;
+
+ pciref.bus = bus;
+ pciref.slot = dev;
+ pciref.func = func;
+
+ v = pci_cfgread(&pciref, reg, 1);
+ return v;
+}
+HPT_U32 pcicfg_read_dword(HPT_U8 bus, HPT_U8 dev, HPT_U8 func, HPT_U8 reg)
+{
+ HPT_U32 v;
+ pcicfgregs pciref;
+
+ pciref.bus = bus;
+ pciref.slot = dev;
+ pciref.func = func;
+
+ v = pci_cfgread(&pciref, reg, 4);
+ return v;
+}
+void pcicfg_write_byte (HPT_U8 bus, HPT_U8 dev, HPT_U8 func, HPT_U8 reg, HPT_U8 v)
+{
+ pcicfgregs pciref;
+
+ pciref.hose = -1;
+ pciref.bus = bus;
+ pciref.slot = dev;
+ pciref.func = func;
+
+ pci_cfgwrite(&pciref, reg, v, 1);
+}
+void pcicfg_write_dword(HPT_U8 bus, HPT_U8 dev, HPT_U8 func, HPT_U8 reg, HPT_U32 v)
+{
+ pcicfgregs pciref;
+
+ pciref.hose = -1;
+ pciref.bus = bus;
+ pciref.slot = dev;
+ pciref.func = func;
+
+ pci_cfgwrite(&pciref, reg, v, 4);
+}/* PCI space access */
+#else
+HPT_U8 pcicfg_read_byte (HPT_U8 bus, HPT_U8 dev, HPT_U8 func, HPT_U8 reg)
+{
+ return (HPT_U8)pci_cfgregread(bus, dev, func, reg, 1);
+}
+HPT_U32 pcicfg_read_dword(HPT_U8 bus, HPT_U8 dev, HPT_U8 func, HPT_U8 reg)
+{
+ return (HPT_U32)pci_cfgregread(bus, dev, func, reg, 4);
+}
+void pcicfg_write_byte (HPT_U8 bus, HPT_U8 dev, HPT_U8 func, HPT_U8 reg, HPT_U8 v)
+{
+ pci_cfgregwrite(bus, dev, func, reg, v, 1);
+}
+void pcicfg_write_dword(HPT_U8 bus, HPT_U8 dev, HPT_U8 func, HPT_U8 reg, HPT_U32 v)
+{
+ pci_cfgregwrite(bus, dev, func, reg, v, 4);
+}/* PCI space access */
+#endif
+
+void *os_map_pci_bar(
+ void *osext,
+ int index,
+ HPT_U32 offset,
+ HPT_U32 length
+)
+{
+ PHBA hba = (PHBA)osext;
+ HPT_U32 base;
+
+ hba->pcibar[index].rid = 0x10 + index * 4;
+ base = pci_read_config(hba->pcidev, hba->pcibar[index].rid, 4);
+
+ if (base & 1) {
+ hba->pcibar[index].type = SYS_RES_IOPORT;
+ hba->pcibar[index].res = bus_alloc_resource(hba->pcidev,
+ hba->pcibar[index].type, &hba->pcibar[index].rid, 0, ~0, length, RF_ACTIVE);
+ hba->pcibar[index].base = (void *)(unsigned long)(base & ~0x1);
+ } else {
+ hba->pcibar[index].type = SYS_RES_MEMORY;
+ hba->pcibar[index].res = bus_alloc_resource(hba->pcidev,
+ hba->pcibar[index].type, &hba->pcibar[index].rid, 0, ~0, length, RF_ACTIVE);
+ hba->pcibar[index].base = (char *)rman_get_virtual(hba->pcibar[index].res) + offset;
+ }
+
+ return hba->pcibar[index].base;
+}
+
+void os_unmap_pci_bar(void *osext, void *base)
+{
+ PHBA hba = (PHBA)osext;
+ int index;
+
+ for (index=0; index<6; index++) {
+ if (hba->pcibar[index].base==base) {
+ bus_release_resource(hba->pcidev, hba->pcibar[index].type,
+ hba->pcibar[index].rid, hba->pcibar[index].res);
+ hba->pcibar[index].base = 0;
+ return;
+ }
+ }
+}
+
+void freelist_reserve(struct freelist *list, void *osext, HPT_UINT size, HPT_UINT count)
+{
+ PVBUS_EXT vbus_ext = osext;
+
+ if (vbus_ext->ext_type!=EXT_TYPE_VBUS)
+ vbus_ext = ((PHBA)osext)->vbus_ext;
+
+ list->next = vbus_ext->freelist_head;
+ vbus_ext->freelist_head = list;
+ list->dma = 0;
+ list->size = size;
+ list->head = 0;
+#if DBG
+ list->reserved_count =
+#endif
+ list->count = count;
+}
+
+void *freelist_get(struct freelist *list)
+{
+ void * result;
+ if (list->count) {
+ HPT_ASSERT(list->head);
+ result = list->head;
+ list->head = *(void **)result;
+ list->count--;
+ return result;
+ }
+ return 0;
+}
+
+void freelist_put(struct freelist * list, void *p)
+{
+ HPT_ASSERT(list->dma==0);
+ list->count++;
+ *(void **)p = list->head;
+ list->head = p;
+}
+
+void freelist_reserve_dma(struct freelist *list, void *osext, HPT_UINT size, HPT_UINT alignment, HPT_UINT count)
+{
+ PVBUS_EXT vbus_ext = osext;
+
+ if (vbus_ext->ext_type!=EXT_TYPE_VBUS)
+ vbus_ext = ((PHBA)osext)->vbus_ext;
+
+ list->next = vbus_ext->freelist_dma_head;
+ vbus_ext->freelist_dma_head = list;
+ list->dma = 1;
+ list->alignment = alignment;
+ list->size = size;
+ list->head = 0;
+#if DBG
+ list->reserved_count =
+#endif
+ list->count = count;
+}
+
+void *freelist_get_dma(struct freelist *list, BUS_ADDRESS *busaddr)
+{
+ void *result;
+ HPT_ASSERT(list->dma);
+ result = freelist_get(list);
+ if (result)
+ *busaddr = *(BUS_ADDRESS *)((void **)result+1);
+ return result;
+}
+
+void freelist_put_dma(struct freelist *list, void *p, BUS_ADDRESS busaddr)
+{
+ HPT_ASSERT(list->dma);
+ list->count++;
+ *(void **)p = list->head;
+ *(BUS_ADDRESS *)((void **)p+1) = busaddr;
+ list->head = p;
+}
+
+HPT_U32 os_get_stamp(void)
+{
+ HPT_U32 stamp;
+ do { stamp = random(); } while (stamp==0);
+ return stamp;
+}
+
+void os_stallexec(HPT_U32 microseconds)
+{
+ DELAY(microseconds);
+}
+
+static void os_timer_for_ldm(void *arg)
+{
+ PVBUS_EXT vbus_ext = (PVBUS_EXT)arg;
+ ldm_on_timer((PVBUS)vbus_ext->vbus);
+}
+
+void os_request_timer(void * osext, HPT_U32 interval)
+{
+ PVBUS_EXT vbus_ext = osext;
+
+ HPT_ASSERT(vbus_ext->ext_type==EXT_TYPE_VBUS);
+
+ untimeout(os_timer_for_ldm, vbus_ext, vbus_ext->timer);
+ vbus_ext->timer = timeout(os_timer_for_ldm, vbus_ext, interval * hz / 1000000);
+}
+
+HPT_TIME os_query_time(void)
+{
+ return ticks * (1000000 / hz);
+}
+
+void os_schedule_task(void *osext, OSM_TASK *task)
+{
+ PVBUS_EXT vbus_ext = osext;
+
+ HPT_ASSERT(task->next==0);
+
+ if (vbus_ext->tasks==0)
+ vbus_ext->tasks = task;
+ else {
+ OSM_TASK *t = vbus_ext->tasks;
+ while (t->next) t = t->next;
+ t->next = task;
+ }
+
+ if (vbus_ext->worker.ta_context)
+ TASK_ENQUEUE(&vbus_ext->worker);
+}
+
+int os_revalidate_device(void *osext, int id)
+{
+
+ return 0;
+}
+
+int os_query_remove_device(void *osext, int id)
+{
+ PVBUS_EXT vbus_ext = (PVBUS_EXT)osext;
+ struct cam_periph *periph = NULL;
+ struct cam_path *path;
+ int status,retval = 0;
+
+ status = xpt_create_path(&path, NULL, vbus_ext->sim->path_id, id, 0);
+ if (status == CAM_REQ_CMP) {
+ if((periph = cam_periph_find(path, "da")) != NULL){
+ if(periph->refcount >= 1)
+ retval = -1;
+ }
+ xpt_free_path(path);
+ }
+
+ return retval;
+}
+
+HPT_U8 os_get_vbus_seq(void *osext)
+{
+ return ((PVBUS_EXT)osext)->sim->path_id;
+}
+
+int os_printk(char *fmt, ...)
+{
+ va_list args;
+ static char buf[512];
+
+ va_start(args, fmt);
+ vsnprintf(buf, sizeof(buf), fmt, args);
+ va_end(args);
+ return printf("%s: %s\n", driver_name, buf);
+}
+
+#if DBG
+void os_check_stack(const char *location, int size){}
+
+void __os_dbgbreak(const char *file, int line)
+{
+ printf("*** break at %s:%d ***", file, line);
+ while (1);
+}
+
+int hpt_dbg_level = 1;
+#endif
Copied: stable/9/sys/dev/hpt27xx/hpt27xx_osm_bsd.c (from r252902, stable/9/sys/dev/hpt27xx/osm_bsd.c)
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ stable/9/sys/dev/hpt27xx/hpt27xx_osm_bsd.c Sat Jul 6 23:26:36 2013 (r252903, copy of r252902, stable/9/sys/dev/hpt27xx/osm_bsd.c)
@@ -0,0 +1,1361 @@
+/*-
+ * Copyright (c) 2011 HighPoint Technologies, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <dev/hpt27xx/hpt27xx_config.h>
+
+#include <dev/hpt27xx/os_bsd.h>
+#include <dev/hpt27xx/hptintf.h>
+
+static int hpt_probe(device_t dev)
+{
+ PCI_ID pci_id;
+ HIM *him;
+ int i;
+ PHBA hba;
+
+ for (him = him_list; him; him = him->next) {
+ for (i=0; him->get_supported_device_id(i, &pci_id); i++) {
+ if (him->get_controller_count)
+ him->get_controller_count(&pci_id,0,0);
+ if ((pci_get_vendor(dev) == pci_id.vid) &&
+ (pci_get_device(dev) == pci_id.did)){
+ KdPrint(("hpt_probe: adapter at PCI %d:%d:%d, IRQ %d",
+ pci_get_bus(dev), pci_get_slot(dev), pci_get_function(dev), pci_get_irq(dev)
+ ));
+ device_set_desc(dev, him->name);
+ hba = (PHBA)device_get_softc(dev);
+ memset(hba, 0, sizeof(HBA));
+ hba->ext_type = EXT_TYPE_HBA;
+ hba->ldm_adapter.him = him;
+ return 0;
+ }
+ }
+ }
+
+ return (ENXIO);
+}
+
+static int hpt_attach(device_t dev)
+{
+ PHBA hba = (PHBA)device_get_softc(dev);
+ HIM *him = hba->ldm_adapter.him;
+ PCI_ID pci_id;
+ HPT_UINT size;
+ PVBUS vbus;
+ PVBUS_EXT vbus_ext;
+
+ KdPrint(("hpt_attach(%d/%d/%d)", pci_get_bus(dev), pci_get_slot(dev), pci_get_function(dev)));
+
+#if __FreeBSD_version >=440000
+ pci_enable_busmaster(dev);
+#endif
+
+ pci_id.vid = pci_get_vendor(dev);
+ pci_id.did = pci_get_device(dev);
+ pci_id.rev = pci_get_revid(dev);
+ pci_id.subsys = (HPT_U32)(pci_get_subdevice(dev)) << 16 | pci_get_subvendor(dev);
+
+ size = him->get_adapter_size(&pci_id);
+ hba->ldm_adapter.him_handle = malloc(size, M_DEVBUF, M_WAITOK);
+ if (!hba->ldm_adapter.him_handle)
+ return ENXIO;
+
+ hba->pcidev = dev;
+ hba->pciaddr.tree = 0;
+ hba->pciaddr.bus = pci_get_bus(dev);
+ hba->pciaddr.device = pci_get_slot(dev);
+ hba->pciaddr.function = pci_get_function(dev);
+
+ if (!him->create_adapter(&pci_id, hba->pciaddr, hba->ldm_adapter.him_handle, hba)) {
+ free(hba->ldm_adapter.him_handle, M_DEVBUF);
+ return -1;
+ }
+
+ os_printk("adapter at PCI %d:%d:%d, IRQ %d",
+ hba->pciaddr.bus, hba->pciaddr.device, hba->pciaddr.function, pci_get_irq(dev));
+
+ if (!ldm_register_adapter(&hba->ldm_adapter)) {
+ size = ldm_get_vbus_size();
+ vbus_ext = malloc(sizeof(VBUS_EXT) + size, M_DEVBUF, M_WAITOK);
+ if (!vbus_ext) {
+ free(hba->ldm_adapter.him_handle, M_DEVBUF);
+ return -1;
+ }
+ memset(vbus_ext, 0, sizeof(VBUS_EXT));
+ vbus_ext->ext_type = EXT_TYPE_VBUS;
+ ldm_create_vbus((PVBUS)vbus_ext->vbus, vbus_ext);
+ ldm_register_adapter(&hba->ldm_adapter);
+ }
+
+ ldm_for_each_vbus(vbus, vbus_ext) {
+ if (hba->ldm_adapter.vbus==vbus) {
+ hba->vbus_ext = vbus_ext;
+ hba->next = vbus_ext->hba_list;
+ vbus_ext->hba_list = hba;
+ break;
+ }
+ }
+ return 0;
+}
+
+/*
+ * Maybe we'd better to use the bus_dmamem_alloc to alloc DMA memory,
+ * but there are some problems currently (alignment, etc).
+ */
+static __inline void *__get_free_pages(int order)
+{
+ /* don't use low memory - other devices may get starved */
+ return contigmalloc(PAGE_SIZE<<order,
+ M_DEVBUF, M_WAITOK, BUS_SPACE_MAXADDR_24BIT, BUS_SPACE_MAXADDR, PAGE_SIZE, 0);
+}
+
+static __inline void free_pages(void *p, int order)
+{
+ contigfree(p, PAGE_SIZE<<order, M_DEVBUF);
+}
+
+static int hpt_alloc_mem(PVBUS_EXT vbus_ext)
+{
+ PHBA hba;
+ struct freelist *f;
+ HPT_UINT i;
+ void **p;
+
+ for (hba = vbus_ext->hba_list; hba; hba = hba->next)
+ hba->ldm_adapter.him->get_meminfo(hba->ldm_adapter.him_handle);
+
+ ldm_get_mem_info((PVBUS)vbus_ext->vbus, 0);
+
+ for (f=vbus_ext->freelist_head; f; f=f->next) {
+ KdPrint(("%s: %d*%d=%d bytes",
+ f->tag, f->count, f->size, f->count*f->size));
+ for (i=0; i<f->count; i++) {
+ p = (void **)malloc(f->size, M_DEVBUF, M_WAITOK);
+ if (!p) return (ENXIO);
+ *p = f->head;
+ f->head = p;
+ }
+ }
+
+ for (f=vbus_ext->freelist_dma_head; f; f=f->next) {
+ int order, size, j;
+
+ HPT_ASSERT((f->size & (f->alignment-1))==0);
+
+ for (order=0, size=PAGE_SIZE; size<f->size; order++, size<<=1)
+ ;
+
+ KdPrint(("%s: %d*%d=%d bytes, order %d",
+ f->tag, f->count, f->size, f->count*f->size, order));
+ HPT_ASSERT(f->alignment<=PAGE_SIZE);
+
+ for (i=0; i<f->count;) {
+ p = (void **)__get_free_pages(order);
+ if (!p) return -1;
+ for (j = size/f->size; j && i<f->count; i++,j--) {
+ *p = f->head;
+ *(BUS_ADDRESS *)(p+1) = (BUS_ADDRESS)vtophys(p);
+ f->head = p;
+ p = (void **)((unsigned long)p + f->size);
+ }
+ }
+ }
+
+ HPT_ASSERT(PAGE_SIZE==DMAPOOL_PAGE_SIZE);
+
+ for (i=0; i<os_max_cache_pages; i++) {
+ p = (void **)__get_free_pages(0);
+ if (!p) return -1;
+ HPT_ASSERT(((HPT_UPTR)p & (DMAPOOL_PAGE_SIZE-1))==0);
+ dmapool_put_page((PVBUS)vbus_ext->vbus, p, (BUS_ADDRESS)vtophys(p));
+ }
+
+ return 0;
+}
+
+static void hpt_free_mem(PVBUS_EXT vbus_ext)
+{
+ struct freelist *f;
+ void *p;
+ int i;
+ BUS_ADDRESS bus;
+
+ for (f=vbus_ext->freelist_head; f; f=f->next) {
+#if DBG
+ if (f->count!=f->reserved_count) {
+ KdPrint(("memory leak for freelist %s (%d/%d)", f->tag, f->count, f->reserved_count));
+ }
+#endif
+ while ((p=freelist_get(f)))
+ free(p, M_DEVBUF);
+ }
+
+ for (i=0; i<os_max_cache_pages; i++) {
+ p = dmapool_get_page((PVBUS)vbus_ext->vbus, &bus);
+ HPT_ASSERT(p);
+ free_pages(p, 0);
+ }
+
+ for (f=vbus_ext->freelist_dma_head; f; f=f->next) {
+ int order, size;
+#if DBG
+ if (f->count!=f->reserved_count) {
+ KdPrint(("memory leak for dma freelist %s (%d/%d)", f->tag, f->count, f->reserved_count));
+ }
+#endif
+ for (order=0, size=PAGE_SIZE; size<f->size; order++, size<<=1) ;
+
+ while ((p=freelist_get_dma(f, &bus))) {
+ if (order)
+ free_pages(p, order);
+ else {
+ /* can't free immediately since other blocks in this page may still be in the list */
+ if (((HPT_UPTR)p & (PAGE_SIZE-1))==0)
+ dmapool_put_page((PVBUS)vbus_ext->vbus, p, bus);
+ }
+ }
+ }
+
+ while ((p = dmapool_get_page((PVBUS)vbus_ext->vbus, &bus)))
+ free_pages(p, 0);
+}
+
+static int hpt_init_vbus(PVBUS_EXT vbus_ext)
+{
+ PHBA hba;
+
+ for (hba = vbus_ext->hba_list; hba; hba = hba->next)
+ if (!hba->ldm_adapter.him->initialize(hba->ldm_adapter.him_handle)) {
+ KdPrint(("fail to initialize %p", hba));
+ return -1;
+ }
+
+ ldm_initialize_vbus((PVBUS)vbus_ext->vbus, &vbus_ext->hba_list->ldm_adapter);
+ return 0;
+}
+
+static void hpt_flush_done(PCOMMAND pCmd)
+{
+ PVDEV vd = pCmd->target;
+
+ if (mIsArray(vd->type) && vd->u.array.transform && vd!=vd->u.array.transform->target) {
+ vd = vd->u.array.transform->target;
+ HPT_ASSERT(vd);
+ pCmd->target = vd;
+ pCmd->Result = RETURN_PENDING;
+ vdev_queue_cmd(pCmd);
+ return;
+ }
+
+ *(int *)pCmd->priv = 1;
+ wakeup(pCmd);
+}
+
+/*
+ * flush a vdev (without retry).
+ */
+static int hpt_flush_vdev(PVBUS_EXT vbus_ext, PVDEV vd)
+{
+ PCOMMAND pCmd;
+ int result = 0, done;
+ HPT_UINT count;
+
+ KdPrint(("flusing dev %p", vd));
+
+ hpt_lock_vbus(vbus_ext);
+
+ if (mIsArray(vd->type) && vd->u.array.transform)
+ count = MAX(vd->u.array.transform->source->cmds_per_request,
+ vd->u.array.transform->target->cmds_per_request);
+ else
+ count = vd->cmds_per_request;
+
+ pCmd = ldm_alloc_cmds(vd->vbus, count);
+
+ if (!pCmd) {
+ hpt_unlock_vbus(vbus_ext);
+ return -1;
+ }
+
+ pCmd->type = CMD_TYPE_FLUSH;
+ pCmd->flags.hard_flush = 1;
+ pCmd->target = vd;
+ pCmd->done = hpt_flush_done;
+ done = 0;
+ pCmd->priv = &done;
+
+ ldm_queue_cmd(pCmd);
+
+ if (!done) {
+ while (hpt_sleep(vbus_ext, pCmd, PPAUSE, "hptfls", HPT_OSM_TIMEOUT)) {
+ ldm_reset_vbus(vd->vbus);
+ }
+ }
+
+ KdPrint(("flush result %d", pCmd->Result));
+
+ if (pCmd->Result!=RETURN_SUCCESS)
+ result = -1;
+
+ ldm_free_cmds(pCmd);
+
+ hpt_unlock_vbus(vbus_ext);
+
+ return result;
+}
+
+static void hpt_stop_tasks(PVBUS_EXT vbus_ext);
+static void hpt_shutdown_vbus(PVBUS_EXT vbus_ext, int howto)
+{
+ PVBUS vbus = (PVBUS)vbus_ext->vbus;
+ PHBA hba;
+ int i;
+
+ KdPrint(("hpt_shutdown_vbus"));
+
+ /* stop all ctl tasks and disable the worker taskqueue */
+ hpt_stop_tasks(vbus_ext);
+ vbus_ext->worker.ta_context = 0;
+
+ /* flush devices */
+ for (i=0; i<osm_max_targets; i++) {
+ PVDEV vd = ldm_find_target(vbus, i);
+ if (vd) {
+ /* retry once */
+ if (hpt_flush_vdev(vbus_ext, vd))
+ hpt_flush_vdev(vbus_ext, vd);
+ }
+ }
+
+ hpt_lock_vbus(vbus_ext);
+ ldm_shutdown(vbus);
+ hpt_unlock_vbus(vbus_ext);
+
+ ldm_release_vbus(vbus);
+
+ for (hba=vbus_ext->hba_list; hba; hba=hba->next)
+ bus_teardown_intr(hba->pcidev, hba->irq_res, hba->irq_handle);
+
+ hpt_free_mem(vbus_ext);
+
+ while ((hba=vbus_ext->hba_list)) {
+ vbus_ext->hba_list = hba->next;
+ free(hba->ldm_adapter.him_handle, M_DEVBUF);
+ }
+
+ free(vbus_ext, M_DEVBUF);
+ KdPrint(("hpt_shutdown_vbus done"));
+}
+
+static void __hpt_do_tasks(PVBUS_EXT vbus_ext)
+{
+ OSM_TASK *tasks;
+
+ tasks = vbus_ext->tasks;
+ vbus_ext->tasks = 0;
+
+ while (tasks) {
+ OSM_TASK *t = tasks;
+ tasks = t->next;
+ t->next = 0;
+ t->func(vbus_ext->vbus, t->data);
+ }
+}
+
+static void hpt_do_tasks(PVBUS_EXT vbus_ext, int pending)
+{
+ if(vbus_ext){
+ hpt_lock_vbus(vbus_ext);
+ __hpt_do_tasks(vbus_ext);
+ hpt_unlock_vbus(vbus_ext);
+ }
+}
+
+static void hpt_action(struct cam_sim *sim, union ccb *ccb);
*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
More information about the svn-src-stable-9
mailing list