1331722Seadler/*
2174604Sscottl * Copyright (c) HighPoint Technologies, Inc.
3174604Sscottl * All rights reserved.
4174604Sscottl *
5174604Sscottl * Redistribution and use in source and binary forms, with or without
6174604Sscottl * modification, are permitted provided that the following conditions
7174604Sscottl * are met:
8174604Sscottl * 1. Redistributions of source code must retain the above copyright
9174604Sscottl *    notice, this list of conditions and the following disclaimer.
10174604Sscottl * 2. Redistributions in binary form must reproduce the above copyright
11174604Sscottl *    notice, this list of conditions and the following disclaimer in the
12174604Sscottl *    documentation and/or other materials provided with the distribution.
13174604Sscottl *
14174604Sscottl * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15174604Sscottl * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16174604Sscottl * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17174604Sscottl * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18174604Sscottl * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19174604Sscottl * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20174604Sscottl * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21174604Sscottl * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22174604Sscottl * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23174604Sscottl * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24174604Sscottl * SUCH DAMAGE.
25174604Sscottl *
26174604Sscottl * $FreeBSD$
27174604Sscottl */
28174604Sscottl#include <dev/hptrr/hptrr_config.h>
29174604Sscottl/* $Id: os_bsd.c,v 1.11 2005/06/03 14:06:38 kdh Exp $
30174604Sscottl *
31174604Sscottl * HighPoint RAID Driver for FreeBSD
32174604Sscottl * Copyright (C) 2005 HighPoint Technologies, Inc. All Rights Reserved.
33174604Sscottl */
34174604Sscottl
35174604Sscottl#include <dev/hptrr/os_bsd.h>
36174604Sscottl
37174604Sscottl/* hardware access */
38174604SscottlHPT_U8   os_inb  (void *port) { return inb((unsigned)(HPT_UPTR)port); }
39174604SscottlHPT_U16  os_inw  (void *port) { return inw((unsigned)(HPT_UPTR)port); }
40174604SscottlHPT_U32  os_inl  (void *port) { return inl((unsigned)(HPT_UPTR)port); }
41174604Sscottl
42174604Sscottlvoid os_outb (void *port, HPT_U8 value) { outb((unsigned)(HPT_UPTR)port, (value)); }
43174604Sscottlvoid os_outw (void *port, HPT_U16 value) { outw((unsigned)(HPT_UPTR)port, (value)); }
44174604Sscottlvoid os_outl (void *port, HPT_U32 value) { outl((unsigned)(HPT_UPTR)port, (value)); }
45174604Sscottl
46174604Sscottlvoid os_insw (void *port, HPT_U16 *buffer, HPT_U32 count)
47174604Sscottl{ insw((unsigned)(HPT_UPTR)port, (void *)buffer, count); }
48174604Sscottl
49174604Sscottlvoid os_outsw(void *port, HPT_U16 *buffer, HPT_U32 count)
50174604Sscottl{ outsw((unsigned)(HPT_UPTR)port, (void *)buffer, count); }
51174604Sscottl
52174604SscottlHPT_U32 __dummy_reg = 0;
53174604Sscottl
54174604Sscottl/* PCI configuration space */
55174604SscottlHPT_U8  os_pci_readb (void *osext, HPT_U8 offset)
56174604Sscottl{
57174604Sscottl    return  pci_read_config(((PHBA)osext)->pcidev, offset, 1);
58174604Sscottl}
59174604Sscottl
60174604SscottlHPT_U16 os_pci_readw (void *osext, HPT_U8 offset)
61174604Sscottl{
62174604Sscottl    return  pci_read_config(((PHBA)osext)->pcidev, offset, 2);
63174604Sscottl}
64174604Sscottl
65174604SscottlHPT_U32 os_pci_readl (void *osext, HPT_U8 offset)
66174604Sscottl{
67174604Sscottl    return  pci_read_config(((PHBA)osext)->pcidev, offset, 4);
68174604Sscottl}
69174604Sscottl
70174604Sscottlvoid os_pci_writeb (void *osext, HPT_U8 offset, HPT_U8 value)
71174604Sscottl{
72174604Sscottl    pci_write_config(((PHBA)osext)->pcidev, offset, value, 1);
73174604Sscottl}
74174604Sscottl
75174604Sscottlvoid os_pci_writew (void *osext, HPT_U8 offset, HPT_U16 value)
76174604Sscottl{
77174604Sscottl    pci_write_config(((PHBA)osext)->pcidev, offset, value, 2);
78174604Sscottl}
79174604Sscottl
80174604Sscottlvoid os_pci_writel (void *osext, HPT_U8 offset, HPT_U32 value)
81174604Sscottl{
82174604Sscottl    pci_write_config(((PHBA)osext)->pcidev, offset, value, 4);
83174604Sscottl}
84174604Sscottl
85174604Sscottlvoid *os_map_pci_bar(
86174604Sscottl    void *osext,
87174604Sscottl    int index,
88174604Sscottl    HPT_U32 offset,
89174604Sscottl    HPT_U32 length
90174604Sscottl)
91174604Sscottl{
92174604Sscottl	PHBA hba = (PHBA)osext;
93174604Sscottl
94174604Sscottl    hba->pcibar[index].rid = 0x10 + index * 4;
95174604Sscottl
96174604Sscottl    if (pci_read_config(hba->pcidev, hba->pcibar[index].rid, 4) & 1)
97174604Sscottl    	hba->pcibar[index].type = SYS_RES_IOPORT;
98174604Sscottl    else
99174604Sscottl    	hba->pcibar[index].type = SYS_RES_MEMORY;
100174604Sscottl
101296135Sjhibbits    hba->pcibar[index].res = bus_alloc_resource_any(hba->pcidev,
102296135Sjhibbits		hba->pcibar[index].type, &hba->pcibar[index].rid, RF_ACTIVE);
103174604Sscottl
104174604Sscottl	hba->pcibar[index].base = (char *)rman_get_virtual(hba->pcibar[index].res) + offset;
105174604Sscottl	return hba->pcibar[index].base;
106174604Sscottl}
107174604Sscottl
108174604Sscottlvoid os_unmap_pci_bar(void *osext, void *base)
109174604Sscottl{
110174604Sscottl	PHBA hba = (PHBA)osext;
111174604Sscottl	int index;
112174604Sscottl
113174604Sscottl	for (index=0; index<6; index++) {
114174604Sscottl		if (hba->pcibar[index].base==base) {
115174604Sscottl			bus_release_resource(hba->pcidev, hba->pcibar[index].type,
116174604Sscottl				hba->pcibar[index].rid, hba->pcibar[index].res);
117174604Sscottl			hba->pcibar[index].base = 0;
118174604Sscottl			return;
119174604Sscottl		}
120174604Sscottl	}
121174604Sscottl}
122174604Sscottl
123174604Sscottlvoid freelist_reserve(struct freelist *list, void *osext, HPT_UINT size, HPT_UINT count)
124174604Sscottl{
125174604Sscottl    PVBUS_EXT vbus_ext = osext;
126174604Sscottl
127174604Sscottl    if (vbus_ext->ext_type!=EXT_TYPE_VBUS)
128174604Sscottl        vbus_ext = ((PHBA)osext)->vbus_ext;
129174604Sscottl
130174604Sscottl    list->next = vbus_ext->freelist_head;
131174604Sscottl    vbus_ext->freelist_head = list;
132174604Sscottl    list->dma = 0;
133174604Sscottl    list->size = size;
134174604Sscottl    list->head = 0;
135176939Sscottl#if DBG
136174604Sscottl    list->reserved_count =
137174604Sscottl#endif
138174604Sscottl    list->count = count;
139174604Sscottl}
140174604Sscottl
141174604Sscottlvoid *freelist_get(struct freelist *list)
142174604Sscottl{
143174604Sscottl    void * result;
144174604Sscottl    if (list->count) {
145174604Sscottl        HPT_ASSERT(list->head);
146174604Sscottl        result = list->head;
147174604Sscottl        list->head = *(void **)result;
148174604Sscottl        list->count--;
149174604Sscottl        return result;
150174604Sscottl    }
151174604Sscottl    return 0;
152174604Sscottl}
153174604Sscottl
154174604Sscottlvoid freelist_put(struct freelist * list, void *p)
155174604Sscottl{
156174604Sscottl    HPT_ASSERT(list->dma==0);
157174604Sscottl    list->count++;
158174604Sscottl    *(void **)p = list->head;
159174604Sscottl    list->head = p;
160174604Sscottl}
161174604Sscottl
162174604Sscottlvoid freelist_reserve_dma(struct freelist *list, void *osext, HPT_UINT size, HPT_UINT alignment, HPT_UINT count)
163174604Sscottl{
164174604Sscottl    PVBUS_EXT vbus_ext = osext;
165174604Sscottl
166174604Sscottl    if (vbus_ext->ext_type!=EXT_TYPE_VBUS)
167174604Sscottl        vbus_ext = ((PHBA)osext)->vbus_ext;
168174604Sscottl
169174604Sscottl    list->next = vbus_ext->freelist_dma_head;
170174604Sscottl    vbus_ext->freelist_dma_head = list;
171174604Sscottl    list->dma = 1;
172174604Sscottl    list->alignment = alignment;
173174604Sscottl    list->size = size;
174174604Sscottl    list->head = 0;
175176939Sscottl#if DBG
176174604Sscottl    list->reserved_count =
177174604Sscottl#endif
178174604Sscottl    list->count = count;
179174604Sscottl}
180174604Sscottl
181174604Sscottlvoid *freelist_get_dma(struct freelist *list, BUS_ADDRESS *busaddr)
182174604Sscottl{
183174604Sscottl    void *result;
184174604Sscottl    HPT_ASSERT(list->dma);
185174604Sscottl    result = freelist_get(list);
186174604Sscottl    if (result)
187174604Sscottl        *busaddr = *(BUS_ADDRESS *)((void **)result+1);
188174604Sscottl    return result;
189174604Sscottl}
190174604Sscottl
191174604Sscottlvoid freelist_put_dma(struct freelist *list, void *p, BUS_ADDRESS busaddr)
192174604Sscottl{
193174604Sscottl    HPT_ASSERT(list->dma);
194174604Sscottl    list->count++;
195174604Sscottl    *(void **)p = list->head;
196174604Sscottl    *(BUS_ADDRESS *)((void **)p+1) = busaddr;
197174604Sscottl    list->head = p;
198174604Sscottl}
199174604Sscottl
200174604SscottlHPT_U32 os_get_stamp(void)
201174604Sscottl{
202174604Sscottl    HPT_U32 stamp;
203174604Sscottl    do { stamp = random(); } while (stamp==0);
204174604Sscottl    return stamp;
205174604Sscottl}
206174604Sscottl
207174604Sscottlvoid os_stallexec(HPT_U32 microseconds)
208174604Sscottl{
209174604Sscottl    DELAY(microseconds);
210174604Sscottl}
211174604Sscottl
212174604Sscottlstatic void os_timer_for_ldm(void *arg)
213174604Sscottl{
214174604Sscottl	PVBUS_EXT vbus_ext = (PVBUS_EXT)arg;
215174604Sscottl	ldm_on_timer((PVBUS)vbus_ext->vbus);
216174604Sscottl}
217174604Sscottl
218174604Sscottlvoid  os_request_timer(void * osext, HPT_U32 interval)
219174604Sscottl{
220174604Sscottl	PVBUS_EXT vbus_ext = osext;
221174604Sscottl
222174604Sscottl	HPT_ASSERT(vbus_ext->ext_type==EXT_TYPE_VBUS);
223269615Sjhb
224274819Ssmh	callout_reset_sbt(&vbus_ext->timer, SBT_1US * interval, 0,
225274819Ssmh	    os_timer_for_ldm, vbus_ext, 0);
226174604Sscottl}
227174604Sscottl
228174604SscottlHPT_TIME os_query_time(void)
229174604Sscottl{
230174604Sscottl	return ticks * (1000000 / hz);
231174604Sscottl}
232174604Sscottl
233174604Sscottlvoid os_schedule_task(void *osext, OSM_TASK *task)
234174604Sscottl{
235174604Sscottl	PVBUS_EXT vbus_ext = osext;
236174604Sscottl
237174604Sscottl	HPT_ASSERT(task->next==0);
238174604Sscottl
239174604Sscottl	if (vbus_ext->tasks==0)
240174604Sscottl		vbus_ext->tasks = task;
241174604Sscottl	else {
242174604Sscottl		OSM_TASK *t = vbus_ext->tasks;
243174604Sscottl		while (t->next) t = t->next;
244174604Sscottl		t->next = task;
245174604Sscottl	}
246174604Sscottl
247174604Sscottl	if (vbus_ext->worker.ta_context)
248174604Sscottl		TASK_ENQUEUE(&vbus_ext->worker);
249174604Sscottl}
250174604Sscottl
251174604Sscottlint os_revalidate_device(void *osext, int id)
252174604Sscottl{
253174604Sscottl
254174604Sscottl    return 0;
255174604Sscottl}
256174604Sscottl
257174604Sscottlint os_query_remove_device(void *osext, int id)
258174604Sscottl{
259267368Sdelphij	return 0;
260174604Sscottl}
261174604Sscottl
262174604SscottlHPT_U8 os_get_vbus_seq(void *osext)
263174604Sscottl{
264174604Sscottl    return ((PVBUS_EXT)osext)->sim->path_id;
265174604Sscottl}
266174604Sscottl
267174604Sscottlint  os_printk(char *fmt, ...)
268174604Sscottl{
269174604Sscottl    va_list args;
270174604Sscottl    static char buf[512];
271174604Sscottl
272174604Sscottl    va_start(args, fmt);
273174604Sscottl    vsnprintf(buf, sizeof(buf), fmt, args);
274174604Sscottl    va_end(args);
275174604Sscottl    return printf("%s: %s\n", driver_name, buf);
276174604Sscottl}
277174604Sscottl
278176939Sscottl#if DBG
279174604Sscottlvoid os_check_stack(const char *location, int size){}
280174604Sscottl
281174604Sscottlvoid __os_dbgbreak(const char *file, int line)
282174604Sscottl{
283174604Sscottl    printf("*** break at %s:%d ***", file, line);
284174604Sscottl    while (1);
285174604Sscottl}
286174604Sscottl
287176031Sscottlint hptrr_dbg_level = 1;
288174604Sscottl#endif
289