int WANDongleSerialPort::writePacket()
{
  tx_mtx.lock();
  if(lock_tx)
  {
    USB_ERR("Fail");
    tx_mtx.unlock();
    return -1;
  }

  if( bulk_out == NULL )
  {
    USB_WARN("Port is disconnected");
    tx_mtx.unlock();
    return -1;
  }

  lock_tx = true; //Transmitting
  tx_mtx.unlock();
//  USB_DBG("writePacket");

  //lock_tx.lock();
  USB_TYPE res = host->bulkWrite(dev, (USBEndpoint *)bulk_out, buf_out, buf_out_len, false); //Queue transfer
  if(res != USB_TYPE_PROCESSING)
  {
    //lock_tx.unlock();
    USB_ERR("host->bulkWrite() returned %d", res);
    ThisThread::sleep_for(100);
    return -1;
  }
  return 0;
}
int WANDongleSerialPort::readPacket()
{
  USB_DBG("Read packet on %p", this);
  rx_mtx.lock();
  if(lock_rx)
  {
    USB_ERR("Fail");
    rx_mtx.unlock();
    return -1;
  }

  if( bulk_in == NULL )
  {
    USB_WARN("Port is disconnected");
    rx_mtx.unlock();
    return -1;
  }

  lock_rx = true; //Receiving
  rx_mtx.unlock();
//  USB_DBG("readPacket");
  //lock_rx.lock();
  USB_TYPE res = host->bulkRead(dev, (USBEndpoint *)bulk_in, buf_in, ((USBEndpoint *)bulk_in)->getSize(), false); //Queue transfer
  if(res != USB_TYPE_PROCESSING)
  {
    //lock_rx.unlock();
    USB_ERR("host->bulkRead() returned %d", res);
    ThisThread::sleep_for(100);
    return -1;
  }
  return 0;
}
static int usb_presence_rx(struct req_ctx *rctx)
{
    struct openpcd_hdr *poh = (struct openpcd_hdr *) rctx->data;

    switch (poh->cmd)
    {
        case OPENPCD_CMD_PRESENCE_UID_GET:
		DEBUGPCRF("get presence UID");	
		
		poh->flags |= OPENPCD_FLAG_RESPOND;
		if(last_polled_uid)
		{
            	    rctx->tot_len += 4;
		    poh->data[0]=(u_int8_t)(last_polled_uid>>24);
		    poh->data[1]=(u_int8_t)(last_polled_uid>>16);
		    poh->data[2]=(u_int8_t)(last_polled_uid>> 8);
		    poh->data[3]=(u_int8_t)(last_polled_uid    );
		    last_polled_uid=0;
		}
                break;
	default:
	        DEBUGP("UNKNOWN ");
                return USB_ERR(USB_ERR_CMD_UNKNOWN);
            	break;
    }
	
    if (poh->flags & OPENPCD_FLAG_RESPOND)
        return USB_RET_RESPOND;

    return 0;
}
示例#4
0
void USBHostHub::portReset(uint8_t port) {
    // reset port
    uint32_t status;
    USB_DBG("reset port %d on hub: %p [this: %p]", port, dev, this)
    setPortFeature(PORT_RESET_FEATURE, port);
    while(1) {
        status = getPortStatus(port);
        if (status & (PORT_ENABLE | PORT_RESET))
            break;
        if (status & PORT_OVER_CURRENT) {
            USB_ERR("OVER CURRENT DETECTED\r\n");
            clearPortFeature(PORT_OVER_CURRENT, port);
            host->deviceDisconnected(dev->getHub() + 1, port, this, 0);
            break;
        }
        Thread::wait(10);
    }
}
int WANDongleSerialPort::putc(int c)
{
  tx_mtx.lock();
  if(!lock_tx)
  {
    if(buf_out_len < max_out_size)
    {
      buf_out[buf_out_len] = (uint8_t)c;
      buf_out_len++;
    }
  }
  else
  {
    USB_ERR("CAN'T WRITE!");
  }
  tx_mtx.unlock();
  return c;
}
int WANDongleSerialPort::getc()
{
  rx_mtx.lock();
  int c = 0;
  if(!lock_rx)
  {
    if(buf_in_read_pos < buf_in_len)
    {
      c = (int)buf_in[buf_in_read_pos];
      buf_in_read_pos++;
    }
  }
  else
  {
    USB_ERR("CAN'T READ!");
  }
  rx_mtx.unlock();
  return c;
}
示例#7
0
static struct platform_device *
tegra_usb_otg_host_register(struct platform_device *ehci_device,
			    struct tegra_ehci_platform_data *pdata)
{
	struct platform_device *pdev;
	void *platform_data;
	int val;

