hptnr_os_bsd.c revision 269613
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 269613 2014-08-05 23:39:35Z jhb $ 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 89252867SdelphijHPT_U32 pcicfg_read_dword(HPT_U8 bus, HPT_U8 dev, HPT_U8 func, HPT_U8 reg) 90252867Sdelphij{ 91252867Sdelphij return (HPT_U32)pci_cfgregread(bus, dev, func, reg, 4);; 92252867Sdelphij}/* PCI space access */ 93252867Sdelphij 94252867Sdelphijvoid *os_map_pci_bar( 95252867Sdelphij void *osext, 96252867Sdelphij int index, 97252867Sdelphij HPT_U32 offset, 98252867Sdelphij HPT_U32 length 99252867Sdelphij) 100252867Sdelphij{ 101252867Sdelphij PHBA hba = (PHBA)osext; 102252867Sdelphij HPT_U32 base; 103252867Sdelphij 104252867Sdelphij hba->pcibar[index].rid = 0x10 + index * 4; 105252867Sdelphij base = pci_read_config(hba->pcidev, hba->pcibar[index].rid, 4); 106252867Sdelphij 107252867Sdelphij if (base & 1) { 108252867Sdelphij hba->pcibar[index].type = SYS_RES_IOPORT; 109252867Sdelphij hba->pcibar[index].res = bus_alloc_resource(hba->pcidev, 110252867Sdelphij hba->pcibar[index].type, &hba->pcibar[index].rid, 0, ~0, length, RF_ACTIVE); 111252867Sdelphij hba->pcibar[index].base = (void *)(unsigned long)(base & ~0x1); 112252867Sdelphij } else { 113252867Sdelphij hba->pcibar[index].type = SYS_RES_MEMORY; 114252867Sdelphij hba->pcibar[index].res = bus_alloc_resource(hba->pcidev, 115252867Sdelphij hba->pcibar[index].type, &hba->pcibar[index].rid, 0, ~0, length, RF_ACTIVE); 116252867Sdelphij hba->pcibar[index].base = (char *)rman_get_virtual(hba->pcibar[index].res) + offset; 117252867Sdelphij } 118252867Sdelphij 119252867Sdelphij return hba->pcibar[index].base; 120252867Sdelphij} 121252867Sdelphij 122252867Sdelphijvoid os_unmap_pci_bar(void *osext, void *base) 123252867Sdelphij{ 124252867Sdelphij PHBA hba = (PHBA)osext; 125252867Sdelphij int index; 126252867Sdelphij 127252867Sdelphij for (index=0; index<6; index++) { 128252867Sdelphij if (hba->pcibar[index].base==base) { 129252867Sdelphij bus_release_resource(hba->pcidev, hba->pcibar[index].type, 130252867Sdelphij hba->pcibar[index].rid, hba->pcibar[index].res); 131252867Sdelphij hba->pcibar[index].base = 0; 132252867Sdelphij return; 133252867Sdelphij } 134252867Sdelphij } 135252867Sdelphij} 136252867Sdelphij 137252867Sdelphijvoid freelist_reserve(struct freelist *list, void *osext, HPT_UINT size, HPT_UINT count) 138252867Sdelphij{ 139252867Sdelphij PVBUS_EXT vbus_ext = osext; 140252867Sdelphij 141252867Sdelphij if (vbus_ext->ext_type!=EXT_TYPE_VBUS) 142252867Sdelphij vbus_ext = ((PHBA)osext)->vbus_ext; 143252867Sdelphij 144252867Sdelphij list->next = vbus_ext->freelist_head; 145252867Sdelphij vbus_ext->freelist_head = list; 146252867Sdelphij list->dma = 0; 147252867Sdelphij list->size = size; 148252867Sdelphij list->head = 0; 149252867Sdelphij#if DBG 150252867Sdelphij list->reserved_count = 151252867Sdelphij#endif 152252867Sdelphij list->count = count; 153252867Sdelphij} 154252867Sdelphij 155252867Sdelphijvoid *freelist_get(struct freelist *list) 156252867Sdelphij{ 157252867Sdelphij void * result; 158252867Sdelphij if (list->count) { 159252867Sdelphij HPT_ASSERT(list->head); 160252867Sdelphij result = list->head; 161252867Sdelphij list->head = *(void **)result; 162252867Sdelphij list->count--; 163252867Sdelphij return result; 164252867Sdelphij } 165252867Sdelphij return 0; 166252867Sdelphij} 167252867Sdelphij 168252867Sdelphijvoid freelist_put(struct freelist * list, void *p) 169252867Sdelphij{ 170252867Sdelphij HPT_ASSERT(list->dma==0); 171252867Sdelphij list->count++; 172252867Sdelphij *(void **)p = list->head; 173252867Sdelphij list->head = p; 174252867Sdelphij} 175252867Sdelphij 176252867Sdelphijvoid freelist_reserve_dma(struct freelist *list, void *osext, HPT_UINT size, HPT_UINT alignment, HPT_UINT count) 177252867Sdelphij{ 178252867Sdelphij PVBUS_EXT vbus_ext = osext; 179252867Sdelphij 180252867Sdelphij if (vbus_ext->ext_type!=EXT_TYPE_VBUS) 181252867Sdelphij vbus_ext = ((PHBA)osext)->vbus_ext; 182252867Sdelphij 183252867Sdelphij list->next = vbus_ext->freelist_dma_head; 184252867Sdelphij vbus_ext->freelist_dma_head = list; 185252867Sdelphij list->dma = 1; 186252867Sdelphij list->alignment = alignment; 187252867Sdelphij list->size = size; 188252867Sdelphij list->head = 0; 189252867Sdelphij#if DBG 190252867Sdelphij list->reserved_count = 191252867Sdelphij#endif 192252867Sdelphij list->count = count; 193252867Sdelphij} 194252867Sdelphij 195252867Sdelphijvoid *freelist_get_dma(struct freelist *list, BUS_ADDRESS *busaddr) 196252867Sdelphij{ 197252867Sdelphij void *result; 198252867Sdelphij HPT_ASSERT(list->dma); 199252867Sdelphij result = freelist_get(list); 200252867Sdelphij if (result) 201252867Sdelphij *busaddr = *(BUS_ADDRESS *)((void **)result+1); 202252867Sdelphij return result; 203252867Sdelphij} 204252867Sdelphij 205252867Sdelphijvoid freelist_put_dma(struct freelist *list, void *p, BUS_ADDRESS busaddr) 206252867Sdelphij{ 207252867Sdelphij HPT_ASSERT(list->dma); 208252867Sdelphij list->count++; 209252867Sdelphij *(void **)p = list->head; 210252867Sdelphij *(BUS_ADDRESS *)((void **)p+1) = busaddr; 211252867Sdelphij list->head = p; 212252867Sdelphij} 213252867Sdelphij 214252867SdelphijHPT_U32 os_get_stamp(void) 215252867Sdelphij{ 216252867Sdelphij HPT_U32 stamp; 217252867Sdelphij do { stamp = random(); } while (stamp==0); 218252867Sdelphij return stamp; 219252867Sdelphij} 220252867Sdelphij 221252867Sdelphijvoid os_stallexec(HPT_U32 microseconds) 222252867Sdelphij{ 223252867Sdelphij DELAY(microseconds); 224252867Sdelphij} 225252867Sdelphij 226252867Sdelphijstatic void os_timer_for_ldm(void *arg) 227252867Sdelphij{ 228252867Sdelphij PVBUS_EXT vbus_ext = (PVBUS_EXT)arg; 229252867Sdelphij ldm_on_timer((PVBUS)vbus_ext->vbus); 230252867Sdelphij} 231252867Sdelphij 232252867Sdelphijvoid os_request_timer(void * osext, HPT_U32 interval) 233252867Sdelphij{ 234252867Sdelphij PVBUS_EXT vbus_ext = osext; 235252867Sdelphij 236252867Sdelphij HPT_ASSERT(vbus_ext->ext_type==EXT_TYPE_VBUS); 237269613Sjhb 238269613Sjhb callout_reset(&vbus_ext->timer, interval * hz / 1000000, 239269613Sjhb os_timer_for_ldm, vbus_ext); 240252867Sdelphij} 241252867Sdelphij 242252867SdelphijHPT_TIME os_query_time(void) 243252867Sdelphij{ 244252867Sdelphij return ticks * (1000000 / hz); 245252867Sdelphij} 246252867Sdelphij 247252867Sdelphijvoid os_schedule_task(void *osext, OSM_TASK *task) 248252867Sdelphij{ 249252867Sdelphij PVBUS_EXT vbus_ext = osext; 250252867Sdelphij 251252867Sdelphij HPT_ASSERT(task->next==0); 252252867Sdelphij 253252867Sdelphij if (vbus_ext->tasks==0) 254252867Sdelphij vbus_ext->tasks = task; 255252867Sdelphij else { 256252867Sdelphij OSM_TASK *t = vbus_ext->tasks; 257252867Sdelphij while (t->next) t = t->next; 258252867Sdelphij t->next = task; 259252867Sdelphij } 260252867Sdelphij 261252867Sdelphij if (vbus_ext->worker.ta_context) 262252867Sdelphij TASK_ENQUEUE(&vbus_ext->worker); 263252867Sdelphij} 264252867Sdelphij 265252867Sdelphijint os_revalidate_device(void *osext, int id) 266252867Sdelphij{ 267252867Sdelphij 268252867Sdelphij return 0; 269252867Sdelphij} 270252867Sdelphij 271252867Sdelphijint os_query_remove_device(void *osext, int id) 272252867Sdelphij{ 273252867Sdelphij PVBUS_EXT vbus_ext = (PVBUS_EXT)osext; 274252867Sdelphij struct cam_periph *periph = NULL; 275252867Sdelphij struct cam_path *path; 276252867Sdelphij int status,retval = 0; 277252867Sdelphij 278252867Sdelphij status = xpt_create_path(&path, NULL, vbus_ext->sim->path_id, id, 0); 279252867Sdelphij if (status == CAM_REQ_CMP) { 280252867Sdelphij if((periph = cam_periph_find(path, "da")) != NULL){ 281252867Sdelphij if(periph->refcount >= 1) 282252867Sdelphij retval = -1; 283252867Sdelphij } 284252867Sdelphij xpt_free_path(path); 285252867Sdelphij } 286252867Sdelphij 287252867Sdelphij return retval; 288252867Sdelphij} 289252867Sdelphij 290252867SdelphijHPT_U8 os_get_vbus_seq(void *osext) 291252867Sdelphij{ 292252867Sdelphij return ((PVBUS_EXT)osext)->sim->path_id; 293252867Sdelphij} 294252867Sdelphij 295252867Sdelphijint os_printk(char *fmt, ...) 296252867Sdelphij{ 297252867Sdelphij va_list args; 298252867Sdelphij static char buf[512]; 299252867Sdelphij 300252867Sdelphij va_start(args, fmt); 301252867Sdelphij vsnprintf(buf, sizeof(buf), fmt, args); 302252867Sdelphij va_end(args); 303252867Sdelphij return printf("%s: %s\n", driver_name, buf); 304252867Sdelphij} 305252867Sdelphij 306252867Sdelphij#if DBG 307252867Sdelphijvoid os_check_stack(const char *location, int size){} 308252867Sdelphij 309252867Sdelphijvoid __os_dbgbreak(const char *file, int line) 310252867Sdelphij{ 311252867Sdelphij printf("*** break at %s:%d ***", file, line); 312252867Sdelphij while (1); 313252867Sdelphij} 314252867Sdelphij 315252867Sdelphijint hpt_dbg_level = 1; 316252867Sdelphij#endif 317