xref: /freebsd/sys/dev/hptrr/hptrr_os_bsd.c (revision 95ee2897e98f5d444f26ed2334cc7c439f9c16c6)
1718cf2ccSPedro F. Giffuni /*-
2*4d846d26SWarner Losh  * SPDX-License-Identifier: BSD-2-Clause
3718cf2ccSPedro F. Giffuni  *
4b063a422SScott Long  * Copyright (c) HighPoint Technologies, Inc.
5b063a422SScott Long  * All rights reserved.
6b063a422SScott Long  *
7b063a422SScott Long  * Redistribution and use in source and binary forms, with or without
8b063a422SScott Long  * modification, are permitted provided that the following conditions
9b063a422SScott Long  * are met:
10b063a422SScott Long  * 1. Redistributions of source code must retain the above copyright
11b063a422SScott Long  *    notice, this list of conditions and the following disclaimer.
12b063a422SScott Long  * 2. Redistributions in binary form must reproduce the above copyright
13b063a422SScott Long  *    notice, this list of conditions and the following disclaimer in the
14b063a422SScott Long  *    documentation and/or other materials provided with the distribution.
15b063a422SScott Long  *
16b063a422SScott Long  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17b063a422SScott Long  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18b063a422SScott Long  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19b063a422SScott Long  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20b063a422SScott Long  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21b063a422SScott Long  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22b063a422SScott Long  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23b063a422SScott Long  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24b063a422SScott Long  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25b063a422SScott Long  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26b063a422SScott Long  * SUCH DAMAGE.
27b063a422SScott Long  */
28b063a422SScott Long #include <dev/hptrr/hptrr_config.h>
29b063a422SScott Long /* $Id: os_bsd.c,v 1.11 2005/06/03 14:06:38 kdh Exp $
30b063a422SScott Long  *
31b063a422SScott Long  * HighPoint RAID Driver for FreeBSD
32b063a422SScott Long  * Copyright (C) 2005 HighPoint Technologies, Inc. All Rights Reserved.
33b063a422SScott Long  */
34b063a422SScott Long 
35b063a422SScott Long #include <dev/hptrr/os_bsd.h>
36b063a422SScott Long 
37b063a422SScott Long /* hardware access */
os_inb(void * port)38b063a422SScott Long HPT_U8   os_inb  (void *port) { return inb((unsigned)(HPT_UPTR)port); }
os_inw(void * port)39b063a422SScott Long HPT_U16  os_inw  (void *port) { return inw((unsigned)(HPT_UPTR)port); }
os_inl(void * port)40b063a422SScott Long HPT_U32  os_inl  (void *port) { return inl((unsigned)(HPT_UPTR)port); }
41b063a422SScott Long 
os_outb(void * port,HPT_U8 value)42b063a422SScott Long void os_outb (void *port, HPT_U8 value) { outb((unsigned)(HPT_UPTR)port, (value)); }
os_outw(void * port,HPT_U16 value)43b063a422SScott Long void os_outw (void *port, HPT_U16 value) { outw((unsigned)(HPT_UPTR)port, (value)); }
os_outl(void * port,HPT_U32 value)44b063a422SScott Long void os_outl (void *port, HPT_U32 value) { outl((unsigned)(HPT_UPTR)port, (value)); }
45b063a422SScott Long 
os_insw(void * port,HPT_U16 * buffer,HPT_U32 count)46b063a422SScott Long void os_insw (void *port, HPT_U16 *buffer, HPT_U32 count)
47b063a422SScott Long { insw((unsigned)(HPT_UPTR)port, (void *)buffer, count); }
48b063a422SScott Long 
os_outsw(void * port,HPT_U16 * buffer,HPT_U32 count)49b063a422SScott Long void os_outsw(void *port, HPT_U16 *buffer, HPT_U32 count)
50b063a422SScott Long { outsw((unsigned)(HPT_UPTR)port, (void *)buffer, count); }
51b063a422SScott Long 
52b063a422SScott Long HPT_U32 __dummy_reg = 0;
53b063a422SScott Long 
54b063a422SScott Long /* PCI configuration space */
os_pci_readb(void * osext,HPT_U8 offset)55b063a422SScott Long HPT_U8  os_pci_readb (void *osext, HPT_U8 offset)
56b063a422SScott Long {
57b063a422SScott Long     return  pci_read_config(((PHBA)osext)->pcidev, offset, 1);
58b063a422SScott Long }
59b063a422SScott Long 
os_pci_readw(void * osext,HPT_U8 offset)60b063a422SScott Long HPT_U16 os_pci_readw (void *osext, HPT_U8 offset)
61b063a422SScott Long {
62b063a422SScott Long     return  pci_read_config(((PHBA)osext)->pcidev, offset, 2);
63b063a422SScott Long }
64b063a422SScott Long 
os_pci_readl(void * osext,HPT_U8 offset)65b063a422SScott Long HPT_U32 os_pci_readl (void *osext, HPT_U8 offset)
66b063a422SScott Long {
67b063a422SScott Long     return  pci_read_config(((PHBA)osext)->pcidev, offset, 4);
68b063a422SScott Long }
69b063a422SScott Long 
os_pci_writeb(void * osext,HPT_U8 offset,HPT_U8 value)70b063a422SScott Long void os_pci_writeb (void *osext, HPT_U8 offset, HPT_U8 value)
71b063a422SScott Long {
72b063a422SScott Long     pci_write_config(((PHBA)osext)->pcidev, offset, value, 1);
73b063a422SScott Long }
74b063a422SScott Long 
os_pci_writew(void * osext,HPT_U8 offset,HPT_U16 value)75b063a422SScott Long void os_pci_writew (void *osext, HPT_U8 offset, HPT_U16 value)
76b063a422SScott Long {
77b063a422SScott Long     pci_write_config(((PHBA)osext)->pcidev, offset, value, 2);
78b063a422SScott Long }
79b063a422SScott Long 
os_pci_writel(void * osext,HPT_U8 offset,HPT_U32 value)80b063a422SScott Long void os_pci_writel (void *osext, HPT_U8 offset, HPT_U32 value)
81b063a422SScott Long {
82b063a422SScott Long     pci_write_config(((PHBA)osext)->pcidev, offset, value, 4);
83b063a422SScott Long }
84b063a422SScott Long 
os_map_pci_bar(void * osext,int index,HPT_U32 offset,HPT_U32 length)85b063a422SScott Long void *os_map_pci_bar(
86b063a422SScott Long     void *osext,
87b063a422SScott Long     int index,
88b063a422SScott Long     HPT_U32 offset,
89b063a422SScott Long     HPT_U32 length
90b063a422SScott Long )
91b063a422SScott Long {
92b063a422SScott Long 	PHBA hba = (PHBA)osext;
93b063a422SScott Long 
94b063a422SScott Long     hba->pcibar[index].rid = 0x10 + index * 4;
95b063a422SScott Long 
96b063a422SScott Long     if (pci_read_config(hba->pcidev, hba->pcibar[index].rid, 4) & 1)
97b063a422SScott Long     	hba->pcibar[index].type = SYS_RES_IOPORT;
98b063a422SScott Long     else
99b063a422SScott Long     	hba->pcibar[index].type = SYS_RES_MEMORY;
100b063a422SScott Long 
101eff83876SJustin Hibbits     hba->pcibar[index].res = bus_alloc_resource_any(hba->pcidev,
102eff83876SJustin Hibbits 		hba->pcibar[index].type, &hba->pcibar[index].rid, RF_ACTIVE);
103b063a422SScott Long 
104b063a422SScott Long 	hba->pcibar[index].base = (char *)rman_get_virtual(hba->pcibar[index].res) + offset;
105b063a422SScott Long 	return hba->pcibar[index].base;
106b063a422SScott Long }
107b063a422SScott Long 
os_unmap_pci_bar(void * osext,void * base)108b063a422SScott Long void os_unmap_pci_bar(void *osext, void *base)
109b063a422SScott Long {
110b063a422SScott Long 	PHBA hba = (PHBA)osext;
111b063a422SScott Long 	int index;
112b063a422SScott Long 
113b063a422SScott Long 	for (index=0; index<6; index++) {
114b063a422SScott Long 		if (hba->pcibar[index].base==base) {
115b063a422SScott Long 			bus_release_resource(hba->pcidev, hba->pcibar[index].type,
116b063a422SScott Long 				hba->pcibar[index].rid, hba->pcibar[index].res);
117b063a422SScott Long 			hba->pcibar[index].base = 0;
118b063a422SScott Long 			return;
119b063a422SScott Long 		}
120b063a422SScott Long 	}
121b063a422SScott Long }
122b063a422SScott Long 
freelist_reserve(struct freelist * list,void * osext,HPT_UINT size,HPT_UINT count)123b063a422SScott Long void freelist_reserve(struct freelist *list, void *osext, HPT_UINT size, HPT_UINT count)
124b063a422SScott Long {
125b063a422SScott Long     PVBUS_EXT vbus_ext = osext;
126b063a422SScott Long 
127b063a422SScott Long     if (vbus_ext->ext_type!=EXT_TYPE_VBUS)
128b063a422SScott Long         vbus_ext = ((PHBA)osext)->vbus_ext;
129b063a422SScott Long 
130b063a422SScott Long     list->next = vbus_ext->freelist_head;
131b063a422SScott Long     vbus_ext->freelist_head = list;
132b063a422SScott Long     list->dma = 0;
133b063a422SScott Long     list->size = size;
134b063a422SScott Long     list->head = 0;
1359d6a74ebSScott Long #if DBG
136b063a422SScott Long     list->reserved_count =
137b063a422SScott Long #endif
138b063a422SScott Long     list->count = count;
139b063a422SScott Long }
140b063a422SScott Long 
freelist_get(struct freelist * list)141b063a422SScott Long void *freelist_get(struct freelist *list)
142b063a422SScott Long {
143b063a422SScott Long     void * result;
144b063a422SScott Long     if (list->count) {
145b063a422SScott Long         HPT_ASSERT(list->head);
146b063a422SScott Long         result = list->head;
147b063a422SScott Long         list->head = *(void **)result;
148b063a422SScott Long         list->count--;
149b063a422SScott Long         return result;
150b063a422SScott Long     }
151b063a422SScott Long     return 0;
152b063a422SScott Long }
153b063a422SScott Long 
freelist_put(struct freelist * list,void * p)154b063a422SScott Long void freelist_put(struct freelist * list, void *p)
155b063a422SScott Long {
156b063a422SScott Long     HPT_ASSERT(list->dma==0);
157b063a422SScott Long     list->count++;
158b063a422SScott Long     *(void **)p = list->head;
159b063a422SScott Long     list->head = p;
160b063a422SScott Long }
161b063a422SScott Long 
freelist_reserve_dma(struct freelist * list,void * osext,HPT_UINT size,HPT_UINT alignment,HPT_UINT count)162b063a422SScott Long void freelist_reserve_dma(struct freelist *list, void *osext, HPT_UINT size, HPT_UINT alignment, HPT_UINT count)
163b063a422SScott Long {
164b063a422SScott Long     PVBUS_EXT vbus_ext = osext;
165b063a422SScott Long 
166b063a422SScott Long     if (vbus_ext->ext_type!=EXT_TYPE_VBUS)
167b063a422SScott Long         vbus_ext = ((PHBA)osext)->vbus_ext;
168b063a422SScott Long 
169b063a422SScott Long     list->next = vbus_ext->freelist_dma_head;
170b063a422SScott Long     vbus_ext->freelist_dma_head = list;
171b063a422SScott Long     list->dma = 1;
172b063a422SScott Long     list->alignment = alignment;
173b063a422SScott Long     list->size = size;
174b063a422SScott Long     list->head = 0;
1759d6a74ebSScott Long #if DBG
176b063a422SScott Long     list->reserved_count =
177b063a422SScott Long #endif
178b063a422SScott Long     list->count = count;
179b063a422SScott Long }
180b063a422SScott Long 
freelist_get_dma(struct freelist * list,BUS_ADDRESS * busaddr)181b063a422SScott Long void *freelist_get_dma(struct freelist *list, BUS_ADDRESS *busaddr)
182b063a422SScott Long {
183b063a422SScott Long     void *result;
184b063a422SScott Long     HPT_ASSERT(list->dma);
185b063a422SScott Long     result = freelist_get(list);
186b063a422SScott Long     if (result)
187b063a422SScott Long         *busaddr = *(BUS_ADDRESS *)((void **)result+1);
188b063a422SScott Long     return result;
189b063a422SScott Long }
190b063a422SScott Long 
freelist_put_dma(struct freelist * list,void * p,BUS_ADDRESS busaddr)191b063a422SScott Long void freelist_put_dma(struct freelist *list, void *p, BUS_ADDRESS busaddr)
192b063a422SScott Long {
193b063a422SScott Long     HPT_ASSERT(list->dma);
194b063a422SScott Long     list->count++;
195b063a422SScott Long     *(void **)p = list->head;
196b063a422SScott Long     *(BUS_ADDRESS *)((void **)p+1) = busaddr;
197b063a422SScott Long     list->head = p;
198b063a422SScott Long }
199b063a422SScott Long 
os_get_stamp(void)200b063a422SScott Long HPT_U32 os_get_stamp(void)
201b063a422SScott Long {
202b063a422SScott Long     HPT_U32 stamp;
203b063a422SScott Long     do { stamp = random(); } while (stamp==0);
204b063a422SScott Long     return stamp;
205b063a422SScott Long }
206b063a422SScott Long 
os_stallexec(HPT_U32 microseconds)207b063a422SScott Long void os_stallexec(HPT_U32 microseconds)
208b063a422SScott Long {
209b063a422SScott Long     DELAY(microseconds);
210b063a422SScott Long }
211b063a422SScott Long 
os_timer_for_ldm(void * arg)212b063a422SScott Long static void os_timer_for_ldm(void *arg)
213b063a422SScott Long {
214b063a422SScott Long 	PVBUS_EXT vbus_ext = (PVBUS_EXT)arg;
215b063a422SScott Long 	ldm_on_timer((PVBUS)vbus_ext->vbus);
216b063a422SScott Long }
217b063a422SScott Long 
os_request_timer(void * osext,HPT_U32 interval)218b063a422SScott Long void  os_request_timer(void * osext, HPT_U32 interval)
219b063a422SScott Long {
220b063a422SScott Long 	PVBUS_EXT vbus_ext = osext;
221b063a422SScott Long 
222b063a422SScott Long 	HPT_ASSERT(vbus_ext->ext_type==EXT_TYPE_VBUS);
223b063a422SScott Long 
22485c9dd9dSSteven Hartland 	callout_reset_sbt(&vbus_ext->timer, SBT_1US * interval, 0,
22585c9dd9dSSteven Hartland 	    os_timer_for_ldm, vbus_ext, 0);
226b063a422SScott Long }
227b063a422SScott Long 
os_query_time(void)228b063a422SScott Long HPT_TIME os_query_time(void)
229b063a422SScott Long {
230b063a422SScott Long 	return ticks * (1000000 / hz);
231b063a422SScott Long }
232b063a422SScott Long 
os_schedule_task(void * osext,OSM_TASK * task)233b063a422SScott Long void os_schedule_task(void *osext, OSM_TASK *task)
234b063a422SScott Long {
235b063a422SScott Long 	PVBUS_EXT vbus_ext = osext;
236b063a422SScott Long 
237b063a422SScott Long 	HPT_ASSERT(task->next==0);
238b063a422SScott Long 
239b063a422SScott Long 	if (vbus_ext->tasks==0)
240b063a422SScott Long 		vbus_ext->tasks = task;
241b063a422SScott Long 	else {
242b063a422SScott Long 		OSM_TASK *t = vbus_ext->tasks;
243b063a422SScott Long 		while (t->next) t = t->next;
244b063a422SScott Long 		t->next = task;
245b063a422SScott Long 	}
246b063a422SScott Long 
247b063a422SScott Long 	if (vbus_ext->worker.ta_context)
248b063a422SScott Long 		TASK_ENQUEUE(&vbus_ext->worker);
249b063a422SScott Long }
250b063a422SScott Long 
os_revalidate_device(void * osext,int id)251b063a422SScott Long int os_revalidate_device(void *osext, int id)
252b063a422SScott Long {
253b063a422SScott Long 
254b063a422SScott Long     return 0;
255b063a422SScott Long }
256b063a422SScott Long 
os_query_remove_device(void * osext,int id)257b063a422SScott Long int os_query_remove_device(void *osext, int id)
258b063a422SScott Long {
2597634a04bSXin LI 	return 0;
260b063a422SScott Long }
261b063a422SScott Long 
os_get_vbus_seq(void * osext)262b063a422SScott Long HPT_U8 os_get_vbus_seq(void *osext)
263b063a422SScott Long {
264b063a422SScott Long     return ((PVBUS_EXT)osext)->sim->path_id;
265b063a422SScott Long }
266b063a422SScott Long 
os_printk(char * fmt,...)267b063a422SScott Long int  os_printk(char *fmt, ...)
268b063a422SScott Long {
269b063a422SScott Long     va_list args;
270b063a422SScott Long     static char buf[512];
271b063a422SScott Long 
272b063a422SScott Long     va_start(args, fmt);
273b063a422SScott Long     vsnprintf(buf, sizeof(buf), fmt, args);
274b063a422SScott Long     va_end(args);
275b063a422SScott Long     return printf("%s: %s\n", driver_name, buf);
276b063a422SScott Long }
277b063a422SScott Long 
2789d6a74ebSScott Long #if DBG
os_check_stack(const char * location,int size)279b063a422SScott Long void os_check_stack(const char *location, int size){}
280b063a422SScott Long 
__os_dbgbreak(const char * file,int line)281b063a422SScott Long void __os_dbgbreak(const char *file, int line)
282b063a422SScott Long {
283b063a422SScott Long     printf("*** break at %s:%d ***", file, line);
284b063a422SScott Long     while (1);
285b063a422SScott Long }
286b063a422SScott Long 
287b204a4e7SScott Long int hptrr_dbg_level = 1;
288b063a422SScott Long #endif
289