	pdev = platform_device_alloc(ehci_device->name, ehci_device->id);
	if (!pdev)
		return NULL;

	val = platform_device_add_resources(pdev, ehci_device->resource,
					    ehci_device->num_resources);
	if (val)
		goto error;

	pdev->dev.dma_mask =  ehci_device->dev.dma_mask;
	pdev->dev.coherent_dma_mask = ehci_device->dev.coherent_dma_mask;

	platform_data = kmalloc(sizeof(struct tegra_ehci_platform_data),
		GFP_KERNEL);
	if (!platform_data)
		goto error;

	memcpy(platform_data, pdata, sizeof(struct tegra_ehci_platform_data));
	pdev->dev.platform_data = platform_data;

	val = platform_device_add(pdev);
	if (val)
		goto error_add;

	return pdev;

error_add:
	kfree(platform_data);
error:
	USB_ERR("%s: failed to add the host controller device\n", __func__);
	platform_device_put(pdev);
	return NULL;
}
示例#8
0
void USBHostHub::rxHandler() {
    uint32_t status;
    if (int_in) {
        if (int_in->getState() == USB_TYPE_IDLE) {
            for (int port = 1; port <= nb_port; port++) {
                status = getPortStatus(port);
                USB_DBG("[hub handler hub: %d] status port %d [hub: %p]: 0x%X", dev->getHub(), port, dev, status);

                // if connection status has changed
                if (status & C_PORT_CONNECTION) {
                    if (status & PORT_CONNECTION) {
                        USB_DBG("[hub handler hub: %d - port: %d] new device connected", dev->getHub(), port);
                        host->deviceConnected(dev->getHub() + 1, port, status & PORT_LOW_SPEED, this);
                    } else {
                        USB_DBG("[hub handler hub: %d - port: %d] device disconnected", dev->getHub(), port);
                        host->deviceDisconnected(dev->getHub() + 1, port, this, 0);
                    }

                    clearPortFeature(C_PORT_CONNECTION_FEATURE, port);
                }

                if (status & C_PORT_RESET) {
                    clearPortFeature(C_PORT_RESET_FEATURE, port);
                }

                if (status & C_PORT_ENABLE) {
                    clearPortFeature(C_PORT_ENABLE_FEATURE, port);
                }

                if ((status & PORT_OVER_CURRENT)) {
                    USB_ERR("OVER CURRENT DETECTED\r\n");
                    clearPortFeature(PORT_OVER_CURRENT, port);
                    host->deviceDisconnected(dev->getHub() + 1, port, this, 0);
                }
            }
        }
        host->interruptRead(dev, int_in, buf, 1, false);
    }
}
示例#9
0
bool WANDongle::tryConnect() {
    //FIXME should run on USB thread

    USB_DBG("Trying to connect device");

    if (dev_connected) {
        USB_DBG("Device is already connected!");
        return true;
    }

    m_pInitializer = NULL;

    //Protect from concurrent access from USB thread
    USBHost::Lock lock(host);

    for (int i = 0; i < MAX_DEVICE_CONNECTED; i++) {
        if ((dev = host->getDevice(i)) != NULL) {
            m_pInitializer = NULL; //Will be set in setVidPid callback

            USB_DBG("Enumerate");
            int ret = host->enumerate(dev, this);
            if(ret) {
                return false;
            }

            USB_DBG("Device has VID:%04x PID:%04x", dev->getVid(), dev->getPid());

            if(m_pInitializer) { //If an initializer has been found
                //USB_DBG("m_pInitializer=%p", m_pInitializer);
                //USB_DBG("m_pInitializer->getSerialVid()=%04x", m_pInitializer->getSerialVid());
                //USB_DBG("m_pInitializer->getSerialPid()=%04x", m_pInitializer->getSerialPid());
                if ((dev->getVid() == m_pInitializer->getSerialVid()) &&
                        (dev->getPid() == m_pInitializer->getSerialPid())) {
                    USB_DBG("The dongle is in virtual serial mode");
                    host->registerDriver(dev, 0, this, &WANDongle::init);
                    m_serialCount = m_pInitializer->getSerialPortCount();
                    if( m_serialCount > WANDONGLE_MAX_SERIAL_PORTS ) {
                        m_serialCount = WANDONGLE_MAX_SERIAL_PORTS;
                    }
                    USB_DBG("Initied Serial Ports %d",m_serialCount);
                    for(int j = 0; j < m_serialCount; j++) {
                        USB_DBG("Connecting serial port #%d", j+1);
                        USB_DBG("Ep %p", m_pInitializer->getEp(dev, j, false));
                        USB_DBG("Ep %p", m_pInitializer->getEp(dev, j, true));
                        m_serial[j].connect( dev, m_pInitializer->getEp(dev, j, false), m_pInitializer->getEp(dev, j, true) );
                    }

                    USB_DBG("Device connected");

                    dev_connected = true;

                    return true;
                } else if ((dev->getVid() == m_pInitializer->getMSDVid()) &&
                           (dev->getPid() == m_pInitializer->getMSDPid())) {
                    USB_DBG("Dongle detected in Wrong USB mode");
                    //Try to switch
                    if( m_pInitializer->switchMode(dev) ) {
                        USB_DBG("Switched OK");
                        return false; //Will be connected on a next iteration
                    } else {
                        USB_ERR("Could not switch mode");
                        return false;
                    }
                }
            } //if()
        } //if()
    } //for()
    return false;
}
示例#10
0
/*
 * This function will be called after a whole SETUP-OUT-IN transfer.
 */
