hptrr_os_bsd.c revision 176031
190075Sobrien/* 2132718Skan * Copyright (c) HighPoint Technologies, Inc. 390075Sobrien * All rights reserved. 490075Sobrien * 590075Sobrien * Redistribution and use in source and binary forms, with or without 690075Sobrien * modification, are permitted provided that the following conditions 790075Sobrien * are met: 890075Sobrien * 1. Redistributions of source code must retain the above copyright 990075Sobrien * notice, this list of conditions and the following disclaimer. 1090075Sobrien * 2. Redistributions in binary form must reproduce the above copyright 11132718Skan * notice, this list of conditions and the following disclaimer in the 12132718Skan * documentation and/or other materials provided with the distribution. 13132718Skan * 14132718Skan * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15132718Skan * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16132718Skan * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17132718Skan * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18132718Skan * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19132718Skan * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2090075Sobrien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2190075Sobrien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2290075Sobrien * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2390075Sobrien * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2490075Sobrien * SUCH DAMAGE. 2590075Sobrien * 2690075Sobrien * $FreeBSD: head/sys/dev/hptrr/hptrr_os_bsd.c 176031 2008-02-06 05:33:17Z scottl $ 27169689Skan */ 28169689Skan#include <dev/hptrr/hptrr_config.h> 2990075Sobrien/* $Id: os_bsd.c,v 1.11 2005/06/03 14:06:38 kdh Exp $ 3090075Sobrien * 3190075Sobrien * HighPoint RAID Driver for FreeBSD 3290075Sobrien * Copyright (C) 2005 HighPoint Technologies, Inc. All Rights Reserved. 3390075Sobrien */ 34132718Skan 35132718Skan#include <dev/hptrr/os_bsd.h> 36132718Skan 3790075Sobrien/* hardware access */ 3890075SobrienHPT_U8 os_inb (void *port) { return inb((unsigned)(HPT_UPTR)port); } 3990075SobrienHPT_U16 os_inw (void *port) { return inw((unsigned)(HPT_UPTR)port); } 4090075SobrienHPT_U32 os_inl (void *port) { return inl((unsigned)(HPT_UPTR)port); } 4190075Sobrien 4290075Sobrienvoid os_outb (void *port, HPT_U8 value) { outb((unsigned)(HPT_UPTR)port, (value)); } 4390075Sobrienvoid os_outw (void *port, HPT_U16 value) { outw((unsigned)(HPT_UPTR)port, (value)); } 4490075Sobrienvoid os_outl (void *port, HPT_U32 value) { outl((unsigned)(HPT_UPTR)port, (value)); } 4590075Sobrien 4690075Sobrienvoid os_insw (void *port, HPT_U16 *buffer, HPT_U32 count) 4790075Sobrien{ insw((unsigned)(HPT_UPTR)port, (void *)buffer, count); } 4890075Sobrien 4990075Sobrienvoid os_outsw(void *port, HPT_U16 *buffer, HPT_U32 count) 5090075Sobrien{ outsw((unsigned)(HPT_UPTR)port, (void *)buffer, count); } 5190075Sobrien 5290075SobrienHPT_U32 __dummy_reg = 0; 5390075Sobrien 5490075Sobrien/* PCI configuration space */ 5590075SobrienHPT_U8 os_pci_readb (void *osext, HPT_U8 offset) 5690075Sobrien{ 5790075Sobrien return pci_read_config(((PHBA)osext)->pcidev, offset, 1); 5890075Sobrien} 5990075Sobrien 6090075SobrienHPT_U16 os_pci_readw (void *osext, HPT_U8 offset) 6190075Sobrien{ 6290075Sobrien return pci_read_config(((PHBA)osext)->pcidev, offset, 2); 6390075Sobrien} 6490075Sobrien 6590075SobrienHPT_U32 os_pci_readl (void *osext, HPT_U8 offset) 6690075Sobrien{ 67132718Skan return pci_read_config(((PHBA)osext)->pcidev, offset, 4); 68132718Skan} 6990075Sobrien 7090075Sobrienvoid os_pci_writeb (void *osext, HPT_U8 offset, HPT_U8 value) 7190075Sobrien{ 7290075Sobrien pci_write_config(((PHBA)osext)->pcidev, offset, value, 1); 7390075Sobrien} 7490075Sobrien 7590075Sobrienvoid os_pci_writew (void *osext, HPT_U8 offset, HPT_U16 value) 7690075Sobrien{ 7790075Sobrien pci_write_config(((PHBA)osext)->pcidev, offset, value, 2); 7890075Sobrien} 7990075Sobrien 8090075Sobrienvoid os_pci_writel (void *osext, HPT_U8 offset, HPT_U32 value) 8190075Sobrien{ 8290075Sobrien pci_write_config(((PHBA)osext)->pcidev, offset, value, 4); 8390075Sobrien} 8490075Sobrien 8590075Sobrienvoid *os_map_pci_bar( 8690075Sobrien void *osext, 8790075Sobrien int index, 8890075Sobrien HPT_U32 offset, 8990075Sobrien HPT_U32 length 9090075Sobrien) 9190075Sobrien{ 9290075Sobrien PHBA hba = (PHBA)osext; 93132718Skan 94132718Skan hba->pcibar[index].rid = 0x10 + index * 4; 9590075Sobrien 9690075Sobrien if (pci_read_config(hba->pcidev, hba->pcibar[index].rid, 4) & 1) 9790075Sobrien hba->pcibar[index].type = SYS_RES_IOPORT; 9890075Sobrien else 9990075Sobrien hba->pcibar[index].type = SYS_RES_MEMORY; 10090075Sobrien 10190075Sobrien hba->pcibar[index].res = bus_alloc_resource(hba->pcidev, 10290075Sobrien hba->pcibar[index].type, &hba->pcibar[index].rid, 0, ~0, length, RF_ACTIVE); 10390075Sobrien 10490075Sobrien hba->pcibar[index].base = (char *)rman_get_virtual(hba->pcibar[index].res) + offset; 10590075Sobrien return hba->pcibar[index].base; 10690075Sobrien} 10790075Sobrien 10890075Sobrienvoid os_unmap_pci_bar(void *osext, void *base) 10990075Sobrien{ 11090075Sobrien PHBA hba = (PHBA)osext; 11190075Sobrien int index; 11290075Sobrien 11390075Sobrien for (index=0; index<6; index++) { 11490075Sobrien if (hba->pcibar[index].base==base) { 11590075Sobrien bus_release_resource(hba->pcidev, hba->pcibar[index].type, 11690075Sobrien hba->pcibar[index].rid, hba->pcibar[index].res); 11790075Sobrien hba->pcibar[index].base = 0; 11890075Sobrien return; 11990075Sobrien } 12090075Sobrien } 12190075Sobrien} 12290075Sobrien 12390075Sobrienvoid freelist_reserve(struct freelist *list, void *osext, HPT_UINT size, HPT_UINT count) 12490075Sobrien{ 12590075Sobrien PVBUS_EXT vbus_ext = osext; 12690075Sobrien 12790075Sobrien if (vbus_ext->ext_type!=EXT_TYPE_VBUS) 12890075Sobrien vbus_ext = ((PHBA)osext)->vbus_ext; 12990075Sobrien 13090075Sobrien list->next = vbus_ext->freelist_head; 13190075Sobrien vbus_ext->freelist_head = list; 13290075Sobrien list->dma = 0; 13390075Sobrien list->size = size; 13490075Sobrien list->head = 0; 13590075Sobrien#ifdef DBG 13690075Sobrien list->reserved_count = 13790075Sobrien#endif 13890075Sobrien list->count = count; 13990075Sobrien} 14090075Sobrien 14190075Sobrienvoid *freelist_get(struct freelist *list) 14290075Sobrien{ 143132718Skan void * result; 14490075Sobrien if (list->count) { 14590075Sobrien HPT_ASSERT(list->head); 14690075Sobrien result = list->head; 14790075Sobrien list->head = *(void **)result; 14890075Sobrien list->count--; 14990075Sobrien return result; 15090075Sobrien } 15190075Sobrien return 0; 15290075Sobrien} 15390075Sobrien 15490075Sobrienvoid freelist_put(struct freelist * list, void *p) 15590075Sobrien{ 15690075Sobrien HPT_ASSERT(list->dma==0); 15790075Sobrien list->count++; 15890075Sobrien *(void **)p = list->head; 15990075Sobrien list->head = p; 16090075Sobrien} 16190075Sobrien 16290075Sobrienvoid freelist_reserve_dma(struct freelist *list, void *osext, HPT_UINT size, HPT_UINT alignment, HPT_UINT count) 16390075Sobrien{ 16490075Sobrien PVBUS_EXT vbus_ext = osext; 165132718Skan 16690075Sobrien if (vbus_ext->ext_type!=EXT_TYPE_VBUS) 16790075Sobrien vbus_ext = ((PHBA)osext)->vbus_ext; 16890075Sobrien 16990075Sobrien list->next = vbus_ext->freelist_dma_head; 17090075Sobrien vbus_ext->freelist_dma_head = list; 17190075Sobrien list->dma = 1; 172132718Skan list->alignment = alignment; 17390075Sobrien list->size = size; 17490075Sobrien list->head = 0; 17590075Sobrien#ifdef DBG 17690075Sobrien list->reserved_count = 17790075Sobrien#endif 17890075Sobrien list->count = count; 17990075Sobrien} 18090075Sobrien 18190075Sobrienvoid *freelist_get_dma(struct freelist *list, BUS_ADDRESS *busaddr) 18290075Sobrien{ 18390075Sobrien void *result; 18490075Sobrien HPT_ASSERT(list->dma); 18590075Sobrien result = freelist_get(list); 18690075Sobrien if (result) 18790075Sobrien *busaddr = *(BUS_ADDRESS *)((void **)result+1); 18890075Sobrien return result; 18990075Sobrien} 19090075Sobrien 19190075Sobrienvoid freelist_put_dma(struct freelist *list, void *p, BUS_ADDRESS busaddr) 19290075Sobrien{ 19390075Sobrien HPT_ASSERT(list->dma); 19490075Sobrien list->count++; 19590075Sobrien *(void **)p = list->head; 19690075Sobrien *(BUS_ADDRESS *)((void **)p+1) = busaddr; 197132718Skan list->head = p; 198117395Skan} 19990075Sobrien 20090075SobrienHPT_U32 os_get_stamp(void) 20190075Sobrien{ 202117395Skan HPT_U32 stamp; 20390075Sobrien do { stamp = random(); } while (stamp==0); 204117395Skan return stamp; 205132718Skan} 20690075Sobrien 20790075Sobrienvoid os_stallexec(HPT_U32 microseconds) 20890075Sobrien{ 20990075Sobrien DELAY(microseconds); 21090075Sobrien} 21190075Sobrien 212117395Skanstatic void os_timer_for_ldm(void *arg) 21390075Sobrien{ 21490075Sobrien PVBUS_EXT vbus_ext = (PVBUS_EXT)arg; 21590075Sobrien ldm_on_timer((PVBUS)vbus_ext->vbus); 21690075Sobrien} 21790075Sobrien 21890075Sobrienvoid os_request_timer(void * osext, HPT_U32 interval) 21990075Sobrien{ 220117395Skan PVBUS_EXT vbus_ext = osext; 22190075Sobrien 22290075Sobrien HPT_ASSERT(vbus_ext->ext_type==EXT_TYPE_VBUS); 22390075Sobrien 22490075Sobrien untimeout(os_timer_for_ldm, vbus_ext, vbus_ext->timer); 22590075Sobrien vbus_ext->timer = timeout(os_timer_for_ldm, vbus_ext, interval * hz / 1000000); 22690075Sobrien} 22790075Sobrien 228117395SkanHPT_TIME os_query_time(void) 22990075Sobrien{ 23090075Sobrien return ticks * (1000000 / hz); 23190075Sobrien} 23290075Sobrien 23390075Sobrienvoid os_schedule_task(void *osext, OSM_TASK *task) 23490075Sobrien{ 23590075Sobrien PVBUS_EXT vbus_ext = osext; 23690075Sobrien 23790075Sobrien HPT_ASSERT(task->next==0); 23890075Sobrien 23990075Sobrien if (vbus_ext->tasks==0) 24090075Sobrien vbus_ext->tasks = task; 24190075Sobrien else { 24290075Sobrien OSM_TASK *t = vbus_ext->tasks; 24390075Sobrien while (t->next) t = t->next; 24490075Sobrien t->next = task; 24590075Sobrien } 24690075Sobrien 24790075Sobrien if (vbus_ext->worker.ta_context) 24890075Sobrien TASK_ENQUEUE(&vbus_ext->worker); 24990075Sobrien} 25090075Sobrien 25190075Sobrienint os_revalidate_device(void *osext, int id) 25290075Sobrien{ 25390075Sobrien 25490075Sobrien return 0; 25590075Sobrien} 25690075Sobrien 25790075Sobrienint os_query_remove_device(void *osext, int id) 25890075Sobrien{ 25990075Sobrien PVBUS_EXT vbus_ext = (PVBUS_EXT)osext; 26090075Sobrien struct cam_periph *periph = NULL; 26190075Sobrien struct cam_path *path; 26290075Sobrien int status,retval = 0; 26390075Sobrien 26490075Sobrien status = xpt_create_path(&path, NULL, vbus_ext->sim->path_id, id, 0); 265117395Skan if (status == CAM_REQ_CMP) { 26690075Sobrien if((periph = cam_periph_find(path, "da")) != NULL){ 267117395Skan if(periph->refcount >= 1) 26890075Sobrien retval = -1; 26990075Sobrien } 27090075Sobrien xpt_free_path(path); 27190075Sobrien } 27290075Sobrien 27390075Sobrien return retval; 27490075Sobrien} 27590075Sobrien 27690075SobrienHPT_U8 os_get_vbus_seq(void *osext) 27790075Sobrien{ 27890075Sobrien return ((PVBUS_EXT)osext)->sim->path_id; 27990075Sobrien} 28090075Sobrien 28190075Sobrienint os_printk(char *fmt, ...) 28290075Sobrien{ 28390075Sobrien va_list args; 28490075Sobrien static char buf[512]; 28590075Sobrien 28690075Sobrien va_start(args, fmt); 28790075Sobrien vsnprintf(buf, sizeof(buf), fmt, args); 28890075Sobrien va_end(args); 28990075Sobrien return printf("%s: %s\n", driver_name, buf); 290132718Skan} 291132718Skan 292#ifdef DBG 293void os_check_stack(const char *location, int size){} 294 295void __os_dbgbreak(const char *file, int line) 296{ 297 printf("*** break at %s:%d ***", file, line); 298 while (1); 299} 300 301int hptrr_dbg_level = 1; 302#endif 303