Split common usbserial function. PL2303 skeleton

This commit is contained in:
Vladimir 'phcoder' Serbinenko 2010-07-18 19:10:57 +02:00
parent 44e7b8cb49
commit a531fd134d
5 changed files with 362 additions and 84 deletions

View file

@ -22,6 +22,7 @@
#include <grub/misc.h>
#include <grub/mm.h>
#include <grub/usb.h>
#include <grub/usbserial.h>
enum
{
@ -161,19 +162,12 @@ ftdi_hw_configure (struct grub_serial_port *port,
return GRUB_ERR_NONE;
}
static void
ftdi_fini (struct grub_serial_port *port)
{
port->usbdev->config[port->configno].interf[port->interfno].detach_hook = 0;
port->usbdev->config[port->configno].interf[port->interfno].attached = 0;
}
static struct grub_serial_driver grub_ftdi_driver =
{
.configure = ftdi_hw_configure,
.fetch = ftdi_hw_fetch,
.put = ftdi_hw_put,
.fini = ftdi_fini
.fini = grub_usbserial_fini
};
static const struct
@ -184,80 +178,6 @@ static const struct
{0x0403, 0x6001} /* QEMU virtual USBserial. */
};
static int ftdinum = 0;
static void
ftdi_detach (grub_usb_device_t usbdev, int configno, int interfno)
{
static struct grub_serial_port *port;
port = usbdev->config[configno].interf[interfno].detach_data;
grub_serial_unregister (port);
}
static int
grub_ftdi_attach_real (grub_usb_device_t usbdev, int configno, int interfno)
{
static struct grub_serial_port *port;
int j;
struct grub_usb_desc_if *interf;
interf = usbdev->config[configno].interf[interfno].descif;
port = grub_malloc (sizeof (*port));
if (!port)
{
grub_print_error ();
return 0;
}
port->name = grub_xasprintf ("ftdi%d", ftdinum++);
if (!port->name)
{
grub_free (port);
grub_print_error ();
return 0;
}
port->usbdev = usbdev;
port->driver = &grub_ftdi_driver;
for (j = 0; j < interf->endpointcnt; j++)
{
struct grub_usb_desc_endp *endp;
endp = &usbdev->config[0].interf[interfno].descendp[j];
if ((endp->endp_addr & 128) && (endp->attrib & 3) == 2)
{
/* Bulk IN endpoint. */
port->in_endp = endp;
}
else if (!(endp->endp_addr & 128) && (endp->attrib & 3) == 2)
{
/* Bulk OUT endpoint. */
port->out_endp = endp;
}
}
if (!port->out_endp || !port->in_endp)
{
grub_free (port->name);
grub_free (port);
return 0;
}
port->configno = configno;
port->interfno = interfno;
grub_serial_config_defaults (port);
grub_serial_register (port);
port->usbdev->config[port->configno].interf[port->interfno].detach_hook
= ftdi_detach;
port->usbdev->config[port->configno].interf[port->interfno].detach_data
= port;
return 1;
}
static int
grub_ftdi_attach (grub_usb_device_t usbdev, int configno, int interfno)
{
@ -270,10 +190,11 @@ grub_ftdi_attach (grub_usb_device_t usbdev, int configno, int interfno)
if (j == ARRAY_SIZE (products))
return 0;
return grub_ftdi_attach_real (usbdev, configno, interfno);
return grub_usbserial_attach (usbdev, configno, interfno,
&grub_ftdi_driver);
}
struct grub_usb_attach_desc attach_hook =
static struct grub_usb_attach_desc attach_hook =
{
.class = 0xff,
.hook = grub_ftdi_attach