bool QGString::resize( uint newlen )
{
  m_len = 0;
  if (newlen==0)
  {
    if (m_data) { free(m_data); m_data=0; }
    m_memSize=0;
    DBG_STR(("%p: 1.QGString::resize() %d:%s\n",this,m_len,m_data?m_data:"<none>"));
    return TRUE;
  }
  m_memSize = ROUND_SIZE(newlen+1);
  assert(m_memSize>=newlen+1);
  if (m_data==0)
  {
    m_data = (char *)malloc(m_memSize);
  }
  else
  {
    m_data = (char *)realloc(m_data,m_memSize);
  }
  if (m_data==0) 
  {
    DBG_STR(("%p: 2.QGString::resize() %d:%s\n",this,m_len,m_data?m_data:"<none>"));
    return FALSE;
  }
  m_data[newlen-1]='\0';
  m_len = qstrlen(m_data);
  DBG_STR(("%p: 3.QGString::resize() %d:%s\n",this,m_len,m_data?m_data:"<none>"));
  return TRUE;
}
Exemple #2
0
bt_error_t bt_get_devno_map(
    bt_desc_t       btd,
    bt_ioctl_vc_map_t            *map_data)
{
    bt_error_t      retval = BT_SUCCESS;
    bt_ioctl_vc_map_t    diag;

    /*
    ** Check for bad descriptor or invalid pointer value
    */
    if (BT_DESC_BAD(btd)) {
        DBG_STR("bt_get_devno_map:bad descriptor.");
        retval = BT_EDESC;
        goto bt_get_devno_map_end;
    }

    if (!(map_data)) {
        DBG_STR("bt_get_devno_map:bad struct pointer.");
        retval = BT_EINVAL;
        goto bt_get_devno_map_end;
    }

    strcpy(diag.targetName, "");
    diag.lun = 0;
    diag.opened = 0;

    diag.mapindex = map_data->mapindex;
    if (diag.mapindex == 0) {
        DBG_STR("bt_get_devno_map:bad map index.");
        retval = BT_EINVAL;
        goto bt_get_devno_map_end;
    }

    /*
    ** Setup ioctl structure
    */
    diag.error = (bt_data32_t) BT_SUCCESS;

    /*
    ** Retrieve the driver version number
    */
    if ((retval = bt_ctrl(btd, BIOC_FCTACH_GET_VC_MAP, &diag)) != BT_SUCCESS) {
        DBG_STR("bt_get_unit_map:BIOC_FCTACH_GET_VC_MAP failed.");
        if (diag.error != BT_SUCCESS) {
            retval = diag.error;
        }
        goto bt_get_devno_map_end;
    }

    /*
    ** Return the info
    */
    sprintf(map_data->targetName, (const char *) diag.targetName);
    map_data->lun = diag.lun;
    map_data->opened = diag.opened;

bt_get_devno_map_end:
    return (retval);
}
Exemple #3
0
bt_error_t bt_lcard_diag(
    bt_desc_t       btd,
    char            *rev_info_p,
    int             *line_p)
{
    bt_error_t      retval = BT_SUCCESS;
    bt_hw_diag_t    diag;
   
    /*
    ** Check for bad descriptor or invalid pointer value
    */
    if (BT_DESC_BAD(btd)) {
        DBG_STR("bt_lcard_diag:bad descriptor.");
        retval = BT_EDESC;
        goto bt_lcard_diag_end;
    }

    /*
    ** Verify parameters
    */

    /*
    ** Setup ioctl structure
    */
    diag.error = (bt_data32_t) BT_SUCCESS;

    /*
    ** Do the actual diagnostics
    */
    if ((retval = bt_ctrl(btd, BIOC_LCARD_DIAG, &diag)) != BT_SUCCESS) {
        DBG_STR("bt_lcard_diag:BIOC_LCARD_DIAG failed.");
        if (diag.error != BT_SUCCESS) {
            retval = diag.error;
        }
        goto bt_lcard_diag_end;
    }

bt_lcard_diag_end:
    /*
    ** Report the line number and rev info if requested
    */
    if (rev_info_p != NULL) {
        strncpy(rev_info_p, (const char *) &diag.rev_info[0], BT_DIAG_MAX_REV_INFO);
    }

    if (line_p != NULL) {
        *line_p = diag.line_number;
    }
    
    return (retval);
}
Exemple #4
0
bt_error_t bt_get_adapter_map(
    bt_desc_t       btd,
    bt_ioctl_get_cardwwns_t            *card_info)
{
    bt_error_t      retval = BT_SUCCESS;
    bt_ioctl_get_cardwwns_t    diag;
    int             i;

    /*
    ** Check for bad descriptor or invalid pointer value
    */
    if (BT_DESC_BAD(btd)) {
        DBG_STR("bt_get_adapter_map:bad descriptor.");
        retval = BT_EDESC;
        goto bt_get_adapter_map_end;
    }

    for (i = 0; i < BT_MAX_CARDS; i++) {
        strcpy(diag.adapterName[i], "");
    }

    /*
    ** Setup ioctl structure
    */
    diag.error = (bt_data32_t) BT_SUCCESS;

    /*
    ** Retrieve the driver version number
    */
    if ((retval = bt_ctrl(btd, BIOC_FCTACH_GET_CARDWWNS, &diag)) != BT_SUCCESS) {
        DBG_STR("bt_get_adapter_map:BIOC_FCTACH_GET_CARDWWNS failed.");
        if (diag.error != BT_SUCCESS) {
            retval = diag.error;
        }
        goto bt_get_adapter_map_end;
    }

bt_get_adapter_map_end:
    /*
    ** Return the info if requested
    */
    if (card_info != NULL) {
        for (i = 0; i < BT_MAX_CARDS; i++) {
            sprintf(card_info->adapterName[i], (const char *) diag.adapterName[i]);
        }
    }

    return (retval);
}
Exemple #5
0
bt_error_t bt_phys_mem_test(
    bt_desc_t       btd,
    char            *vaddr,
    int             size,
    int             *line_p)
{
    bt_error_t      retval = BT_SUCCESS;
    bt_hw_diag_t    diag;

    /*
    ** Check for bad descriptor or invalid pointer value
    */
    if (BT_DESC_BAD(btd)) {
        DBG_STR("bt_phys_mem_test:bad descriptor.");
        retval = BT_EDESC;
        goto bt_phys_mem_test;
    }

    /*
    ** Setup ioctl structure
    */
    diag.error = (bt_data32_t) BT_SUCCESS;

    diag.r_addr = (bt_data32_t)vaddr;
    diag.r_len = size;

    /*
    ** Send the allocated memory to the driver for testing
    */
    if ((retval = bt_ctrl(btd, BIOC_PHYS_MEM_TEST, &diag)) != BT_SUCCESS) {
        DBG_STR("bt_phys_mem_test: BIOC_LYNXOS_MEM_TEST failed.");
        if (diag.error != BT_SUCCESS) {
            retval = diag.error;
        }
        goto bt_phys_mem_test;
    }


bt_phys_mem_test:

    if (line_p != NULL) {
        *line_p = diag.line_number;
    }


    return (retval);
}
Exemple #6
0
bt_error_t bt_trace_init(
    bt_desc_t       btd,
    FILE           *stream1,
    FILE           *stream2)
{
    bt_error_t      retval = BT_SUCCESS;
    bt_trace_init_t trace_data;
   
    /*
    ** Check for bad descriptor or invalid pointer value
    */
    if (BT_DESC_BAD(btd)) {
        DBG_STR("bt_pair_diag:bad descriptor.");
        retval = BT_EDESC;
        goto bt_trace_init_end;
    }

    /*
    ** Setup ioctl structure
    */
    trace_data.error = (bt_data32_t) BT_SUCCESS;
    trace_data.stream1 = (FILE *) stream1;
    trace_data.stream2 = (FILE *) stream2;

    /*
    ** Do the actual ioctl call
    */
    if ((retval = bt_ctrl(btd, BIOC_TRACE_INIT, &trace_data)) != BT_SUCCESS) {
        DBG_STR("bt_pair_diag:BIOC_TRACE_INIT failed.");
        if (trace_data.error != BT_SUCCESS) {
            retval = trace_data.error;
        }
        goto bt_trace_init_end;
    }

bt_trace_init_end:
    
    return (retval);
}
QGString &QGString::operator+=( char c )
{
  uint len = m_len;
  uint memSize = ROUND_SIZE(len+2);
  assert(memSize>=len+2);
  char *newData = memSize!=m_memSize ? (char *)realloc( m_data, memSize ) : m_data;
  m_memSize = memSize;
  if (newData)
  {
    m_data = newData;
    m_data[len] = c;
    m_data[len+1] = '\0';
  }
  m_len++;
  DBG_STR(("%p: QGString::operator+=(char s) %d:%s\n",this,m_len,m_data?m_data:"<none>"));
  return *this;
}
QGString::QGString( const QGString &s ) 
{ 
  if (s.m_memSize==0)
  {
    m_data    = 0;
    m_len     = 0;
    m_memSize = 0;
  }
  else
  {
    m_data    = (char *)malloc(s.m_memSize); 
    m_len     = s.m_len;
    m_memSize = s.m_memSize;
    qstrcpy(m_data,s.m_data);
  }
  DBG_STR(("%p: QGString::QGString(const QGString &) %d:%s\n",this,m_len,m_data?m_data:"<none>"));
} 
QGString &QGString::operator+=( const char *str )
{
  if (!str) return *this;
  uint len1 = length();
  uint len2 = qstrlen(str);
  uint memSize = ROUND_SIZE(len1 + len2 + 1);
  assert(memSize>=len1+len2+1);
  char *newData = memSize!=m_memSize ? (char *)realloc( m_data, memSize ) : m_data;
  m_memSize = memSize;
  if (newData)
  {
    m_data = newData;
    memcpy( m_data + len1, str, len2 + 1 );
  }
  m_len+=len2;
  DBG_STR(("%p: QGString::operator+=(const char *) %d:%s\n",this,m_len,m_data?m_data:"<none>"));
  return *this;
}
QGString::QGString( const char *str )
{
  if (str==0)
  {
    m_data=0;
    m_len=0;
    m_memSize=0;
  }
  else
  {
    m_len = qstrlen(str);
    m_memSize = ROUND_SIZE(m_len+1);
    assert(m_memSize>=m_len+1);
    m_data = (char *)malloc(m_memSize);
    qstrcpy(m_data,str);
  }
  DBG_STR(("%p: QGString::QGString(const char *) %d:%s\n",this,m_len,m_data?m_data:"<none>"));
}
QGString::QGString(uint size)
{
  if (size==0)
  {
    m_data=0;
    m_len=0;
  }
  else
  {
    m_memSize = ROUND_SIZE(size+1);
    m_data = (char*)malloc(m_memSize);
    memset(m_data,' ',size);
    m_data[size]='\0';
    m_len=size;
  }
  DBG_STR(("%p: QGString::QGString(uint size=%d) %d:%s\n",
      this,size,m_len,m_data?m_data:"<none>"));
}
QGString &QGString::operator=( const char *str ) 
{ 
  if (m_data) free(m_data);
  if (str==0) // null string
  {
    m_data    = 0;
    m_len     = 0;
    m_memSize = 0;
  }
  else
  {
    m_len     = qstrlen(str);
    m_memSize = ROUND_SIZE(m_len+1);
    assert(m_memSize>=m_len+1);
    m_data    = (char*)malloc(m_memSize);
    qstrcpy(m_data,str);
  }
  DBG_STR(("%p: QGString::operator=(const char *) %d:%s\n",this,m_len,m_data?m_data:"<none>"));
  return *this;
}
QGString &QGString::operator=( const QGString &s ) 
{
  if (m_data) free(m_data);
  if (s.m_memSize==0) // null string
  {
    m_data    = 0;
    m_len     = 0;
    m_memSize = 0;
  }
  else
  {
    m_len     = s.m_len;
    m_memSize = s.m_memSize;
    m_data    = (char*)malloc(m_memSize);
    qstrcpy(m_data,s.m_data);
  }
  DBG_STR(("%p: QGString::operator=(const QGString &%p) %d:%s\n",
      this,&s,m_len,m_data?m_data:"<none>"));
  return *this;
}
Exemple #14
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);
}
Exemple #15
0
/*****************************************************************************
**
**  Function:   bt_icbr_remove()
**
**  Purpose:    Remove an ICBR from the list
**
**  Args:
**    btd       Descriptor to call through
**    irq       Type of interrupt to register for
**    func_p    Address of interrupt call back routine to remove
**                      
**  Modifies:
**
**  Returns:    BT_EINVAL if error, otherwise BT_SUCCESS
**
**  Note:
**    Removes all the ICBR register with this type and fucntion from the 
**    driver's descriptor data.
**
**    Eventhough we may remove all of the ICBRs from the list we
**    allow the ICBR thread to continue to execute until the 
**    bt_close() comes.
**
*****************************************************************************/
bt_error_t bt_icbr_remove(
    bt_desc_t    btd,     /* Unit information */
    bt_irq_t     irq,     /* Interrupt type to register for */
    bt_icbr_t    *func_p  /* Address of ICBR to call */
    )
{
    bt_error_t      retvalue = BT_EFAIL;
    bt_icbr_list_t  *curr_icbr_p = NULL;
    bt_icbr_list_t  *prev_icbr_p = NULL;
    bt_thread_add_t thread_sub_data;

    if (BT_DESC_BAD(btd)) {
        DBG_STR("Bad descriptor");
        retvalue = BT_EDESC;
        goto bt_icbr_rem_end;
    }

    /* 
    ** Check range on interrupt type and validate function pointer 
    */
    if ((0 > irq) || 
        (BT_MAX_IRQ < irq)) {
        DBG_STR("Invalid interrupt type");
        retvalue = BT_EINVAL;
        goto bt_icbr_rem_end;
    }
    if (NULL == func_p) {
        DBG_STR("Null ICBR function");
        retvalue = BT_EINVAL;
        goto bt_icbr_rem_end;
    }

    /* 
    ** Search list for given ICBR
    */
    pthread_mutex_lock(&btd->mutex);
    prev_icbr_p = (bt_icbr_list_t *) &btd->icbr_head_p;
    curr_icbr_p = btd->icbr_head_p;
    while (curr_icbr_p != NULL) {
 
        /* 
        ** Check if we found the one we were looking for 
        */
        if ((irq  == curr_icbr_p->type) &&
            (func_p == curr_icbr_p->func_p) ) {

            /* 
            ** Unlink ICBR entry free it and move on in the list
            */
            if (prev_icbr_p == NULL) {
                btd->icbr_head_p = curr_icbr_p->next_p;
                free(curr_icbr_p);
                curr_icbr_p = btd->icbr_head_p;
            } else {
                prev_icbr_p->next_p = curr_icbr_p->next_p;
                free(curr_icbr_p);
                curr_icbr_p = prev_icbr_p->next_p;
            }
            retvalue = BT_SUCCESS;

            /*
            ** If we found the ICBR in the list, tell the driver to 
            ** delete one instance of this irq type
            */
            thread_sub_data.irq_type = irq;
            thread_sub_data.vector = BT_VECTOR_ALL;
            thread_sub_data.thread_id = btd->thread_id;
            if (bt_ctrl(btd, BIOC_THREAD_DELETE, &thread_sub_data) != BT_SUCCESS) {
                /*
                ** Ignore failures, since the routine was removed
                ** from the ICBR list it will not be called and worst
                ** that will happen is that the ICBR thread will still
                ** be called for this irq type.
                */
                DBG_STR("Delete thread ioctl failed");
            }    
            continue;
        }

        /*
        ** Move to the next item on the list
        ** Note we do not stop until we have found all matching
        ** items since we are not matching vectors there may be
        ** multiple entries to remove
        */
        prev_icbr_p = curr_icbr_p;
        curr_icbr_p = prev_icbr_p->next_p;
    }
    pthread_mutex_unlock(&btd->mutex);

    /*
    ** We return BT_SUCCESS as long as we delete at least on ICBR
    */
bt_icbr_rem_end:
    return retvalue;
}
Exemple #16
0
/******************************************************************************
**
** Function: bt_icbr_install()
**       
** Purpose: Install an ICBR (interrupt call-back routine) that will be called
**          when a particular interrupt type occurs.
**
** Args:    bt_desc_t btd: Descriptor returned by the original call to
**          bt_open().
**
**          bt_irq_t irq_type: Type of interrupt this ICBR handles.
**
**          bt_icbr_t *icbr_p: Address of the ICBR (see comments for ICBR
**          prototype).
**
**          void *param_p: A user defined object that is passed unmodified
**          to the ICBR as a parameter.  This is usually a pointer to a data
**          structure.
**
**          bt_data32_t vector: Vector for selective registration (see
**          comments for more information).
**
** Returns: bt_error_t:
**          BT_SUCCESS   Added ICBR to list
**          BT_ENOMEM    Couldn't allocate memory for list element
**
**
** Comments: The prototype for the application's ICBR is:
**           void app_icbr(void *param_p, bt_irq_t irq_type, bt_data32_t vector);
**
**              The ICBR's param_p parameter is same value passed to
**              bt_icbr_install() in it's param_p parameter.
**
**              The ICBR's irq_type parameter is the interrupt type that
**              actually occurred.  If the ICBR thread's interrupt data
**              queue has overflowed, this will be BT_IRQ_OVERFLOW.  Otherwise,
**              it will be the same type as passed to bt_icbr_install() in it's
**              irq_type parameter.
**
**              The value in the ICBR's vector parameter depends on the
**              irq_type parameter, as follows:
**
**              BT_IRQ_ERROR: Vector will be either a value returned
**              by one of the user installed ISR or BT_ESTATUS.
**
**              BT_IRQ_PROG: Vector will either be zero or the 
**              value returned by one of the user installed ISR.
**
**              BT_IRQ_VME: Vector will zero of the value returned
**              by one of the user installed ISR.
**
**
**          ICBRs execute within their own unique threads within an
**          application.  These are referred to as ICBR threads.
**
**          The interrupt call back will be called if:
**          There is an overflow. 
**
**          The type matchs and the registered vector is BT_VECTOR_ALL
**
**          The type matchs and the registered vector matches the actual
**          vector received.
**
******************************************************************************/
bt_error_t bt_icbr_install(
    bt_desc_t   btd,     /* Unit information */
    bt_irq_t    irq,     /* Interrupt type to register for */
    bt_icbr_t  *func_p,  /* Address of ICBR to call */
    void       *param_p, /* Parameter to pass when calling ICBR */
    bt_data32_t vector   /* Vector to match against */
    )
{
    bt_error_t          retvalue = BT_SUCCESS;
    int                 os_ret = 0;
    bt_icbr_list_t      *new_icbr_p = NULL;
    bt_thread_add_t     thread_add_data;                     


    if (BT_DESC_BAD(btd)) {
        DBG_STR("Bad descriptor");
        retvalue = BT_EDESC;
        goto bt_icbr_ins_end;
    }

    /* 
    ** Check range on interrupt type and validate function pointer 
    */
    if ((0 > irq) || 
        (BT_MAX_IRQ < irq)) {
        DBG_STR("Invalid interrupt type");
        retvalue = BT_EINVAL;
        goto bt_icbr_ins_end;
    }
    if (NULL == func_p) {
        DBG_STR("Null ICBR function");
        retvalue = BT_EINVAL;
        goto bt_icbr_ins_end;
    }
    
    /*
    ** Create the new ICBR list item
    */
    new_icbr_p = (bt_icbr_list_t *) malloc(sizeof(bt_icbr_list_t));
    if (NULL == new_icbr_p) {
        retvalue = BT_ENOMEM;
        goto bt_icbr_ins_end;    
    }
    new_icbr_p->type = irq;
    new_icbr_p->vector = vector;
    new_icbr_p->func_p = func_p;
    new_icbr_p->param_p = param_p;

    /* 
    ** Check if the ICBR thread already exists 
    */
    pthread_mutex_lock(&btd->mutex);
    if (btd->icbr_running == FALSE) {

        /*
        ** Init the thread condition variable and start the thread
        */
        os_ret = pthread_cond_init(&btd->icbr_started, NULL);
        assert(0 == os_ret);
        os_ret = pthread_create(&btd->icbr_thread, NULL, bt_icbr_thread, (void *) btd); 
        if (os_ret < 0) {
            pthread_cond_destroy(&btd->icbr_started);
            DBG_STR("Failed creating ICBR thread");
            switch (os_ret) {
              case EAGAIN: /* system limit */
                  retvalue = BT_EBUSY;
                  break;
              case EINVAL:  /* sp was null and len was less than 8192 */
              case ENOMEM:  /* can't allocate stack */
                  retvalue = os_ret;
                  break;
              default:
                 retvalue = BT_EFAIL;
                 break;
            }
            goto bt_icbr_ins_unlock;
        }

        /*
        ** Wait for the ICBR thread to start
        ** Note btd->mutex is reaquired on return from this function
        */
        os_ret = pthread_cond_wait(&btd->icbr_started, &btd->mutex);
        if (os_ret < 0) {
            pthread_cancel(btd->icbr_thread);
            pthread_cond_destroy(&btd->icbr_started);
            btd->icbr_running = FALSE;
            DBG_STR("Failed waiting for ICBR thread to start");
            retvalue = BT_EFAIL;
            goto bt_icbr_ins_unlock;
        }
        
    }

    /*
    ** Check that the ICBR thread is running
    */
    if (!btd->icbr_running) {
        /* 
        ** ICBR list needs to be cleaned up, let bt_close do it 
        */
        DBG_STR("ICBR thread encountered error");
        retvalue = BT_EFAIL;
        goto bt_icbr_ins_unlock;
    }

    /*
    ** Add this interrupt type to the driver so the ICBR
    ** thread gets called on this type of interrupt
    */
    thread_add_data.irq_type = irq;
    thread_add_data.vector = vector;
    thread_add_data.thread_id = btd->thread_id;
    retvalue = bt_ctrl(btd, BIOC_THREAD_ADD, &thread_add_data);
    if (os_ret != BT_SUCCESS) {
        /*
        ** On failure we allow the ICBR thread to continue to run
        ** because it may be processing other ICBRs
        */
        DBG_STR("Add thread ioctl failed");
        goto bt_icbr_ins_unlock;  
    }

    /*
    ** Now add ICBR to list 
    */
    new_icbr_p->next_p = btd->icbr_head_p;
    btd->icbr_head_p = new_icbr_p;
    
bt_icbr_ins_unlock:
    pthread_mutex_unlock(&btd->mutex);
    if (retvalue != BT_SUCCESS) {
        free(new_icbr_p);
    }

bt_icbr_ins_end:
    return retvalue;
}
Exemple #17
0
bt_error_t bt_pair_diag(
    bt_desc_t       btd,
    bt_dev_t        rldev,
    bt_devaddr_t    raddr,
    bt_data32_t     rlen,
    char            *rev_info_p,
    int             *line_p)
{
    bt_error_t      retval = BT_SUCCESS;
    bt_hw_diag_t    diag;
   
    /*
    ** Check for bad descriptor or invalid pointer value
    */
    if (BT_DESC_BAD(btd)) {
        DBG_STR("bt_pair_diag:bad descriptor.");
        retval = BT_EDESC;
        goto bt_pair_diag_end;
    }

    /*
    ** Verify parameters
    */
    if ((rldev != BT_DEV_A32) &&
        (rldev != BT_DEV_A32) &&
        (rldev != BT_DEV_A16)) {
        DBG_STR("bt_pair_diag: invalid remote logical device type.");
        retval = BT_EINVAL;
        goto bt_pair_diag_end;
    }
    if (rlen == 0) {
        DBG_STR("bt_pair_diag: zero remote length.");
        retval = BT_EINVAL;
        goto bt_pair_diag_end;
    }

    /*
    ** Setup ioctl structure
    */
    diag.error = (bt_data32_t) BT_SUCCESS;
    diag.r_ldev = rldev;
    diag.r_addr = raddr;
    diag.r_len = rlen;

    /*
    ** Do the actual diagnostics
    */
    if ((retval = bt_ctrl(btd, BIOC_PAIR_DIAG, &diag)) != BT_SUCCESS) {
        DBG_STR("bt_pair_diag:BIOC_PAIR_DIAG failed.");
        if (diag.error != BT_SUCCESS) {
            retval = diag.error;
        }
        goto bt_pair_diag_end;
    }

bt_pair_diag_end:
    /*
    ** Report the line number and rev info if requested
    */
    if (rev_info_p != NULL) {
        strncpy(rev_info_p, (const char *) &diag.rev_info[0], BT_DIAG_MAX_REV_INFO);
    }
    if (line_p != NULL) {
        *line_p = diag.line_number;
    }
    
    return (retval);
}
QGString::~QGString() 
{ 
  free(m_data); 
  m_data=0; 
  DBG_STR(("%p: QGString::~QGString() %d:%s\n",this,m_len,m_data?m_data:"<none>"));
}
Exemple #19
0
bt_error_t bt_driver_version(
    bt_desc_t       btd,
    char            *ver_info_p,
    int             *line_p)
{
    bt_error_t      retval = BT_SUCCESS;
    bt_hw_diag_t    diag;
    char            model_version[BT_DIAG_MAX_REV_INFO];
    int             i;
   
    /*
    ** Check for bad descriptor or invalid pointer value
    */
    if (BT_DESC_BAD(btd)) {
        DBG_STR("bt_driver_version:bad descriptor.");
        retval = BT_EDESC;
        goto bt_driver_version_end;
    }

    for (i = 0; i < BT_DIAG_MAX_REV_INFO; i++) {
        model_version[i] = '\0';
    }

    /*
    ** Verify parameters
    */
#if defined (__vxworks)
    ver_info_p[BT_DIAG_MAX_REV_INFO] = 0; 
#endif /* defined (__vxworks) */

    /*
    ** Setup ioctl structure
    */
    diag.error = (bt_data32_t) BT_SUCCESS;

    /*
    ** Retrieve the driver version number
    */
    if ((retval = bt_ctrl(btd, BIOC_DRIVER_VERSION, &diag)) != BT_SUCCESS) {
        DBG_STR("bt_lcard_diag:BIOC_DRIVER_VERSION failed.");
        if (diag.error != BT_SUCCESS) {
            retval = diag.error;
        }
        goto bt_driver_version_end;
    }

bt_driver_version_end:
    /*
    ** Report the line number and rev info if requested
    */
    if (ver_info_p != NULL) {
#ifdef FCTACH_LINUX
        sprintf(model_version, (const char *) &diag.rev_info[0]);
#else
        sscanf((const char *) &diag.rev_info[0], "$Name: %s ", model_version);
#endif

#if defined (__vxworks)
        sprintf(ver_info_p, "%s", model_version);
#else
        snprintf(ver_info_p, BT_DIAG_MAX_REV_INFO, "%s", model_version);
#endif /* defined (__vxworks) */

    }

    if (line_p != NULL) {
        *line_p = diag.line_number;
    }

    return (retval);
}
QGString::QGString() // make null string
  : m_data(0), m_len(0), m_memSize(0) 
{
  DBG_STR(("%p: QGString::QGString() %d:%s\n",this,m_len,m_data?m_data:"<none>"));
} 
Exemple #21
0
bt_error_t bt_open(
    bt_desc_t   *btd_p,         /* Pointer to Bit 3 descriptor */
    const char  *devname_p,     /* Device name, as created by bt_gen_name() */
    bt_accessflag_t     flags   /* Flags for read, write, etc */
    )
{
    bt_error_t  retvalue = BT_SUCCESS;
    bt_desc_t   btd = NULL;     /* Unit descriptor */
    int         rdwr_flags;
    int         os_ret;         /* errno return values from operating system */
    static pthread_once_t       bt_once_control = PTHREAD_ONCE_INIT;

    /*
    ** Make sure device name is a valid pointer
    */
    if ((NULL == devname_p)) {
        DBG_STR("Invalid device name");
        retvalue = BT_EFAIL;
        goto bt_open_end;
    }

    /* 
    ** Set up threading support 
    */
    os_ret = pthread_once(&bt_once_control, lib_init);
    if ((0 != os_ret) || (0 != init_failed)) {
        DBG_MSG((stderr, "%s failed %d.\n", 
                os_ret ? "pthread_once" : "pthread_atfork", os_ret));
        switch (os_ret) {
          case BT_ENOMEM:
          case BT_EINVAL:
            retvalue = os_ret;  /* Used same numbers as POSIX */
            break;

          default:
            retvalue = BT_EFAIL;
            break;
        }
        goto bt_open_end;
    }

    /* 
    ** Convert from our flags to normal open()/close() flags 
    */
    if ((0 == flags) || 
        ((flags & BT_RD) && (flags & BT_WR))) {
        rdwr_flags = O_RDWR;
    } else if (flags & BT_RD) {
        rdwr_flags = O_RDONLY;
    } else if (flags & BT_WR) {
        rdwr_flags = O_WRONLY;
    } else {
        DBG_STR("Invalid read/write flags.");
        retvalue = BT_EINVAL;
        goto bt_open_end;
    }

    /*
    ** Allocate an SBS descriptor
    */
    btd = malloc(sizeof(bt_lib_data_t));
    if (NULL == btd) {
        DBG_STR("Can't allocate memory for descriptor.");
        retvalue = BT_ENOMEM;
        goto bt_open_end;
    }
    memset(btd, 0, sizeof(bt_lib_data_t));
    btd->access_flags = flags;
    btd->icbr_head_p = NULL;
    btd->icbr_running = FALSE;
    DBG_MSG((stderr, "Device to open: %s\n", devname_p));

    /*
    ** Actually open the device
    */
    if (-1 == (btd->fd = open((char *) devname_p, rdwr_flags, 0))) { 
        DBG_MSG((stderr, "Call to open failed, devname_p = %s\n", devname_p));
        switch (errno) {
          case BT_EACCESS:
          case BT_EIO:
          case BT_EINVAL:
            retvalue = errno;   /* Our number is same as POSIX error number */
            break;

          case ENOENT:
          case ENXIO:
            /* retvalue = BT_ENODEV; */
            retvalue = BT_EFAIL;
            break;

          case ENAMETOOLONG:
            retvalue = BT_EINVAL;
            break;

          default:
            /* retvalue = BT_ESYSTEM;  */
            retvalue = BT_ENOSUP;
            break;
        }
        goto bt_open_end;
    }

    /* 
    ** Initialize mutex private to this descriptor 
    */
    os_ret = pthread_mutex_init(&btd->mutex, NULL);
    assert(0 == os_ret);

    /* 
    ** Insert this descriptor in the list of open descriptors 
    */
    pthread_mutex_lock(&bt_lib_mutex_g);
    btd->next_p = bt_lib_data_gp;
    bt_lib_data_gp = btd;
    pthread_mutex_unlock(&bt_lib_mutex_g);

bt_open_end:
    if ((BT_SUCCESS != retvalue) && (NULL != btd)){
        free(btd);
        btd = NULL;
    }
    *btd_p = btd;
    return retvalue;
}
Exemple #22
0
bt_error_t bt_close(
    bt_desc_t   btd             /* Bit 3 descriptor */
    )
{
    bt_error_t          retvalue = BT_SUCCESS;
    bt_icbr_list_t      *curr_p, *next_p;
    bt_thread_wait_t    thread_wake_data;

    if (BT_DESC_BAD(btd)) {
        DBG_STR("Invalid descriptor.");
        retvalue = BT_EDESC;
        goto close_end;
    }

    /* 
    ** Cancel the ICBR thread and wait for it to exit
    ** before destroying the descriptor that it was using
    */
    pthread_mutex_lock(&btd->mutex);
    if (btd->icbr_running == TRUE) {
        pthread_cancel(btd->icbr_thread);
        thread_wake_data.thread_id = btd->thread_id;
        (void) bt_ctrl(btd, BIOC_THREAD_WAKE, &thread_wake_data);
        (void) pthread_cond_wait(&btd->icbr_started, &btd->mutex);
        
    }
    
    /* 
    ** Unregister for any ICBRs currently defined 
    */
    while ((curr_p = btd->icbr_head_p) != NULL) {
        next_p = curr_p->next_p;
        free(curr_p);
        btd->icbr_head_p = next_p;
    }
    pthread_mutex_unlock(&btd->mutex);

    /* 
    ** Remove this descriptor from global list 
    */
    pthread_mutex_lock(&bt_lib_mutex_g);
    {
        bt_lib_data_t   *current_p, *previous_p;

        /* 
        ** Removal of 1st element is handled by next_p always being
        ** first structure field
        */
        previous_p = (bt_lib_data_t *) &bt_lib_data_gp;
        current_p = bt_lib_data_gp;
        while ((NULL != current_p) && (btd != current_p)) {
            previous_p = current_p;
            current_p = current_p->next_p;
        }
        if (NULL != current_p) {
            previous_p->next_p = current_p->next_p;
        } else {
            DBG_MSG((stderr, "Couldn't find descriptor %p in list.\n", btd));
        }
    }
    pthread_mutex_unlock(&bt_lib_mutex_g);

    /*
    ** Destroy the local mutex 
    */
    pthread_cond_destroy(&btd->icbr_started);
    pthread_mutex_destroy(&btd->mutex);

    /*
    ** Must not use any mutexs from this point on! 
    */
    if (-1 == close(btd->fd)){
        switch (errno) {
          case EBADF:
            retvalue = BT_EDESC;
            break;
          default:
            /* retvalue = BT_ESYSTEM;  */
            retvalue = BT_ENOSUP;
            break;
        }
    }
    free(btd);

close_end:
    return retvalue;
}