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; }
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); }
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); }
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); }
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); }
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; }
/***************************************************************************** ** ** 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); }
/***************************************************************************** ** ** 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; }
/****************************************************************************** ** ** 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; }
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>")); }
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>")); }
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; }
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; }