11fdeb165SXin LI /* $Id: os_bsd.c,v 1.13 2010/05/11 03:12:11 lcn Exp $ */
21fdeb165SXin LI /*-
34d846d26SWarner Losh * SPDX-License-Identifier: BSD-2-Clause
4718cf2ccSPedro F. Giffuni *
51fdeb165SXin LI * HighPoint RAID Driver for FreeBSD
61fdeb165SXin LI * Copyright (C) 2005-2011 HighPoint Technologies, Inc. All Rights Reserved.
71fdeb165SXin LI * All rights reserved.
81fdeb165SXin LI *
91fdeb165SXin LI * Redistribution and use in source and binary forms, with or without
101fdeb165SXin LI * modification, are permitted provided that the following conditions
111fdeb165SXin LI * are met:
121fdeb165SXin LI * 1. Redistributions of source code must retain the above copyright
131fdeb165SXin LI * notice, this list of conditions and the following disclaimer.
141fdeb165SXin LI * 2. Redistributions in binary form must reproduce the above copyright
151fdeb165SXin LI * notice, this list of conditions and the following disclaimer in the
161fdeb165SXin LI * documentation and/or other materials provided with the distribution.
171fdeb165SXin LI *
181fdeb165SXin LI * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
191fdeb165SXin LI * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
201fdeb165SXin LI * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
211fdeb165SXin LI * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
221fdeb165SXin LI * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
231fdeb165SXin LI * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
241fdeb165SXin LI * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
251fdeb165SXin LI * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
261fdeb165SXin LI * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
271fdeb165SXin LI * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
281fdeb165SXin LI * SUCH DAMAGE.
291fdeb165SXin LI */
301fdeb165SXin LI
311fdeb165SXin LI #include <dev/hptnr/hptnr_config.h>
321fdeb165SXin LI #include <dev/hptnr/os_bsd.h>
331fdeb165SXin LI
341fdeb165SXin LI BUS_ADDRESS get_dmapool_phy_addr(void *osext, void * dmapool_virt_addr);
351fdeb165SXin LI
361fdeb165SXin LI /* hardware access */
os_inb(void * port)371fdeb165SXin LI HPT_U8 os_inb (void *port) { return inb((unsigned)(HPT_UPTR)port); }
os_inw(void * port)381fdeb165SXin LI HPT_U16 os_inw (void *port) { return inw((unsigned)(HPT_UPTR)port); }
os_inl(void * port)391fdeb165SXin LI HPT_U32 os_inl (void *port) { return inl((unsigned)(HPT_UPTR)port); }
401fdeb165SXin LI
os_outb(void * port,HPT_U8 value)411fdeb165SXin LI void os_outb (void *port, HPT_U8 value) { outb((unsigned)(HPT_UPTR)port, (value)); }
os_outw(void * port,HPT_U16 value)421fdeb165SXin LI void os_outw (void *port, HPT_U16 value) { outw((unsigned)(HPT_UPTR)port, (value)); }
os_outl(void * port,HPT_U32 value)431fdeb165SXin LI void os_outl (void *port, HPT_U32 value) { outl((unsigned)(HPT_UPTR)port, (value)); }
441fdeb165SXin LI
os_insw(void * port,HPT_U16 * buffer,HPT_U32 count)451fdeb165SXin LI void os_insw (void *port, HPT_U16 *buffer, HPT_U32 count)
461fdeb165SXin LI { insw((unsigned)(HPT_UPTR)port, (void *)buffer, count); }
471fdeb165SXin LI
os_outsw(void * port,HPT_U16 * buffer,HPT_U32 count)481fdeb165SXin LI void os_outsw(void *port, HPT_U16 *buffer, HPT_U32 count)
491fdeb165SXin LI { outsw((unsigned)(HPT_UPTR)port, (void *)buffer, count); }
501fdeb165SXin LI
511fdeb165SXin LI HPT_U32 __dummy_reg = 0;
521fdeb165SXin LI
531fdeb165SXin LI /* PCI configuration space */
os_pci_readb(void * osext,HPT_U8 offset)541fdeb165SXin LI HPT_U8 os_pci_readb (void *osext, HPT_U8 offset)
551fdeb165SXin LI {
561fdeb165SXin LI return pci_read_config(((PHBA)osext)->pcidev, offset, 1);
571fdeb165SXin LI }
581fdeb165SXin LI
os_pci_readw(void * osext,HPT_U8 offset)591fdeb165SXin LI HPT_U16 os_pci_readw (void *osext, HPT_U8 offset)
601fdeb165SXin LI {
611fdeb165SXin LI return pci_read_config(((PHBA)osext)->pcidev, offset, 2);
621fdeb165SXin LI }
631fdeb165SXin LI
os_pci_readl(void * osext,HPT_U8 offset)641fdeb165SXin LI HPT_U32 os_pci_readl (void *osext, HPT_U8 offset)
651fdeb165SXin LI {
661fdeb165SXin LI return pci_read_config(((PHBA)osext)->pcidev, offset, 4);
671fdeb165SXin LI }
681fdeb165SXin LI
os_pci_writeb(void * osext,HPT_U8 offset,HPT_U8 value)691fdeb165SXin LI void os_pci_writeb (void *osext, HPT_U8 offset, HPT_U8 value)
701fdeb165SXin LI {
711fdeb165SXin LI pci_write_config(((PHBA)osext)->pcidev, offset, value, 1);
721fdeb165SXin LI }
731fdeb165SXin LI
os_pci_writew(void * osext,HPT_U8 offset,HPT_U16 value)741fdeb165SXin LI void os_pci_writew (void *osext, HPT_U8 offset, HPT_U16 value)
751fdeb165SXin LI {
761fdeb165SXin LI pci_write_config(((PHBA)osext)->pcidev, offset, value, 2);
771fdeb165SXin LI }
781fdeb165SXin LI
os_pci_writel(void * osext,HPT_U8 offset,HPT_U32 value)791fdeb165SXin LI void os_pci_writel (void *osext, HPT_U8 offset, HPT_U32 value)
801fdeb165SXin LI {
811fdeb165SXin LI pci_write_config(((PHBA)osext)->pcidev, offset, value, 4);
821fdeb165SXin LI }
831fdeb165SXin LI
get_dmapool_phy_addr(void * osext,void * dmapool_virt_addr)841fdeb165SXin LI BUS_ADDRESS get_dmapool_phy_addr(void *osext, void * dmapool_virt_addr)
851fdeb165SXin LI {
861fdeb165SXin LI return (BUS_ADDRESS)vtophys(dmapool_virt_addr);
871fdeb165SXin LI }
881fdeb165SXin LI
pcicfg_read_dword(HPT_U8 bus,HPT_U8 dev,HPT_U8 func,HPT_U8 reg)891fdeb165SXin LI HPT_U32 pcicfg_read_dword(HPT_U8 bus, HPT_U8 dev, HPT_U8 func, HPT_U8 reg)
901fdeb165SXin LI {
911587a9dbSJohn Baldwin return (HPT_U32)pci_cfgregread(0, bus, dev, func, reg, 4);
921fdeb165SXin LI }/* PCI space access */
931fdeb165SXin LI
os_map_pci_bar(void * osext,int index,HPT_U32 offset,HPT_U32 length)941fdeb165SXin LI void *os_map_pci_bar(
951fdeb165SXin LI void *osext,
961fdeb165SXin LI int index,
971fdeb165SXin LI HPT_U32 offset,
981fdeb165SXin LI HPT_U32 length
991fdeb165SXin LI )
1001fdeb165SXin LI {
1011fdeb165SXin LI PHBA hba = (PHBA)osext;
1021fdeb165SXin LI HPT_U32 base;
1031fdeb165SXin LI
1041fdeb165SXin LI hba->pcibar[index].rid = 0x10 + index * 4;
1051fdeb165SXin LI base = pci_read_config(hba->pcidev, hba->pcibar[index].rid, 4);
1061fdeb165SXin LI
1071fdeb165SXin LI if (base & 1) {
1081fdeb165SXin LI hba->pcibar[index].type = SYS_RES_IOPORT;
109eff83876SJustin Hibbits hba->pcibar[index].res = bus_alloc_resource_any(hba->pcidev,
110eff83876SJustin Hibbits hba->pcibar[index].type, &hba->pcibar[index].rid, RF_ACTIVE);
1111fdeb165SXin LI hba->pcibar[index].base = (void *)(unsigned long)(base & ~0x1);
1121fdeb165SXin LI } else {
1131fdeb165SXin LI hba->pcibar[index].type = SYS_RES_MEMORY;
114eff83876SJustin Hibbits hba->pcibar[index].res = bus_alloc_resource_any(hba->pcidev,
115eff83876SJustin Hibbits hba->pcibar[index].type, &hba->pcibar[index].rid, RF_ACTIVE);
1161fdeb165SXin LI hba->pcibar[index].base = (char *)rman_get_virtual(hba->pcibar[index].res) + offset;
1171fdeb165SXin LI }
1181fdeb165SXin LI
1191fdeb165SXin LI return hba->pcibar[index].base;
1201fdeb165SXin LI }
1211fdeb165SXin LI
os_unmap_pci_bar(void * osext,void * base)1221fdeb165SXin LI void os_unmap_pci_bar(void *osext, void *base)
1231fdeb165SXin LI {
1241fdeb165SXin LI PHBA hba = (PHBA)osext;
1251fdeb165SXin LI int index;
1261fdeb165SXin LI
1271fdeb165SXin LI for (index=0; index<6; index++) {
1281fdeb165SXin LI if (hba->pcibar[index].base==base) {
1291fdeb165SXin LI bus_release_resource(hba->pcidev, hba->pcibar[index].type,
1301fdeb165SXin LI hba->pcibar[index].rid, hba->pcibar[index].res);
1311fdeb165SXin LI hba->pcibar[index].base = 0;
1321fdeb165SXin LI return;
1331fdeb165SXin LI }
1341fdeb165SXin LI }
1351fdeb165SXin LI }
1361fdeb165SXin LI
freelist_reserve(struct freelist * list,void * osext,HPT_UINT size,HPT_UINT count)1371fdeb165SXin LI void freelist_reserve(struct freelist *list, void *osext, HPT_UINT size, HPT_UINT count)
1381fdeb165SXin LI {
1391fdeb165SXin LI PVBUS_EXT vbus_ext = osext;
1401fdeb165SXin LI
1411fdeb165SXin LI if (vbus_ext->ext_type!=EXT_TYPE_VBUS)
1421fdeb165SXin LI vbus_ext = ((PHBA)osext)->vbus_ext;
1431fdeb165SXin LI
1441fdeb165SXin LI list->next = vbus_ext->freelist_head;
1451fdeb165SXin LI vbus_ext->freelist_head = list;
1461fdeb165SXin LI list->dma = 0;
1471fdeb165SXin LI list->size = size;
1481fdeb165SXin LI list->head = 0;
1491fdeb165SXin LI #if DBG
1501fdeb165SXin LI list->reserved_count =
1511fdeb165SXin LI #endif
1521fdeb165SXin LI list->count = count;
1531fdeb165SXin LI }
1541fdeb165SXin LI
freelist_get(struct freelist * list)1551fdeb165SXin LI void *freelist_get(struct freelist *list)
1561fdeb165SXin LI {
1571fdeb165SXin LI void * result;
1581fdeb165SXin LI if (list->count) {
1591fdeb165SXin LI HPT_ASSERT(list->head);
1601fdeb165SXin LI result = list->head;
1611fdeb165SXin LI list->head = *(void **)result;
1621fdeb165SXin LI list->count--;
1631fdeb165SXin LI return result;
1641fdeb165SXin LI }
1651fdeb165SXin LI return 0;
1661fdeb165SXin LI }
1671fdeb165SXin LI
freelist_put(struct freelist * list,void * p)1681fdeb165SXin LI void freelist_put(struct freelist * list, void *p)
1691fdeb165SXin LI {
1701fdeb165SXin LI HPT_ASSERT(list->dma==0);
1711fdeb165SXin LI list->count++;
1721fdeb165SXin LI *(void **)p = list->head;
1731fdeb165SXin LI list->head = p;
1741fdeb165SXin LI }
1751fdeb165SXin LI
freelist_reserve_dma(struct freelist * list,void * osext,HPT_UINT size,HPT_UINT alignment,HPT_UINT count)1761fdeb165SXin LI void freelist_reserve_dma(struct freelist *list, void *osext, HPT_UINT size, HPT_UINT alignment, HPT_UINT count)
1771fdeb165SXin LI {
1781fdeb165SXin LI PVBUS_EXT vbus_ext = osext;
1791fdeb165SXin LI
1801fdeb165SXin LI if (vbus_ext->ext_type!=EXT_TYPE_VBUS)
1811fdeb165SXin LI vbus_ext = ((PHBA)osext)->vbus_ext;
1821fdeb165SXin LI
1831fdeb165SXin LI list->next = vbus_ext->freelist_dma_head;
1841fdeb165SXin LI vbus_ext->freelist_dma_head = list;
1851fdeb165SXin LI list->dma = 1;
1861fdeb165SXin LI list->alignment = alignment;
1871fdeb165SXin LI list->size = size;
1881fdeb165SXin LI list->head = 0;
1891fdeb165SXin LI #if DBG
1901fdeb165SXin LI list->reserved_count =
1911fdeb165SXin LI #endif
1921fdeb165SXin LI list->count = count;
1931fdeb165SXin LI }
1941fdeb165SXin LI
freelist_get_dma(struct freelist * list,BUS_ADDRESS * busaddr)1951fdeb165SXin LI void *freelist_get_dma(struct freelist *list, BUS_ADDRESS *busaddr)
1961fdeb165SXin LI {
1971fdeb165SXin LI void *result;
1981fdeb165SXin LI HPT_ASSERT(list->dma);
1991fdeb165SXin LI result = freelist_get(list);
2001fdeb165SXin LI if (result)
2011fdeb165SXin LI *busaddr = *(BUS_ADDRESS *)((void **)result+1);
2021fdeb165SXin LI return result;
2031fdeb165SXin LI }
2041fdeb165SXin LI
freelist_put_dma(struct freelist * list,void * p,BUS_ADDRESS busaddr)2051fdeb165SXin LI void freelist_put_dma(struct freelist *list, void *p, BUS_ADDRESS busaddr)
2061fdeb165SXin LI {
2071fdeb165SXin LI HPT_ASSERT(list->dma);
2081fdeb165SXin LI list->count++;
2091fdeb165SXin LI *(void **)p = list->head;
2101fdeb165SXin LI *(BUS_ADDRESS *)((void **)p+1) = busaddr;
2111fdeb165SXin LI list->head = p;
2121fdeb165SXin LI }
2131fdeb165SXin LI
os_get_stamp(void)2141fdeb165SXin LI HPT_U32 os_get_stamp(void)
2151fdeb165SXin LI {
2161fdeb165SXin LI HPT_U32 stamp;
2171fdeb165SXin LI do { stamp = random(); } while (stamp==0);
2181fdeb165SXin LI return stamp;
2191fdeb165SXin LI }
2201fdeb165SXin LI
os_stallexec(HPT_U32 microseconds)2211fdeb165SXin LI void os_stallexec(HPT_U32 microseconds)
2221fdeb165SXin LI {
2231fdeb165SXin LI DELAY(microseconds);
2241fdeb165SXin LI }
2251fdeb165SXin LI
os_timer_for_ldm(void * arg)2261fdeb165SXin LI static void os_timer_for_ldm(void *arg)
2271fdeb165SXin LI {
2281fdeb165SXin LI PVBUS_EXT vbus_ext = (PVBUS_EXT)arg;
2291fdeb165SXin LI ldm_on_timer((PVBUS)vbus_ext->vbus);
2301fdeb165SXin LI }
2311fdeb165SXin LI
os_request_timer(void * osext,HPT_U32 interval)2321fdeb165SXin LI void os_request_timer(void * osext, HPT_U32 interval)
2331fdeb165SXin LI {
2341fdeb165SXin LI PVBUS_EXT vbus_ext = osext;
2351fdeb165SXin LI
2361fdeb165SXin LI HPT_ASSERT(vbus_ext->ext_type==EXT_TYPE_VBUS);
2371fdeb165SXin LI
23885c9dd9dSSteven Hartland callout_reset_sbt(&vbus_ext->timer, SBT_1US * interval, 0,
23985c9dd9dSSteven Hartland os_timer_for_ldm, vbus_ext, 0);
2401fdeb165SXin LI }
2411fdeb165SXin LI
os_query_time(void)2421fdeb165SXin LI HPT_TIME os_query_time(void)
2431fdeb165SXin LI {
2441fdeb165SXin LI return ticks * (1000000 / hz);
2451fdeb165SXin LI }
2461fdeb165SXin LI
os_schedule_task(void * osext,OSM_TASK * task)2471fdeb165SXin LI void os_schedule_task(void *osext, OSM_TASK *task)
2481fdeb165SXin LI {
2491fdeb165SXin LI PVBUS_EXT vbus_ext = osext;
2501fdeb165SXin LI
2511fdeb165SXin LI HPT_ASSERT(task->next==0);
2521fdeb165SXin LI
2531fdeb165SXin LI if (vbus_ext->tasks==0)
2541fdeb165SXin LI vbus_ext->tasks = task;
2551fdeb165SXin LI else {
2561fdeb165SXin LI OSM_TASK *t = vbus_ext->tasks;
2571fdeb165SXin LI while (t->next) t = t->next;
2581fdeb165SXin LI t->next = task;
2591fdeb165SXin LI }
2601fdeb165SXin LI
2611fdeb165SXin LI if (vbus_ext->worker.ta_context)
2621fdeb165SXin LI TASK_ENQUEUE(&vbus_ext->worker);
2631fdeb165SXin LI }
2641fdeb165SXin LI
os_revalidate_device(void * osext,int id)2651fdeb165SXin LI int os_revalidate_device(void *osext, int id)
2661fdeb165SXin LI {
2671fdeb165SXin LI
2681fdeb165SXin LI return 0;
2691fdeb165SXin LI }
2701fdeb165SXin LI
os_query_remove_device(void * osext,int id)2711fdeb165SXin LI int os_query_remove_device(void *osext, int id)
2721fdeb165SXin LI {
273090234abSXin LI return 0;
2741fdeb165SXin LI }
2751fdeb165SXin LI
os_get_vbus_seq(void * osext)2761fdeb165SXin LI HPT_U8 os_get_vbus_seq(void *osext)
2771fdeb165SXin LI {
2781fdeb165SXin LI return ((PVBUS_EXT)osext)->sim->path_id;
2791fdeb165SXin LI }
2801fdeb165SXin LI
os_printk(char * fmt,...)2811fdeb165SXin LI int os_printk(char *fmt, ...)
2821fdeb165SXin LI {
2831fdeb165SXin LI va_list args;
2841fdeb165SXin LI static char buf[512];
2851fdeb165SXin LI
2861fdeb165SXin LI va_start(args, fmt);
2871fdeb165SXin LI vsnprintf(buf, sizeof(buf), fmt, args);
2881fdeb165SXin LI va_end(args);
2891fdeb165SXin LI return printf("%s: %s\n", driver_name, buf);
2901fdeb165SXin LI }
2911fdeb165SXin LI
2921fdeb165SXin LI #if DBG
os_check_stack(const char * location,int size)2931fdeb165SXin LI void os_check_stack(const char *location, int size){}
2941fdeb165SXin LI
__os_dbgbreak(const char * file,int line)2951fdeb165SXin LI void __os_dbgbreak(const char *file, int line)
2961fdeb165SXin LI {
2971fdeb165SXin LI printf("*** break at %s:%d ***", file, line);
2981fdeb165SXin LI while (1);
2991fdeb165SXin LI }
3001fdeb165SXin LI
3011fdeb165SXin LI int hpt_dbg_level = 1;
3021fdeb165SXin LI #endif
303