hptnr_os_bsd.c revision 252867
1252867Sdelphij/* $Id: os_bsd.c,v 1.13 2010/05/11 03:12:11 lcn Exp $ */ 2252867Sdelphij/*- 3252867Sdelphij * HighPoint RAID Driver for FreeBSD 4252867Sdelphij * Copyright (C) 2005-2011 HighPoint Technologies, Inc. All Rights Reserved. 5252867Sdelphij * All rights reserved. 6252867Sdelphij * 7252867Sdelphij * Redistribution and use in source and binary forms, with or without 8252867Sdelphij * modification, are permitted provided that the following conditions 9252867Sdelphij * are met: 10252867Sdelphij * 1. Redistributions of source code must retain the above copyright 11252867Sdelphij * notice, this list of conditions and the following disclaimer. 12252867Sdelphij * 2. Redistributions in binary form must reproduce the above copyright 13252867Sdelphij * notice, this list of conditions and the following disclaimer in the 14252867Sdelphij * documentation and/or other materials provided with the distribution. 15252867Sdelphij * 16252867Sdelphij * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17252867Sdelphij * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18252867Sdelphij * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19252867Sdelphij * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20252867Sdelphij * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21252867Sdelphij * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22252867Sdelphij * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23252867Sdelphij * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24252867Sdelphij * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25252867Sdelphij * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26252867Sdelphij * SUCH DAMAGE. 27252867Sdelphij * 28252867Sdelphij * $FreeBSD: head/sys/dev/hptnr/hptnr_os_bsd.c 252867 2013-07-06 07:49:41Z delphij $ 29252867Sdelphij */ 30252867Sdelphij 31252867Sdelphij#include <dev/hptnr/hptnr_config.h> 32252867Sdelphij#include <dev/hptnr/os_bsd.h> 33252867Sdelphij 34252867SdelphijBUS_ADDRESS get_dmapool_phy_addr(void *osext, void * dmapool_virt_addr); 35252867Sdelphij 36252867Sdelphij/* hardware access */ 37252867SdelphijHPT_U8 os_inb (void *port) { return inb((unsigned)(HPT_UPTR)port); } 38252867SdelphijHPT_U16 os_inw (void *port) { return inw((unsigned)(HPT_UPTR)port); } 39252867SdelphijHPT_U32 os_inl (void *port) { return inl((unsigned)(HPT_UPTR)port); } 40252867Sdelphij 41252867Sdelphijvoid os_outb (void *port, HPT_U8 value) { outb((unsigned)(HPT_UPTR)port, (value)); } 42252867Sdelphijvoid os_outw (void *port, HPT_U16 value) { outw((unsigned)(HPT_UPTR)port, (value)); } 43252867Sdelphijvoid os_outl (void *port, HPT_U32 value) { outl((unsigned)(HPT_UPTR)port, (value)); } 44252867Sdelphij 45252867Sdelphijvoid os_insw (void *port, HPT_U16 *buffer, HPT_U32 count) 46252867Sdelphij{ insw((unsigned)(HPT_UPTR)port, (void *)buffer, count); } 47252867Sdelphij 48252867Sdelphijvoid os_outsw(void *port, HPT_U16 *buffer, HPT_U32 count) 49252867Sdelphij{ outsw((unsigned)(HPT_UPTR)port, (void *)buffer, count); } 50252867Sdelphij 51252867SdelphijHPT_U32 __dummy_reg = 0; 52252867Sdelphij 53252867Sdelphij/* PCI configuration space */ 54252867SdelphijHPT_U8 os_pci_readb (void *osext, HPT_U8 offset) 55252867Sdelphij{ 56252867Sdelphij return pci_read_config(((PHBA)osext)->pcidev, offset, 1); 57252867Sdelphij} 58252867Sdelphij 59252867SdelphijHPT_U16 os_pci_readw (void *osext, HPT_U8 offset) 60252867Sdelphij{ 61252867Sdelphij return pci_read_config(((PHBA)osext)->pcidev, offset, 2); 62252867Sdelphij} 63252867Sdelphij 64252867SdelphijHPT_U32 os_pci_readl (void *osext, HPT_U8 offset) 65252867Sdelphij{ 66252867Sdelphij return pci_read_config(((PHBA)osext)->pcidev, offset, 4); 67252867Sdelphij} 68252867Sdelphij 69252867Sdelphijvoid os_pci_writeb (void *osext, HPT_U8 offset, HPT_U8 value) 70252867Sdelphij{ 71252867Sdelphij pci_write_config(((PHBA)osext)->pcidev, offset, value, 1); 72252867Sdelphij} 73252867Sdelphij 74252867Sdelphijvoid os_pci_writew (void *osext, HPT_U8 offset, HPT_U16 value) 75252867Sdelphij{ 76252867Sdelphij pci_write_config(((PHBA)osext)->pcidev, offset, value, 2); 77252867Sdelphij} 78252867Sdelphij 79252867Sdelphijvoid os_pci_writel (void *osext, HPT_U8 offset, HPT_U32 value) 80252867Sdelphij{ 81252867Sdelphij pci_write_config(((PHBA)osext)->pcidev, offset, value, 4); 82252867Sdelphij} 83252867Sdelphij 84252867SdelphijBUS_ADDRESS get_dmapool_phy_addr(void *osext, void * dmapool_virt_addr) 85252867Sdelphij{ 86252867Sdelphij return (BUS_ADDRESS)vtophys(dmapool_virt_addr); 87252867Sdelphij} 88252867Sdelphij 89252867Sdelphij#if __FreeBSD_version < 500043 90252867SdelphijHPT_U32 pcicfg_read_dword(HPT_U8 bus, HPT_U8 dev, HPT_U8 func, HPT_U8 reg) 91252867Sdelphij{ 92252867Sdelphij HPT_U32 v; 93252867Sdelphij pcicfgregs pciref; 94252867Sdelphij 95252867Sdelphij pciref.bus = bus; 96252867Sdelphij pciref.slot = dev; 97252867Sdelphij pciref.func = func; 98252867Sdelphij 99252867Sdelphij v = pci_cfgread(&pciref, reg, 4); 100252867Sdelphij return v; 101252867Sdelphij}/* PCI space access */ 102252867Sdelphij#else 103252867SdelphijHPT_U32 pcicfg_read_dword(HPT_U8 bus, HPT_U8 dev, HPT_U8 func, HPT_U8 reg) 104252867Sdelphij{ 105252867Sdelphij return (HPT_U32)pci_cfgregread(bus, dev, func, reg, 4);; 106252867Sdelphij}/* PCI space access */ 107252867Sdelphij#endif 108252867Sdelphij 109252867Sdelphijvoid *os_map_pci_bar( 110252867Sdelphij void *osext, 111252867Sdelphij int index, 112252867Sdelphij HPT_U32 offset, 113252867Sdelphij HPT_U32 length 114252867Sdelphij) 115252867Sdelphij{ 116252867Sdelphij PHBA hba = (PHBA)osext; 117252867Sdelphij HPT_U32 base; 118252867Sdelphij 119252867Sdelphij hba->pcibar[index].rid = 0x10 + index * 4; 120252867Sdelphij base = pci_read_config(hba->pcidev, hba->pcibar[index].rid, 4); 121252867Sdelphij 122252867Sdelphij if (base & 1) { 123252867Sdelphij hba->pcibar[index].type = SYS_RES_IOPORT; 124252867Sdelphij hba->pcibar[index].res = bus_alloc_resource(hba->pcidev, 125252867Sdelphij hba->pcibar[index].type, &hba->pcibar[index].rid, 0, ~0, length, RF_ACTIVE); 126252867Sdelphij hba->pcibar[index].base = (void *)(unsigned long)(base & ~0x1); 127252867Sdelphij } else { 128252867Sdelphij hba->pcibar[index].type = SYS_RES_MEMORY; 129252867Sdelphij hba->pcibar[index].res = bus_alloc_resource(hba->pcidev, 130252867Sdelphij hba->pcibar[index].type, &hba->pcibar[index].rid, 0, ~0, length, RF_ACTIVE); 131252867Sdelphij hba->pcibar[index].base = (char *)rman_get_virtual(hba->pcibar[index].res) + offset; 132252867Sdelphij } 133252867Sdelphij 134252867Sdelphij return hba->pcibar[index].base; 135252867Sdelphij} 136252867Sdelphij 137252867Sdelphijvoid os_unmap_pci_bar(void *osext, void *base) 138252867Sdelphij{ 139252867Sdelphij PHBA hba = (PHBA)osext; 140252867Sdelphij int index; 141252867Sdelphij 142252867Sdelphij for (index=0; index<6; index++) { 143252867Sdelphij if (hba->pcibar[index].base==base) { 144252867Sdelphij bus_release_resource(hba->pcidev, hba->pcibar[index].type, 145252867Sdelphij hba->pcibar[index].rid, hba->pcibar[index].res); 146252867Sdelphij hba->pcibar[index].base = 0; 147252867Sdelphij return; 148252867Sdelphij } 149252867Sdelphij } 150252867Sdelphij} 151252867Sdelphij 152252867Sdelphijvoid freelist_reserve(struct freelist *list, void *osext, HPT_UINT size, HPT_UINT count) 153252867Sdelphij{ 154252867Sdelphij PVBUS_EXT vbus_ext = osext; 155252867Sdelphij 156252867Sdelphij if (vbus_ext->ext_type!=EXT_TYPE_VBUS) 157252867Sdelphij vbus_ext = ((PHBA)osext)->vbus_ext; 158252867Sdelphij 159252867Sdelphij list->next = vbus_ext->freelist_head; 160252867Sdelphij vbus_ext->freelist_head = list; 161252867Sdelphij list->dma = 0; 162252867Sdelphij list->size = size; 163252867Sdelphij list->head = 0; 164252867Sdelphij#if DBG 165252867Sdelphij list->reserved_count = 166252867Sdelphij#endif 167252867Sdelphij list->count = count; 168252867Sdelphij} 169252867Sdelphij 170252867Sdelphijvoid *freelist_get(struct freelist *list) 171252867Sdelphij{ 172252867Sdelphij void * result; 173252867Sdelphij if (list->count) { 174252867Sdelphij HPT_ASSERT(list->head); 175252867Sdelphij result = list->head; 176252867Sdelphij list->head = *(void **)result; 177252867Sdelphij list->count--; 178252867Sdelphij return result; 179252867Sdelphij } 180252867Sdelphij return 0; 181252867Sdelphij} 182252867Sdelphij 183252867Sdelphijvoid freelist_put(struct freelist * list, void *p) 184252867Sdelphij{ 185252867Sdelphij HPT_ASSERT(list->dma==0); 186252867Sdelphij list->count++; 187252867Sdelphij *(void **)p = list->head; 188252867Sdelphij list->head = p; 189252867Sdelphij} 190252867Sdelphij 191252867Sdelphijvoid freelist_reserve_dma(struct freelist *list, void *osext, HPT_UINT size, HPT_UINT alignment, HPT_UINT count) 192252867Sdelphij{ 193252867Sdelphij PVBUS_EXT vbus_ext = osext; 194252867Sdelphij 195252867Sdelphij if (vbus_ext->ext_type!=EXT_TYPE_VBUS) 196252867Sdelphij vbus_ext = ((PHBA)osext)->vbus_ext; 197252867Sdelphij 198252867Sdelphij list->next = vbus_ext->freelist_dma_head; 199252867Sdelphij vbus_ext->freelist_dma_head = list; 200252867Sdelphij list->dma = 1; 201252867Sdelphij list->alignment = alignment; 202252867Sdelphij list->size = size; 203252867Sdelphij list->head = 0; 204252867Sdelphij#if DBG 205252867Sdelphij list->reserved_count = 206252867Sdelphij#endif 207252867Sdelphij list->count = count; 208252867Sdelphij} 209252867Sdelphij 210252867Sdelphijvoid *freelist_get_dma(struct freelist *list, BUS_ADDRESS *busaddr) 211252867Sdelphij{ 212252867Sdelphij void *result; 213252867Sdelphij HPT_ASSERT(list->dma); 214252867Sdelphij result = freelist_get(list); 215252867Sdelphij if (result) 216252867Sdelphij *busaddr = *(BUS_ADDRESS *)((void **)result+1); 217252867Sdelphij return result; 218252867Sdelphij} 219252867Sdelphij 220252867Sdelphijvoid freelist_put_dma(struct freelist *list, void *p, BUS_ADDRESS busaddr) 221252867Sdelphij{ 222252867Sdelphij HPT_ASSERT(list->dma); 223252867Sdelphij list->count++; 224252867Sdelphij *(void **)p = list->head; 225252867Sdelphij *(BUS_ADDRESS *)((void **)p+1) = busaddr; 226252867Sdelphij list->head = p; 227252867Sdelphij} 228252867Sdelphij 229252867SdelphijHPT_U32 os_get_stamp(void) 230252867Sdelphij{ 231252867Sdelphij HPT_U32 stamp; 232252867Sdelphij do { stamp = random(); } while (stamp==0); 233252867Sdelphij return stamp; 234252867Sdelphij} 235252867Sdelphij 236252867Sdelphijvoid os_stallexec(HPT_U32 microseconds) 237252867Sdelphij{ 238252867Sdelphij DELAY(microseconds); 239252867Sdelphij} 240252867Sdelphij 241252867Sdelphijstatic void os_timer_for_ldm(void *arg) 242252867Sdelphij{ 243252867Sdelphij PVBUS_EXT vbus_ext = (PVBUS_EXT)arg; 244252867Sdelphij ldm_on_timer((PVBUS)vbus_ext->vbus); 245252867Sdelphij} 246252867Sdelphij 247252867Sdelphijvoid os_request_timer(void * osext, HPT_U32 interval) 248252867Sdelphij{ 249252867Sdelphij PVBUS_EXT vbus_ext = osext; 250252867Sdelphij 251252867Sdelphij HPT_ASSERT(vbus_ext->ext_type==EXT_TYPE_VBUS); 252252867Sdelphij 253252867Sdelphij untimeout(os_timer_for_ldm, vbus_ext, vbus_ext->timer); 254252867Sdelphij vbus_ext->timer = timeout(os_timer_for_ldm, vbus_ext, interval * hz / 1000000); 255252867Sdelphij} 256252867Sdelphij 257252867SdelphijHPT_TIME os_query_time(void) 258252867Sdelphij{ 259252867Sdelphij return ticks * (1000000 / hz); 260252867Sdelphij} 261252867Sdelphij 262252867Sdelphijvoid os_schedule_task(void *osext, OSM_TASK *task) 263252867Sdelphij{ 264252867Sdelphij PVBUS_EXT vbus_ext = osext; 265252867Sdelphij 266252867Sdelphij HPT_ASSERT(task->next==0); 267252867Sdelphij 268252867Sdelphij if (vbus_ext->tasks==0) 269252867Sdelphij vbus_ext->tasks = task; 270252867Sdelphij else { 271252867Sdelphij OSM_TASK *t = vbus_ext->tasks; 272252867Sdelphij while (t->next) t = t->next; 273252867Sdelphij t->next = task; 274252867Sdelphij } 275252867Sdelphij 276252867Sdelphij if (vbus_ext->worker.ta_context) 277252867Sdelphij TASK_ENQUEUE(&vbus_ext->worker); 278252867Sdelphij} 279252867Sdelphij 280252867Sdelphijint os_revalidate_device(void *osext, int id) 281252867Sdelphij{ 282252867Sdelphij 283252867Sdelphij return 0; 284252867Sdelphij} 285252867Sdelphij 286252867Sdelphijint os_query_remove_device(void *osext, int id) 287252867Sdelphij{ 288252867Sdelphij PVBUS_EXT vbus_ext = (PVBUS_EXT)osext; 289252867Sdelphij struct cam_periph *periph = NULL; 290252867Sdelphij struct cam_path *path; 291252867Sdelphij int status,retval = 0; 292252867Sdelphij 293252867Sdelphij status = xpt_create_path(&path, NULL, vbus_ext->sim->path_id, id, 0); 294252867Sdelphij if (status == CAM_REQ_CMP) { 295252867Sdelphij if((periph = cam_periph_find(path, "da")) != NULL){ 296252867Sdelphij if(periph->refcount >= 1) 297252867Sdelphij retval = -1; 298252867Sdelphij } 299252867Sdelphij xpt_free_path(path); 300252867Sdelphij } 301252867Sdelphij 302252867Sdelphij return retval; 303252867Sdelphij} 304252867Sdelphij 305252867SdelphijHPT_U8 os_get_vbus_seq(void *osext) 306252867Sdelphij{ 307252867Sdelphij return ((PVBUS_EXT)osext)->sim->path_id; 308252867Sdelphij} 309252867Sdelphij 310252867Sdelphijint os_printk(char *fmt, ...) 311252867Sdelphij{ 312252867Sdelphij va_list args; 313252867Sdelphij static char buf[512]; 314252867Sdelphij 315252867Sdelphij va_start(args, fmt); 316252867Sdelphij vsnprintf(buf, sizeof(buf), fmt, args); 317252867Sdelphij va_end(args); 318252867Sdelphij return printf("%s: %s\n", driver_name, buf); 319252867Sdelphij} 320252867Sdelphij 321252867Sdelphij#if DBG 322252867Sdelphijvoid os_check_stack(const char *location, int size){} 323252867Sdelphij 324252867Sdelphijvoid __os_dbgbreak(const char *file, int line) 325252867Sdelphij{ 326252867Sdelphij printf("*** break at %s:%d ***", file, line); 327252867Sdelphij while (1); 328252867Sdelphij} 329252867Sdelphij 330252867Sdelphijint hpt_dbg_level = 1; 331252867Sdelphij#endif 332