int fb_init() { bt_error_t status; /* Bit 3 library error return type */ char devname[BT_MAX_DEV_NAME]; /* Device to open */ bt_devdata_t flag; /* Open the device in A24 space */ bt_gen_name(0, BT_DEV_A24, devname, BT_MAX_DEV_NAME); status = bt_open(&btd, devname, BT_RDWR); if (status != BT_SUCCESS) { cm_msg(MERROR, "fb_init", "Cannot open Bit3 device driver"); return FALSE; } bt_init(btd); bt_clrerr(btd); /* map SFI memory */ status = bt_mmap(btd, &_sfi, SFI_ADDRESS, SFI_SIZE, BT_RDWR, BT_SWAP_DEFAULT); if (status != BT_SUCCESS) { cm_msg(MERROR, "fb_init", "Cannot map VME memory"); bt_close(btd); return FALSE; } /* Open the device in local memory */ bt_gen_name(0, BT_DEV_LM, devname, BT_MAX_DEV_NAME); status = bt_open(&btd_lm, devname, BT_RDWR); if (status != BT_SUCCESS) { cm_msg(MERROR, "fb_init", "Cannot open Bit3 device for local memory"); return FALSE; } bt_clrerr(btd_lm); /* map local memory */ status = bt_mmap(btd_lm, &remote_ram_buffer, 0, REMOTE_RAM_SIZE, BT_RDWR, BT_SWAP_DEFAULT); if (status != BT_SUCCESS) { cm_msg(MERROR, "fb_init", "Cannot map local memory"); bt_close(btd); return FALSE; } /* clear local memory */ memset(remote_ram_buffer, 0, REMOTE_RAM_SIZE); /* force D32 mode */ bt_get_info(btd, BT_INFO_MMAP_AMOD, &flag); flag = BT_AMOD_A24_SD; bt_set_info(btd, BT_INFO_MMAP_AMOD, flag); /* sequencer reset */ SFI_OUT(SFI_SEQUENCER_RESET, 0); /* arbitration level */ // SFI_OUT(SFI_FASTBUS_ARBITRATION_LEVEL_REGISTER, 0x15); SFI_OUT(SFI_FASTBUS_ARBITRATION_LEVEL_REGISTER, 0xBF); /* timeout */ SFI_OUT(SFI_FASTBUS_TIMEOUT_REGISTER, 0x73); /* sequencer enable */ SFI_OUT(SFI_SEQUENCER_ENABLE, 0); /* switch off all output */ SFI_OUT(SFI_CLEAR_BOTH_LCA1_TEST_REGISTER, 0); /* clear registers */ SFI_OUT(SFI_RESET_REGISTER_GROUP_LCA2, 0); return SUCCESS; }
/***************************************************************************** ** ** Function: bt_icbr_thread() ** ** Purpose: This thread waits for an interrupt, then call all the ** the registered ICBRs. ** ** Args: param_p Descriptor to call through ** ** Modifies: ** ** Returns: ** void ** ** Note: ** *****************************************************************************/ static void *bt_icbr_thread( void *param_p) { bt_error_t api_ret; bt_desc_t btd = param_p; bt_thread_wait_t thread_wait_data; bt_thread_reg_t thread_reg_data; bt_data8_t *irq_mmap_p; bt_irq_q_t *error_irq_p; bt_irq_q_t *prog_irq_p; bt_irq_q_t *vme_irq_p; bt_data64_t error_tail, prog_tail, vme_tail; bt_devdata_t q_size; char devname[BT_MAX_DEV_NAME]; char *devname_p = &(devname[0]); #if defined (BT951) void *map_addr = NULL; #endif /* ** Grab the descriptor mutex */ pthread_mutex_lock(&btd->mutex); /* ** Register with the driver */ api_ret = bt_ctrl(btd, BIOC_THREAD_REG, &thread_reg_data); btd->thread_id = thread_reg_data.thread_id; if (api_ret != BT_SUCCESS) { DBG_STR("Thread registration failed"); pthread_cond_signal(&btd->icbr_started); pthread_mutex_unlock(&btd->mutex); pthread_exit(NULL); } /* ** Get the interrupt queue length */ (void) bt_get_info(btd, BT_INFO_ICBR_Q_SIZE, &q_size); /* ** Open the diagnostic device for mmapping the irq queues */ devname_p = bt_gen_name(thread_reg_data.unit, BT_DEV_DIAG, devname_p, BT_MAX_DEV_NAME); btd->fd_diag = open((char *) devname_p, O_RDONLY, 0); if (btd->fd_diag == -1) { DBG_STR("Open of diag device failed"); (void) bt_ctrl(btd, BIOC_THREAD_UNREG, &thread_reg_data); pthread_cond_signal(&btd->icbr_started); pthread_mutex_unlock(&btd->mutex); pthread_exit(NULL); } /* ** Memory map the interrupt queues */ irq_mmap_p = (bt_data8_t *) mmap(NULL, BTK_Q_NUM * BTK_Q_SIZE(q_size), PROT_READ, MAP_SHARED, btd->fd_diag, BT_DIAG_ISR_Q_OFFSET); /* Handle the error condition */ #if defined (BT951) if (irq_mmap_p == MAP_FAILED) #else if (irq_mmap_p == NULL) #endif { DBG_STR("Irq queue mmap failed"); (void) close(btd->fd_diag); (void) bt_ctrl(btd, BIOC_THREAD_UNREG, &thread_reg_data); pthread_cond_signal(&btd->icbr_started); pthread_mutex_unlock(&btd->mutex); pthread_exit(NULL); } #if defined (BT951) else { /* We have an address the driver wants us to use, but first it needs to * be mapped into this virtual user space. */ /* * Open the memory device */ btd->dev_mem_fd = open("/dev/mem", O_RDWR); if (btd->dev_mem_fd < 0) { DBG_MSG ((stderr, "Unable to open /dev/mem device. fd = %d errno = %d\n", btd->dev_mem_fd, errno)); /* Failure: cleanup the thread and close the device. */ (void) close(btd->fd_diag); (void) bt_ctrl(btd, BIOC_THREAD_UNREG, &thread_reg_data); pthread_cond_signal(&btd->icbr_started); pthread_mutex_unlock(&btd->mutex); pthread_exit(NULL); } /* Map the resource */ map_addr = (bt_data32_t*)mmap(0, BTK_Q_NUM * BTK_Q_SIZE(q_size), (PROT_READ | PROT_WRITE | PROT_UNCACHE), (MAP_SHARED), btd->dev_mem_fd, (off_t)irq_mmap_p); if (map_addr == MAP_FAILED) { DBG_MSG ((stderr, "Unable to map fd (%d) with the address (%08Xh), errno = %d\n", btd->dev_mem_fd, (unsigned int)irq_mmap_p, errno)); /* Unmap the address and close the device*/ close(btd->dev_mem_fd); (void) close(btd->fd_diag); (void) bt_ctrl(btd, BIOC_THREAD_UNREG, &thread_reg_data); pthread_cond_signal(&btd->icbr_started); pthread_mutex_unlock(&btd->mutex); pthread_exit(NULL); } #if 0 map_addr = (bt_data8_t *) map_addr + (map_off % size_of_page); *mmap_p = (void *) map_addr; #endif /* Save the address from the driver and the kernel virtual address */ /* We will use the driver address to free the resources I think */ btd->driver_phys_addr = (unsigned int)irq_mmap_p; btd->map_virt_addr = (unsigned int)map_addr; } btd->icbr_mmap_p = map_addr; #else /* defined BT951 */ btd->icbr_mmap_p = irq_mmap_p; #endif /* defined BT951 */ btd->icbr_running = TRUE; btd->icbr_mmap_len = BTK_Q_NUM * BTK_Q_SIZE(q_size); /* ** Register a cleanup function to release mmap, unregister with ** driver, and clear running flag */ pthread_cleanup_push(bt_thread_cancel, (void *) btd); /* ** Setup the interrupt queue pointers and set the tails equal to ** the heads */ BTK_Q_ASSIGN(btd->icbr_mmap_p, error_irq_p, prog_irq_p, vme_irq_p, q_size); error_tail = error_irq_p->head; prog_tail = prog_irq_p->head; vme_tail = vme_irq_p->head; /* ** Signal bt_icbr_install() to continue, must do this after we have ** sampled the queue heads, otherwise main program may start and begin ** receiving interrupts before we have a valid head pointer, thus ** missing the first couple of interrupts */ pthread_cond_signal(&btd->icbr_started); pthread_mutex_unlock(&btd->mutex); /* ** Wait for some interrupts to occur */ thread_wait_data.thread_id = btd->thread_id; thread_wait_data.wait_msec = BT_FOREVER; while (1) { api_ret = bt_ctrl(btd, BIOC_THREAD_WAIT, &thread_wait_data); pthread_testcancel(); if (api_ret != BT_SUCCESS) { DBG_STR("Thread wait ioctl failed"); pthread_exit(NULL); } /* ** Parse the error, programmed & vme irq queues */ if (btd->icbr_head_p != NULL) { bt_irq_parse(btd, error_irq_p, &error_tail, BT_IRQ_ERROR); bt_irq_parse(btd, prog_irq_p, &prog_tail, BT_IRQ_PRG); bt_irq_parse(btd, vme_irq_p, &vme_tail, BT_IRQ_IACK); } else { error_tail = error_irq_p->head; prog_tail = prog_irq_p->head; vme_tail = vme_irq_p->head; } } /* ** Don't know how we would get here, but call the ** cleanup routine ** ** Note the pop() routine must exist otherwise it will not compile */ pthread_cleanup_pop(1); }
static int bt_osl_proc_read_info ( char *page, char **start, off_t off, int count, int *eof, void *context) { BT_CONTEXT *battery = NULL; BT_BATTERY_INFO *battery_info = NULL; char *p = page; int len = 0; if (!context || (off != 0)) { goto end; } battery = (BT_CONTEXT*)context; /* * Battery Present? * ---------------- */ if (!battery->is_present) { p += sprintf(p, "Present: no\n"); goto end; } else { p += sprintf(p, "Present: yes\n"); } /* * Get Battery Information: * ------------------------ */ if (ACPI_FAILURE(bt_get_info(battery, &battery_info))) { p += sprintf(p, "Error reading battery information (_BIF)\n"); goto end; } if (battery_info->design_capacity == BT_UNKNOWN) { p += sprintf(p, "Design Capacity: unknown\n"); } else { p += sprintf(p, "Design Capacity: %d %sh\n", (u32)battery_info->design_capacity, battery->power_units); } if (battery_info->last_full_capacity == BT_UNKNOWN) { p += sprintf(p, "Last Full Capacity: unknown\n"); } else { p += sprintf(p, "Last Full Capacity: %d %sh\n", (u32)battery_info->last_full_capacity, battery->power_units); } if (battery_info->battery_technology == 0) { p += sprintf(p, "Battery Technology: primary (non-rechargeable)\n"); } else if (battery_info->battery_technology == 1) { p += sprintf(p, "Battery Technology: secondary (rechargeable)\n"); } else { p += sprintf(p, "Battery Technology: unknown\n"); } if (battery_info->design_voltage == BT_UNKNOWN) { p += sprintf(p, "Design Voltage: unknown\n"); } else { p += sprintf(p, "Design Voltage: %d mV\n", (u32)battery_info->design_voltage); } p += sprintf(p, "Design Capacity Warning: %d %sh\n", (u32)battery_info->design_capacity_warning, battery->power_units); p += sprintf(p, "Design Capacity Low: %d %sh\n", (u32)battery_info->design_capacity_low, battery->power_units); p += sprintf(p, "Capacity Granularity 1: %d %sh\n", (u32)battery_info->battery_capacity_granularity_1, battery->power_units); p += sprintf(p, "Capacity Granularity 2: %d %sh\n", (u32)battery_info->battery_capacity_granularity_2, battery->power_units); p += sprintf(p, "Model Number: %s\n", battery_info->model_number); p += sprintf(p, "Serial Number: %s\n", battery_info->serial_number); p += sprintf(p, "Battery Type: %s\n", battery_info->battery_type); p += sprintf(p, "OEM Info: %s\n", battery_info->oem_info); end: len = (p - page); if (len <= off+count) *eof = 1; *start = page + off; len -= off; if (len>count) len = count; if (len<0) len = 0; acpi_os_free(battery_info); return(len); }