2 * GRUB -- GRand Unified Bootloader
3 * Copyright (C) 2000,2001,2002,2003,2004,2005,2007,2008,2009,2010 Free Software Foundation, Inc.
5 * GRUB is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * GRUB is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
19 #include <grub/serial.h>
20 #include <grub/usbserial.h>
23 GRUB_MOD_LICENSE ("GPLv3+");
26 grub_usbserial_fini (struct grub_serial_port
*port
)
28 port
->usbdev
->config
[port
->configno
].interf
[port
->interfno
].detach_hook
= 0;
29 port
->usbdev
->config
[port
->configno
].interf
[port
->interfno
].attached
= 0;
33 grub_usbserial_detach (grub_usb_device_t usbdev
, int configno
, int interfno
)
35 static struct grub_serial_port
*port
;
36 port
= usbdev
->config
[configno
].interf
[interfno
].detach_data
;
38 grub_serial_unregister (port
);
41 static int usbnum
= 0;
44 grub_usbserial_attach (grub_usb_device_t usbdev
, int configno
, int interfno
,
45 struct grub_serial_driver
*driver
)
47 struct grub_serial_port
*port
;
49 struct grub_usb_desc_if
*interf
;
50 grub_usb_err_t err
= GRUB_USB_ERR_NONE
;
52 interf
= usbdev
->config
[configno
].interf
[interfno
].descif
;
54 port
= grub_malloc (sizeof (*port
));
61 port
->name
= grub_xasprintf ("usb%d", usbnum
++);
69 port
->usbdev
= usbdev
;
70 port
->driver
= driver
;
71 for (j
= 0; j
< interf
->endpointcnt
; j
++)
73 struct grub_usb_desc_endp
*endp
;
74 endp
= &usbdev
->config
[0].interf
[interfno
].descendp
[j
];
76 if ((endp
->endp_addr
& 128) && (endp
->attrib
& 3) == 2)
78 /* Bulk IN endpoint. */
81 else if (!(endp
->endp_addr
& 128) && (endp
->attrib
& 3) == 2)
83 /* Bulk OUT endpoint. */
84 port
->out_endp
= endp
;
88 /* Configure device */
89 if (port
->out_endp
&& port
->in_endp
)
90 err
= grub_usb_set_configuration (usbdev
, configno
+ 1);
92 if (!port
->out_endp
|| !port
->in_endp
|| err
)
94 grub_free (port
->name
);
99 port
->configno
= configno
;
100 port
->interfno
= interfno
;
102 grub_serial_config_defaults (port
);
103 grub_serial_register (port
);
105 port
->usbdev
->config
[port
->configno
].interf
[port
->interfno
].detach_hook
106 = grub_usbserial_detach
;
107 port
->usbdev
->config
[port
->configno
].interf
[port
->interfno
].detach_data
114 grub_usbserial_fetch (struct grub_serial_port
*port
, grub_size_t header_size
)
119 if (port
->bufstart
< port
->bufend
)
120 return port
->buf
[port
->bufstart
++];
122 err
= grub_usb_bulk_read_extended (port
->usbdev
, port
->in_endp
->endp_addr
,
123 sizeof (port
->buf
), port
->buf
, 10,
125 if (err
!= GRUB_USB_ERR_NONE
)
128 port
->bufstart
= header_size
;
129 port
->bufend
= actual
;
130 if (port
->bufstart
>= port
->bufend
)
133 return port
->buf
[port
->bufstart
++];