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 delp...@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 ***
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to