예제 #1
0
static int wiiusb_hid_add_adapter(void *data, usb_device_entry *dev)
{
   usb_devdesc desc;
   const char        *device_name = NULL;
   wiiusb_hid_t              *hid = (wiiusb_hid_t*)data;
   struct wiiusb_adapter *adapter = (struct wiiusb_adapter*)
      calloc(1, sizeof(struct wiiusb_adapter));

   if (!adapter)
      return -1;

   if (!hid)
   {
      free(adapter);
      RARCH_ERR("Allocation of adapter failed.\n");
      return -1;
   }

   if (USB_OpenDevice(dev->device_id, dev->vid, dev->pid, &adapter->handle) < 0)
   {
      RARCH_ERR("Error opening device 0x%p (VID/PID: %04x:%04x).\n",
           dev->device_id, dev->vid, dev->pid);
      free(adapter);
      return -1;
   }

   adapter->device_id = dev->device_id;

   USB_GetDescriptors(adapter->handle, &desc);
   wiiusb_get_description(dev, adapter, &desc);

   if (adapter->endpoint_in == 0)
   {
      RARCH_ERR("Could not find HID config for device.\n");
      goto error;
   }

   /* Allocate mem for the send control buffer, 32bit aligned */
   adapter->send_control_type   = WIIUSB_SC_NONE;
   adapter->send_control_buffer = memalign(32, 128);

   if (!adapter->send_control_buffer)
   {
      RARCH_ERR("Error creating send control buffer.\n");
      goto error;
   }

   /* Sent the pad name as dummy, we don't know the
    * control name until we get its interface */
   adapter->slot = pad_connection_pad_init(hid->connections,
         "hid", desc.idVendor, desc.idProduct,
         adapter, &wiiusb_hid);

   if (adapter->slot == -1)
      goto error;

   if (!pad_connection_has_interface(hid->connections, adapter->slot))
   {
      RARCH_ERR(" Interface not found.\n");
      goto error;
   }

   adapter->data      = memalign(32, 128);
   adapter->hid       = hid;
   adapter->next      = hid->adapters_head;
   hid->adapters_head = adapter;

   /*  Get the name from the interface */
   device_name = wiiusb_hid_joypad_name(hid, adapter->slot);

   RARCH_LOG("Interface found: [%s].\n", device_name);

   RARCH_LOG("Device 0x%p attached (VID/PID: %04x:%04x).\n",
         adapter->device_id, desc.idVendor, desc.idProduct);

   wiiusb_hid_device_add_autodetect(adapter->slot,
         device_name, wiiusb_hid.ident, desc.idVendor, desc.idProduct);

   USB_FreeDescriptors(&desc);
   USB_DeviceRemovalNotifyAsync(adapter->handle, wiiusb_hid_removal_cb, adapter);

   return 0;

error:
   if (adapter->send_control_buffer)
      free(adapter->send_control_buffer);
   if (adapter)
      free(adapter);
   USB_FreeDescriptors(&desc);
   USB_CloseDevice(&adapter->handle);
   return -1;
}
예제 #2
0
static int add_adapter(void *data, usb_device_entry *dev)
{
   int rc;
   usb_devdesc desc;
   const char *device_name = NULL;
   struct wiiusb_adapter *old_head = NULL;
   struct wiiusb_hid *hid = (struct wiiusb_hid*)data;
   struct wiiusb_adapter *adapter  = (struct wiiusb_adapter*)
      calloc(1, sizeof(struct wiiusb_adapter));

   (void)rc;

   if (!adapter)
      return -1;

   if (!hid)
   {
      free(adapter);
      RARCH_ERR("Allocation of adapter failed.\n");
      return -1;
   }

   if (USB_OpenDevice(dev->device_id, dev->vid, dev->pid, &adapter->handle) < 0)
   {
      RARCH_ERR("Error opening device 0x%p (VID/PID: %04x:%04x).\n",
            (void*)&adapter->device, dev->vid, dev->pid);
      free(adapter);
      return -1;
   }

   adapter->device = *dev;

   USB_GetDescriptors(adapter->handle, &desc);

   wiiusb_get_description(&adapter->device, adapter, &desc);

   if (adapter->endpoint_in == 0)
   {
      RARCH_ERR("Could not find HID config for device.\n");
      goto error;
   }

   if (desc.iManufacturer)
   {
      USB_GetAsciiString(adapter->handle, desc.iManufacturer, 0,
            sizeof(adapter->manufacturer_name), adapter->manufacturer_name);
#if 0
      RARCH_ERR(" Adapter Manufacturer name: %s\n", adapter->manufacturer_name);
#endif
   }

   if (desc.iProduct)
   {
      USB_GetAsciiString(adapter->handle, desc.iProduct, 0,
            sizeof(adapter->name), adapter->name);
#if 0
      RARCH_ERR(" Adapter name: %s\n", adapter->name);
#endif
   }

   device_name = (const char *)adapter->name;

   adapter->send_control_lock = slock_new();
   adapter->send_control_buffer = fifo_new(4096);

   if (!adapter->send_control_lock || !adapter->send_control_buffer)
   {
      RARCH_ERR("Error creating send control buffer.\n");
      goto error;
   }

   adapter->slot = pad_connection_pad_init(hid->slots,
         device_name, desc.idVendor, desc.idProduct,
         adapter, &wiiusb_hid_device_send_control);

   if (adapter->slot == -1)
      goto error;

   if (!pad_connection_has_interface(hid->slots, adapter->slot))
   {
      RARCH_ERR(" Interface not found (%s).\n", adapter->name);
      goto error;
   }

   RARCH_LOG("Interface found: [%s].\n", adapter->name);

   RARCH_LOG("Device 0x%p attached (VID/PID: %04x:%04x).\n",
         adapter->device, desc.idVendor, desc.idProduct);

   wiiusb_hid_device_add_autodetect(adapter->slot,
         device_name, wiiusb_hid.ident, desc.idVendor, desc.idProduct);

   adapter->hid = hid;
   adapter->thread = sthread_create(adapter_thread, adapter);

   if (!adapter->thread)
   {
      RARCH_ERR("Error initializing adapter thread.\n");
      goto error;
   }

   adapter->data = memalign(32, 2048);

   old_head = adapters.next;
   adapters.next = adapter;
   adapter->next = old_head;

   USB_FreeDescriptors(&desc);

   USB_DeviceRemovalNotifyAsync(adapter->handle, wiiusb_hid_removalnotify_cb, (void *)hid);

   return 0;

error:
   if (adapter->thread)
      sthread_join(adapter->thread);
   if (adapter->send_control_lock)
      slock_free(adapter->send_control_lock);
   if (adapter->send_control_buffer)
      fifo_free(adapter->send_control_buffer);
   if (adapter)
      free(adapter);
   USB_FreeDescriptors(&desc);
   USB_CloseDevice(&adapter->handle);
   return -1;
}