xref: /freebsd/sys/dev/hptnr/hptnr_os_bsd.c (revision 1587a9db)
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