void do_vendor_out_complete( pcd_struct_t *_pcd, struct usb_ctrlrequest * ctrl)
{
	int			value = 0;
	u16			w_index = ctrl->wIndex;
	u16			w_value = ctrl->wValue;
	u16			w_length = ctrl->wLength;
	void (*fp)(void);
	char * buf; 

	//USB_DBG("do_vendor_out_complete()\n");
	switch (ctrl->bRequest) {

	  case AM_REQ_WRITE_MEM:
		if (ctrl->bRequestType != (USB_DIR_OUT | USB_TYPE_VENDOR |
				USB_RECIP_DEVICE))
				break;
			USB_DBG("--am req write memory completed\n\n");
	  	break;
		
	  case AM_REQ_FILL_MEM:
	  	buf = _pcd->buf;
		unsigned int addr,i;
		for(i = 0; i < _pcd->length; i+=8){
			addr = *((unsigned int *)&buf[i]) ;
			value = *((unsigned int *)&buf[i+4]) ;
			*(unsigned int*)addr = value;
		}
	  	break;

	  case AM_REQ_WRITE_AUX:
	  	buf = _pcd->buf;
		unsigned int data =0; 

		data = *((unsigned int *)&buf[0]) ; //reg value
		value = (w_value << 16) + w_index; //aux reg

		//_sr(data,value);
	  	break;	  	

	  case AM_REQ_MODIFY_MEM:
	  	do_modify_memory(w_value,_pcd->buf);
	  	break;		
		
	  case AM_REQ_RUN_IN_ADDR:
	  	if (ctrl->bRequestType != (USB_DIR_OUT | USB_TYPE_VENDOR |
				USB_RECIP_DEVICE))
				break;
	  	value = (w_value << 16) + w_index;
	  	USB_DBG("run addr = 0x%08X\n",value);
	  	fp = (void(*)(void))value;
	  	dwc_otg_power_off_phy();
	  	fp();
	  	break;

	  case AM_REQ_WR_LARGE_MEM:
	  	value = 1; // is_out = 1
	  case AM_REQ_RD_LARGE_MEM:
	  	_pcd->bulk_out = value; // read or write
	  	_pcd->bulk_buf = (char *)(*(unsigned int*)buff); // board address
	  	_pcd->bulk_data_len = (*(unsigned int*) &buff[4]); // data length
	  	start_bulk_transfer(_pcd);
	  	break;

	  default:
		USB_ERR("--unknown vendor req comp %02x.%02x v%04x i%04x l%u\n",
			ctrl->bRequestType, ctrl->bRequest,
			w_value, w_index, w_length);
	}
	w_length = 0;//remove compile warning
	return;
}
示例#11
0
/**
 * This functions delegates vendor ctrl request.
 */
void do_vendor_request( pcd_struct_t *_pcd, struct usb_ctrlrequest * ctrl)
{
	int			value =0;
	u16			w_index = ctrl->wIndex;
	u16			w_value = ctrl->wValue;
	u16			w_length = ctrl->wLength;
	
	switch (ctrl->bRequest) {

	  case AM_REQ_WRITE_MEM:
		if (ctrl->bRequestType != (USB_DIR_OUT | USB_TYPE_VENDOR |
				USB_RECIP_DEVICE))
				break;
		USB_DBG("--am req write memory\n");
		value = (w_value << 16) + w_index;
		USB_DBG("addr = 0x%08X, size = %d\n\n",value,w_length);
		_pcd->buf = (char *)value; // copy to dst memory directly
		_pcd->length = w_length;
	  	break;

	  case AM_REQ_READ_MEM:
		if (ctrl->bRequestType != (USB_DIR_IN | USB_TYPE_VENDOR |
				USB_RECIP_DEVICE))
				break;
		value = (w_value << 16) + w_index;

		usb_memcpy((char *)buff,(char*)value,w_length);
		
		_pcd->buf = buff;
		_pcd->length = w_length;
	  	break;

	  case AM_REQ_READ_AUX:
		if (ctrl->bRequestType != (USB_DIR_IN | USB_TYPE_VENDOR |
				USB_RECIP_DEVICE))
				break;
		unsigned int data = 0;
		value = (w_value << 16) + w_index;

		//data = _lr(value);
		*(unsigned int *)buff = data;
		
		_pcd->buf = buff;
		_pcd->length = w_length;
	  	break;

	  case AM_REQ_FILL_MEM:
	  case AM_REQ_WRITE_AUX:
	  case AM_REQ_MODIFY_MEM:
		if (ctrl->bRequestType != (USB_DIR_OUT | USB_TYPE_VENDOR |
				USB_RECIP_DEVICE))
				break;
		_pcd->buf = buff;
		_pcd->length = w_length;
	  	break;

	  case AM_REQ_RUN_IN_ADDR:
		if (ctrl->bRequestType != (USB_DIR_OUT | USB_TYPE_VENDOR |
				USB_RECIP_DEVICE))
				break;
		value = (w_value << 16) + w_index;
		USB_DBG("--am req run in addr %p\n\n",value);		
		_pcd->buf = buff;
		_pcd->length = w_length;
	  	break;
		
	  case AM_REQ_WR_LARGE_MEM:
	  	value = 1;
	  case AM_REQ_RD_LARGE_MEM:
	  	USB_DBG("--am req large %s mem \n\n",value?"write":"read");

	  	_pcd->bulk_len = w_value;	// block length
	  	_pcd->bulk_num = w_index; // number of block
	  	_pcd->buf = buff;
	  	_pcd->length = w_length; 
		break;
		
	  case AM_REQ_IDENTIFY_HOST:
	  	buff[0] = USB_ROM_VER_MAJOR;
	  	buff[1] = USB_ROM_VER_MINOR;
	  	buff[2] = USB_ROM_STAGE_MAJOR;
	  	buff[3] = USB_ROM_STAGE_MINOR;
	  	_pcd->buf = buff;
	  	_pcd->length = w_length;
	  	need_check_timeout = 0;
		break;
	  default:
		USB_ERR("--unknown vendor req %02x.%02x v%04x i%04x l%u\n",
			ctrl->bRequestType, ctrl->bRequest,
			w_value, w_index, w_length);
		break;
	}

	return;
}
示例#12
0
/**
 * This functions delegates the setup command to the gadget driver.
 */
