⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 driver.c

📁 usb to rs232 converter source code
💻 C
📖 第 1 页 / 共 2 页
字号:
      case TTYCLRDTR:          break;      }    }        bret = true;  }    TRACE_FUNCRET("usb_serial_service returns %d\n", bret);  return bret;}void usb_serial_notify_interrupt(void *cookie, uint32 status,                                 void *data, uint32 actual_len){  TRACE_FUNCALLS("usb_serial_notify_interrupt : %p %lx %p %ld\n",                                     cookie, status, data, actual_len);  if(cookie){    usb_serial_device *usd = ((usb_serial_device_info *)cookie)->device;    usd->actual_len_interrupt = actual_len;     usd->dev_status_interrupt = status;   }}     /* usb_serial_open - handle open() calls */static status_t usb_serial_open (const char *name, uint32 flags, void** cookie){  int i;  status_t status = ENODEV;  TRACE_FUNCALLS("usb_serial_open:%s flags:%d cookie:%08x\n",                                                   name, flags, cookie);    for(i=0;i<DEVICES_COUNT;i++)    TRACE("%08x\n",usb_serial_devices[i]);    *cookie = NULL;  i = strtol(name + BASENAME_LEN, NULL, 10);  if(i >= 0 && i < DEVICES_COUNT){    acquire_sem(usb_serial_lock);    if(usb_serial_devices[i]){      usb_serial_device_info *usdi = malloc(sizeof(usb_serial_device_info));      if(usdi){        struct ddrover *ddr;        memset(usdi, 0, sizeof(usb_serial_device_info));        *cookie = usdi;                TRACE("cookie in open:%08x\n", *cookie);                usdi->device = usb_serial_devices[i];                (*tty_m->ttyinit)(&usb_serial_tty[i], true);                usdi->ttyfile.tty = &usb_serial_tty[i];        usdi->ttyfile.flags = flags;        usb_serial_devices[i]->tty = &usb_serial_tty[i];               (*usdi->device->hw->reset_device)(usdi->device);                      TRACE("Opened:%s %08x\n", usdi->device->hw->descr, usdi->device->dev);                       ddr = (*tty_m->ddrstart)(NULL);        if(ddr){          (*tty_m->ddacquire)(ddr, &usb_serial_dd);          status = (*tty_m->ttyopen)(&usdi->ttyfile, ddr, usb_serial_service);          (*tty_m->ddrdone)(ddr);                    if(status == B_OK){            sem_id sem = spawn_kernel_thread(usb_serial_device_thread,                                          "usb_serial_device_thread", 0xa, usdi);            if(sem != -1)              resume_thread(sem);            else              TRACE_ALWAYS("usb_serial_open: cannot spawn kernel thread!!!\n");                      usdi->device->ctrlout = CLS_LINE_DTR | CLS_LINE_RTS;            (*usdi->device->hw->set_control_line_state)(usdi->device,                                                        usdi->device->ctrlout);                      status = (*usb_m->queue_interrupt)(usdi->device->pipe_control,                                               usdi->device->interrupt_buffer,                                               usdi->device->interrupt_buffer_size,                                                usb_serial_notify_interrupt, usdi);          }        }else          status = B_NO_MEMORY;                  if(status != B_OK)          free(usdi);      }else        status = B_NO_MEMORY;    }    release_sem(usb_serial_lock);  }  TRACE_FUNCRET("usb_serial_open returns:%08x\n", status);  return status;}/* usb_serial_read - handle read() calls */static status_t usb_serial_read (void* cookie, off_t position,                                 void *buf, size_t* num_bytes){  status_t status = B_OK;  struct ddrover *ddr;  TRACE_FUNCALLS("usb_serial_read:%08x position:%Ld buf:%08x len:%d\n",                                               cookie, position, buf, *num_bytes);    ddr = (*tty_m->ddrstart)(NULL);  if(ddr){    if(cookie)      status = (*tty_m->ttyread)(cookie, ddr, buf, num_bytes);    else      (*tty_m->ddacquire)(ddr, &usb_serial_dd);    (*tty_m->ddrdone)(ddr);  }else{    TRACE_ALWAYS("usb_serial_read : ddrstart problem !!!\n");    status = B_NO_MEMORY;   }    TRACE_FUNCRET("usb_serial_read returns:%08x readed:%d\n", status, *num_bytes);  return status;}/* usb_serial_write - handle write() calls */static status_t usb_serial_write (void* cookie, off_t position,                                  const void* buffer, size_t* num_bytes){  status_t status = B_OK;  usb_serial_device_info *usdi = (usb_serial_device_info *)cookie;  usb_serial_device *usd = usdi->device;  size_t to_write = *num_bytes;  TRACE_FUNCALLS("usb_serial_write:%08x position:%Ld buf:%08x len:%d\n",                                         cookie, position, buffer, *num_bytes);  *num_bytes = 0;                /* tell caller nothing was written */  while(to_write > 0){    size_t len = to_write;    (*usd->hw->on_write)(usd, buffer, &len);    usd->actual_len_write = 0;    usd->dev_status_write = 0;    status = (*usb_m->queue_bulk)(usd->pipe_write, usd->write_buffer,                                    len, usb_serial_device_notify_out, cookie);    if(status != B_OK){      TRACE_ALWAYS("usb_serial_write : dev %p status %lx", cookie, status);      break;    }    status = acquire_sem_etc(usd->done_write, 1, B_CAN_INTERRUPT, 0);    if(status != B_OK){      TRACE_ALWAYS("usb_serial_write : acquire_sem_etc() %lx (%s)",                                                    status, strerror(status));      break;    }    ((const char*)buffer) += usd->actual_len_write;    *num_bytes += usd->actual_len_write;    to_write   -= usd->actual_len_write;  }  TRACE_FUNCRET("usb_serial_write returns:%08x written:%d\n", status, *num_bytes);  return status;}/* usb_serial_control - handle ioctl calls */static status_t usb_serial_control (void* cookie, uint32 op, void* arg, size_t len){  status_t status = B_BAD_VALUE;  TRACE_FUNCALLS("usb_serial_control cookie:%08x op:%08x arg:%08x len:%d\n",                                                           cookie, op, arg, len);  if(cookie){    struct ddrover *ddr = (*tty_m->ddrstart)(NULL);    if(ddr){      status = (*tty_m->ttycontrol)(cookie, ddr, op, arg, len);      (*tty_m->ddrdone)(ddr);    }else      status = B_NO_MEMORY;  }else    status = ENODEV;  TRACE_FUNCRET("usb_serial_control returns:%08x\n", status);  return status;}/* usb_serial_close - handle close() calls */static status_t usb_serial_close (void* cookie){  status_t status = ENODEV;  TRACE_FUNCALLS("usb_serial_close:%08x\n", cookie);  if(cookie){    usb_serial_device_info *usdi = (usb_serial_device_info *)cookie;    usb_serial_device *usd = usdi->device;    struct ddrover *ddr;        (*usd->hw->on_close)(usd);    ddr = (*tty_m->ddrstart)(NULL);    if(ddr){      status = (*tty_m->ttyclose)(cookie, ddr);      (*tty_m->ddrdone)(ddr);    }else      status = B_NO_MEMORY;  }  TRACE_FUNCRET("usb_serial_close returns:%08x\n", status);  return status;}/* usb_serial_free - called after the last device is closed, and after   all i/o is complete.*/static status_t usb_serial_free (void* cookie){  status_t status = B_OK;  TRACE_FUNCALLS("usb_serial_free:%08x\n", cookie);  if(cookie){    struct ddrover *ddr = (*tty_m->ddrstart)(NULL);    if(ddr){      status = (*tty_m->ttyfree)(cookie, ddr);      (*tty_m->ddrdone)(ddr);    }else      status = B_NO_MEMORY;    free(cookie);  }  TRACE_FUNCRET("usb_serial_free returns:%08x\n", status);  return status;}/* publish_devices - return a null-terminated array of devices   supported by this driver. */const char** publish_devices(){  int i, j;  TRACE_FUNCALLS("publish_devices\n");  for(i=0; usb_serial_names[i]; i++)    free(usb_serial_names[i]);  acquire_sem(usb_serial_lock);  for(i=0, j=0; i < DEVICES_COUNT; i++){    if(usb_serial_devices[i]){      usb_serial_names[j] = malloc(strlen(basename + 2));      if(usb_serial_names[j]){        sprintf(usb_serial_names[j], basename, i);        j++;      }      else        TRACE_ALWAYS("publish_devices - NO MEMORY\n");    }  }  usb_serial_names[j] = NULL;  release_sem(usb_serial_lock);  return (const char **)&usb_serial_names[0];}/* find_device - return ptr to device hooks structure for a   given device name */device_hooks* find_device(const char* name){  TRACE_FUNCALLS("find_device(%s)\n", name);  return &usb_serial_hooks;}status_t add_device(usb_serial_device *usd, const usb_configuration_info *uci,                                            usb_endpoint_info *comm_epi,                                             usb_endpoint_info *data_out_epi,                                             usb_endpoint_info *data_in_epi){  char name[32];   status_t status = ENODEV;  size_t buf_len;  int i = 0;   TRACE_FUNCALLS("add_device(%08x, %08x, %08x, %08x, %08x)\n",                             usd, uci, comm_epi, data_in_epi, data_out_epi);    acquire_sem(usb_serial_lock);  for(i = 0; i < DEVICES_COUNT; i++){    if(usb_serial_devices[i] != NULL)      continue;    usb_serial_devices[i] = usd;          usd->active = 1;    usd->open = 0;        sprintf(name, "usb_serial:%d:done_read", i );    usd->done_read = create_sem(0, name);        sprintf(name, "usb_serial:%d:done_write", i);    usd->done_write = create_sem(0, name);    usd->tty = NULL;        buf_len = usd->read_buffer_size + usd->write_buffer_size +                                                     usd->interrupt_buffer_size;    usd->buffers_area = create_area("usb_serial:buffers_area",                                    (void *)&usd->read_buffer,                                    B_ANY_KERNEL_ADDRESS,                                    ROUNDUP(buf_len, B_PAGE_SIZE),                                    B_CONTIGUOUS, B_READ_AREA|B_WRITE_AREA);          usd->write_buffer     = usd->read_buffer + usd->read_buffer_size;    usd->interrupt_buffer = usd->write_buffer + usd->write_buffer_size;               (*usb_m->set_configuration)(usd->dev, uci);    usd->pipe_control = (comm_epi) ? comm_epi->handle : 0;    usd->pipe_write = data_out_epi->handle;    usd->pipe_read = data_in_epi->handle;    status = B_OK;     break;  }     release_sem(usb_serial_lock);    TRACE_FUNCRET("add_device returns:%08x\n", status);  return status;}status_t usb_serial_device_added(const usb_device *dev, void **cookie){  int i;  status_t status = B_OK;  const usb_device_descriptor *udd;  usb_serial_device *usd = 0;  TRACE_FUNCALLS("usb_serial_device_added:%08x cookie:%08x\n", dev, cookie);    udd = (*usb_m->get_device_descriptor)(dev);  TRACE_ALWAYS("Probing device: %08x/%08x\n", udd->vendor_id, udd->product_id);  *cookie = 0;  for(i=1; i < sizeof(usb_serial_hw_devices)/sizeof(usb_serial_hw_devices[0]); i++)    if(usb_serial_hw_devices[i].vendor_id == udd->vendor_id      && usb_serial_hw_devices[i].product_id == udd->product_id){      const usb_configuration_info *uci;      uci = (*usb_m->get_nth_configuration)(dev, 0);      if(uci){        usd = malloc(sizeof(usb_serial_device));        if(usd){          usd->dev = dev;          usd->hw = &usb_serial_hw_devices[i];          usd->read_buffer_size =           usd->write_buffer_size =           usd->interrupt_buffer_size = ROUNDUP(DEF_BUFFER_SIZE, 16);          if((status = (*usb_serial_hw_devices[i].add_device)(usd, uci)) == B_OK){            *cookie = dev;            TRACE_ALWAYS("%s (%04x/%04x) added \n",                                        usb_serial_hw_devices[i].descr,                                        usb_serial_hw_devices[i].vendor_id,                                        usb_serial_hw_devices[i].product_id);          }else            free(usd);        }else          status = B_NO_MEMORY;      }      break;    }  if(!*cookie){    if(b_acm_support &&         udd->device_class == USB_DEV_CLASS_COMM &&           udd->device_subclass == 0 &&             udd->device_protocol == 0 ){      const usb_configuration_info *uci;      uint16 idx = 0;      do{        uci = (*usb_m->get_nth_configuration)(dev, idx++);        if(uci){          if(uci->interface_count != 2)            continue;          usd = malloc(sizeof(usb_serial_device));          if(usd){            usd->dev = dev;            usd->hw = &usb_serial_hw_devices[0];            usd->read_buffer_size =             usd->write_buffer_size =             usd->interrupt_buffer_size = ROUNDUP(DEF_BUFFER_SIZE, 16);            if((status = (*usb_serial_hw_devices[0].add_device)(usd, uci)) == B_OK){              *cookie = dev;              TRACE_ALWAYS("%s (%04x/%04x) added \n",                                         usb_serial_hw_devices[0].descr,                                         udd->vendor_id, udd->product_id);            }else              free(usd);          }else            status = B_NO_MEMORY;        }      }while(uci);    }else{      TRACE_ALWAYS("device has wrong class, subclass and protocol\n");      status = B_ERROR;    }  }  TRACE_FUNCRET("usb_serial_device_added returns:%08x\n", status);  return status;}status_t usb_serial_device_removed(void *cookie){  int i;  status_t status = B_OK;  usb_device *ud = (usb_device *) cookie;  TRACE_FUNCALLS("usb_serial_device_removed:%08x\n", cookie);  acquire_sem(usb_serial_lock);    for(i = 0; i < DEVICES_COUNT; i++ ){    usb_serial_device *usd = usb_serial_devices[i];    if(usd){      if(ud == usd->dev){        usd->active = 0;        if(!usd->open)          break;                    delete_area(usd->buffers_area);        delete_sem(usd->done_read);        delete_sem(usd->done_write);        free(usd);        usb_serial_devices[i] = 0;      }    }  }    release_sem(usb_serial_lock);  TRACE_FUNCRET("usb_serial_device_removed returns:%08x\n", status);  return status;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -