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"