void do_gadget_setup( pcd_struct_t *_pcd, struct usb_ctrlrequest * ctrl)
{
	int			value;
	u16			w_index = ctrl->wIndex;
	u16			w_value = ctrl->wValue;
	u16			w_length = ctrl->wLength;
	
	/* usually this just stores reply data in the pre-allocated ep0 buffer,
	 * but config change events will also reconfigure hardware. */
	switch (ctrl->bRequest) {

	  case USB_REQ_GET_DESCRIPTOR:
		if (ctrl->bRequestType != (USB_DIR_IN | USB_TYPE_STANDARD |
								USB_RECIP_DEVICE))
			break;
		//time_out_val = USB_ROM_DRIVER_TIMEOUT;// Wait SetConfig (PC install driver OK)
		need_check_timeout = 0;
		switch (w_value >> 8) {
			case USB_DT_DEVICE:
				USB_DBG("--get device descriptor\n\n");
				value = min(w_length, (u16) sizeof device_desc);
				usb_memcpy(buff, (char*)&device_desc, value);
				_pcd->buf = buff;
				_pcd->length = value;
				break;
			case USB_DT_DEVICE_QUALIFIER:
				USB_DBG("--get device qualifier\n\n");
				break;
			case USB_DT_OTHER_SPEED_CONFIG: 
				DBG("--get other speed configuration descriptor\n");
				DBG("--other speed configuration descriptor length :%d\n", value);
				break;
			case USB_DT_CONFIG:
				USB_DBG("--get configuration descriptor: size %d\n",w_length);
				if(w_length > USB_DT_CONFIG_SIZE)
				{					
					value = TOTAL_CONFIG_DESC_LEN;
					usb_memcpy(buff+USB_DT_CONFIG_SIZE,(void*)&intf_desc[0],INTF_CONFIG_DESC_LEN);
				}
				else
					value = w_length;
				usb_memcpy(buff, (void*)&config_desc, USB_DT_CONFIG_SIZE);
				_pcd->buf = buff;
				_pcd->length = value;
				USB_DBG("--configuration descriptor length :%d\n\n", value);			
				break;
			case USB_DT_STRING:
				USB_DBG("--get string descriptor: id: %d\n",w_value & 0xff);
				switch(w_value & 0xff){
					case 0: // IDs
						usb_memcpy(buff,(void*)dt_string_id,DT_STRING_ID_LEN);
						break;
					case 1: // STRING_MANUFACTURER
						usb_memcpy(buff,(void*)dt_string_vid,DT_STRING_VID_LEN);

						break;
					case 2://STRING_PRODUCT
						usb_memcpy(buff,(void*)dt_string_pid,DT_STRING_PID_LEN);
						break;
					case 3://STRING_SERIAL
						usb_memcpy(buff,(void*)dt_string_serial,DT_STRING_SERIAL_LEN);
						break;
					default:
						USB_ERR("Error string id!\n");
						buff[0] = 0;
						break;	
					}
				_pcd->buf = buff;
				_pcd->length = buff[0];
				USB_DBG("--get string descriptor: return length: %d\n\n",_pcd->length);
				break;
			}
			break;

	case USB_REQ_SET_CONFIGURATION:
		if (ctrl->bRequestType != (USB_DIR_OUT | USB_TYPE_STANDARD |
				USB_RECIP_DEVICE))
			break;
		USB_DBG("--set configuration\n\n");
		_pcd->buf = 0;
		_pcd->length = 0;
		_pcd->request_config = 1;   /* Configuration changed */
		//need_check_timeout = 0;
		break;
	
	case USB_REQ_GET_CONFIGURATION:
		if (ctrl->bRequestType != (USB_DIR_IN | USB_TYPE_STANDARD |
				USB_RECIP_DEVICE))
			break;
		USB_DBG("--get configuration\n\n");
		buff[0] = 1;
		_pcd->buf = buff;
		_pcd->length = 1;
		break;

	default:
		USB_ERR("--unknown control req %02x.%02x v%04x i%04x l%u\n",
			ctrl->bRequestType, ctrl->bRequest,
			w_value, w_index, w_length);
	}

	w_index = 0; //remove compile warning
	return ;
}