svn commit: r252867 - in head: 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 07:49:43 UTC 2013


Author: delphij
Date: Sat Jul  6 07:49:41 2013
New Revision: 252867
URL: http://svnweb.freebsd.org/changeset/base/252867

Log:
  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.
  
  MFC after:	1 day

Added:
  head/share/man/man4/hptnr.4   (contents, props changed)
  head/sys/dev/hpt27xx/hpt27xx_os_bsd.c
     - copied unchanged from r252864, head/sys/dev/hpt27xx/os_bsd.c
  head/sys/dev/hpt27xx/hpt27xx_osm_bsd.c
     - copied unchanged from r252859, head/sys/dev/hpt27xx/osm_bsd.c
  head/sys/dev/hptnr/
  head/sys/dev/hptnr/README   (contents, props changed)
  head/sys/dev/hptnr/amd64-elf.hptnr_lib.o.uu   (contents, props changed)
  head/sys/dev/hptnr/array.h   (contents, props changed)
  head/sys/dev/hptnr/him.h   (contents, props changed)
  head/sys/dev/hptnr/himfuncs.h   (contents, props changed)
  head/sys/dev/hptnr/hptintf.h   (contents, props changed)
  head/sys/dev/hptnr/hptnr_config.c   (contents, props changed)
  head/sys/dev/hptnr/hptnr_config.h   (contents, props changed)
  head/sys/dev/hptnr/hptnr_os_bsd.c   (contents, props changed)
  head/sys/dev/hptnr/hptnr_osm_bsd.c   (contents, props changed)
  head/sys/dev/hptnr/i386-elf.hptnr_lib.o.uu   (contents, props changed)
  head/sys/dev/hptnr/ldm.h   (contents, props changed)
  head/sys/dev/hptnr/list.h   (contents, props changed)
  head/sys/dev/hptnr/os_bsd.h   (contents, props changed)
  head/sys/dev/hptnr/osm.h   (contents, props changed)
  head/sys/dev/hptnr/wj.h   (contents, props changed)
  head/sys/modules/hptnr/
  head/sys/modules/hptnr/Makefile   (contents, props changed)
Deleted:
  head/sys/dev/hpt27xx/os_bsd.c
  head/sys/dev/hpt27xx/osm_bsd.c
Modified:
  head/share/man/man4/Makefile
  head/sys/amd64/conf/GENERIC
  head/sys/amd64/conf/NOTES
  head/sys/conf/WITHOUT_SOURCELESS_HOST
  head/sys/conf/files.amd64
  head/sys/conf/files.i386
  head/sys/i386/conf/GENERIC
  head/sys/i386/conf/NOTES
  head/sys/i386/conf/PAE
  head/sys/i386/conf/XEN
  head/sys/modules/Makefile
  head/sys/modules/hpt27xx/Makefile

Modified: head/share/man/man4/Makefile
==============================================================================
--- head/share/man/man4/Makefile	Sat Jul  6 06:34:53 2013	(r252866)
+++ head/share/man/man4/Makefile	Sat Jul  6 07:49:41 2013	(r252867)
@@ -163,6 +163,7 @@ MAN=	aac.4 \
 	${_hpt27xx.4} \
 	${_hptiop.4} \
 	${_hptmv.4} \
+	${_hptnr.4} \
 	${_hptrr.4} \
 	hwpmc.4 \
 	ichsmb.4 \
@@ -745,6 +746,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

Added: head/share/man/man4/hptnr.4
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/share/man/man4/hptnr.4	Sat Jul  6 07:49:41 2013	(r252867)
@@ -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: head/sys/amd64/conf/GENERIC
==============================================================================
--- head/sys/amd64/conf/GENERIC	Sat Jul  6 06:34:53 2013	(r252866)
+++ head/sys/amd64/conf/GENERIC	Sat Jul  6 07:49:41 2013	(r252867)
@@ -147,6 +147,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: head/sys/amd64/conf/NOTES
==============================================================================
--- head/sys/amd64/conf/NOTES	Sat Jul  6 06:34:53 2013	(r252866)
+++ head/sys/amd64/conf/NOTES	Sat Jul  6 07:49:41 2013	(r252867)
@@ -418,6 +418,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: head/sys/conf/WITHOUT_SOURCELESS_HOST
==============================================================================
--- head/sys/conf/WITHOUT_SOURCELESS_HOST	Sat Jul  6 06:34:53 2013	(r252866)
+++ head/sys/conf/WITHOUT_SOURCELESS_HOST	Sat Jul  6 07:49:41 2013	(r252867)
@@ -6,5 +6,6 @@
 
 nodevice	hpt27xx
 nodevice	hptmv
+nodevice	hptnr
 nodevice	hptrr
 nodevice	nve

Modified: head/sys/conf/files.amd64
==============================================================================
--- head/sys/conf/files.amd64	Sat Jul  6 06:34:53 2013	(r252866)
+++ head/sys/conf/files.amd64	Sat Jul  6 07:49:41 2013	(r252867)
@@ -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" \
@@ -190,14 +197,17 @@ dev/fdc/fdc_acpi.c		optional	fdc
 dev/fdc/fdc_isa.c		optional	fdc isa
 dev/fdc/fdc_pccard.c		optional	fdc pccard
 dev/fdt/fdt_x86.c		optional	fdt
-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: head/sys/conf/files.i386
==============================================================================
--- head/sys/conf/files.i386	Sat Jul  6 06:34:53 2013	(r252866)
+++ head/sys/conf/files.i386	Sat Jul  6 07:49:41 2013	(r252867)
@@ -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" \
@@ -181,14 +187,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: head/sys/dev/hpt27xx/hpt27xx_os_bsd.c (from r252864, head/sys/dev/hpt27xx/os_bsd.c)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sys/dev/hpt27xx/hpt27xx_os_bsd.c	Sat Jul  6 07:49:41 2013	(r252867, copy of r252864, head/sys/dev/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: head/sys/dev/hpt27xx/hpt27xx_osm_bsd.c (from r252859, head/sys/dev/hpt27xx/osm_bsd.c)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sys/dev/hpt27xx/hpt27xx_osm_bsd.c	Sat Jul  6 07:49:41 2013	(r252867, copy of r252859, head/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-head mailing list