Beispiel #1
0
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;
}
Beispiel #2
0
/*****************************************************************************
**
**  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);
}