~ubuntu-branches/ubuntu/trusty/grub2/trusty-updates

« back to all changes in this revision

Viewing changes to bus/usb/usb.c

Tags: upstream-1.99~20101122
ImportĀ upstreamĀ versionĀ 1.99~20101122

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* usb.c - Generic USB interfaces.  */
2
 
/*
3
 
 *  GRUB  --  GRand Unified Bootloader
4
 
 *  Copyright (C) 2008  Free Software Foundation, Inc.
5
 
 *
6
 
 *  GRUB is free software: you can redistribute it and/or modify
7
 
 *  it under the terms of the GNU General Public License as published by
8
 
 *  the Free Software Foundation, either version 3 of the License, or
9
 
 *  (at your option) any later version.
10
 
 *
11
 
 *  GRUB is distributed in the hope that it will be useful,
12
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 
 *  GNU General Public License for more details.
15
 
 *
16
 
 *  You should have received a copy of the GNU General Public License
17
 
 *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
18
 
 */
19
 
 
20
 
#include <grub/dl.h>
21
 
#include <grub/mm.h>
22
 
#include <grub/usb.h>
23
 
#include <grub/misc.h>
24
 
 
25
 
static grub_usb_controller_dev_t grub_usb_list;
26
 
 
27
 
void
28
 
grub_usb_controller_dev_register (grub_usb_controller_dev_t usb)
29
 
{
30
 
  auto int iterate_hook (grub_usb_controller_t dev);
31
 
 
32
 
  /* Iterate over all controllers found by the driver.  */
33
 
  int iterate_hook (grub_usb_controller_t dev)
34
 
    {
35
 
      dev->dev = usb;
36
 
 
37
 
      /* Enable the ports of the USB Root Hub.  */
38
 
      grub_usb_root_hub (dev);
39
 
 
40
 
      return 0;
41
 
    }
42
 
 
43
 
  usb->next = grub_usb_list;
44
 
  grub_usb_list = usb;
45
 
 
46
 
  if (usb->iterate)
47
 
    usb->iterate (iterate_hook);
48
 
}
49
 
 
50
 
void
51
 
grub_usb_controller_dev_unregister (grub_usb_controller_dev_t usb)
52
 
{
53
 
  grub_usb_controller_dev_t *p, q;
54
 
 
55
 
  for (p = &grub_usb_list, q = *p; q; p = &(q->next), q = q->next)
56
 
    if (q == usb)
57
 
      {
58
 
        *p = q->next;
59
 
        break;
60
 
      }
61
 
}
62
 
 
63
 
#if 0
64
 
int
65
 
grub_usb_controller_iterate (int (*hook) (grub_usb_controller_t dev))
66
 
{
67
 
  grub_usb_controller_dev_t p;
68
 
 
69
 
  auto int iterate_hook (grub_usb_controller_t dev);
70
 
 
71
 
  int iterate_hook (grub_usb_controller_t dev)
72
 
    {
73
 
      dev->dev = p;
74
 
      if (hook (dev))
75
 
        return 1;
76
 
      return 0;
77
 
    }
78
 
 
79
 
  /* Iterate over all controller drivers.  */
80
 
  for (p = grub_usb_list; p; p = p->next)
81
 
    {
82
 
      /* Iterate over the busses of the controllers.  XXX: Actually, a
83
 
         hub driver should do this.  */
84
 
      if (p->iterate (iterate_hook))
85
 
        return 1;
86
 
    }
87
 
 
88
 
  return 0;
89
 
}
90
 
#endif
91
 
 
92
 
 
93
 
grub_usb_err_t
94
 
grub_usb_clear_halt (grub_usb_device_t dev, int endpoint)
95
 
{
96
 
  dev->toggle[endpoint] = 0;
97
 
  return grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT
98
 
                                     | GRUB_USB_REQTYPE_STANDARD
99
 
                                     | GRUB_USB_REQTYPE_TARGET_ENDP),
100
 
                               GRUB_USB_REQ_CLEAR_FEATURE,
101
 
                               GRUB_USB_FEATURE_ENDP_HALT,
102
 
                               endpoint, 0, 0);
103
 
}
104
 
 
105
 
grub_usb_err_t
106
 
grub_usb_set_configuration (grub_usb_device_t dev, int configuration)
107
 
{
108
 
  int i;
109
 
 
110
 
  for (i = 0; i < 16; i++)
111
 
    dev->toggle[i] = 0;
112
 
 
113
 
  return grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT
114
 
                                     | GRUB_USB_REQTYPE_STANDARD
115
 
                                     | GRUB_USB_REQTYPE_TARGET_DEV),
116
 
                               GRUB_USB_REQ_SET_CONFIGURATION, configuration,
117
 
                               0, 0, NULL);
118
 
}
119
 
 
120
 
grub_usb_err_t
121
 
grub_usb_get_descriptor (grub_usb_device_t dev,
122
 
                         grub_uint8_t type, grub_uint8_t index,
123
 
                         grub_size_t size, char *data)
124
 
{
125
 
  return grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_IN
126
 
                                     | GRUB_USB_REQTYPE_STANDARD
127
 
                                     | GRUB_USB_REQTYPE_TARGET_DEV),
128
 
                               GRUB_USB_REQ_GET_DESCRIPTOR,
129
 
                               (type << 8) | index,
130
 
                               0, size, data);
131
 
}
132
 
 
133
 
struct grub_usb_desc_endp *
134
 
grub_usb_get_endpdescriptor (grub_usb_device_t usbdev, int addr)
135
 
{
136
 
  int i;
137
 
 
138
 
  for (i = 0; i < usbdev->config[0].descconf->numif; i++)
139
 
    {
140
 
      struct grub_usb_desc_if *interf;
141
 
      int j;
142
 
 
143
 
      interf = usbdev->config[0].interf[i].descif;
144
 
 
145
 
      for (j = 0; j < interf->endpointcnt; j++)
146
 
        {
147
 
          struct grub_usb_desc_endp *endp;
148
 
          endp = &usbdev->config[0].interf[i].descendp[j];
149
 
 
150
 
          if (endp->endp_addr == addr)
151
 
            return endp;
152
 
        }
153
 
    }
154
 
 
155
 
  return NULL;
156
 
}
157
 
 
158
 
grub_usb_err_t
159
 
grub_usb_device_initialize (grub_usb_device_t dev)
160
 
{
161
 
  struct grub_usb_desc_device *descdev;
162
 
  struct grub_usb_desc_config config;
163
 
  grub_usb_err_t err;
164
 
  int i;
165
 
 
166
 
  err = grub_usb_get_descriptor (dev, GRUB_USB_DESCRIPTOR_DEVICE,
167
 
                                 0, sizeof (struct grub_usb_desc_device),
168
 
                                 (char *) &dev->descdev);
169
 
  if (err)
170
 
    return err;
171
 
  descdev = &dev->descdev;
172
 
 
173
 
  for (i = 0; i < 8; i++)
174
 
    dev->config[i].descconf = NULL;
175
 
 
176
 
  for (i = 0; i < descdev->configcnt; i++)
177
 
    {
178
 
      int pos;
179
 
      int currif;
180
 
      char *data;
181
 
 
182
 
      /* First just read the first 4 bytes of the configuration
183
 
         descriptor, after that it is known how many bytes really have
184
 
         to be read.  */
185
 
      err = grub_usb_get_descriptor (dev, GRUB_USB_DESCRIPTOR_CONFIG, i, 4,
186
 
                                     (char *) &config);
187
 
 
188
 
      data = grub_malloc (config.totallen);
189
 
      if (! data)
190
 
        {
191
 
          err = GRUB_USB_ERR_INTERNAL;
192
 
          goto fail;
193
 
        }
194
 
 
195
 
      dev->config[i].descconf = (struct grub_usb_desc_config *) data;
196
 
      err = grub_usb_get_descriptor (dev, GRUB_USB_DESCRIPTOR_CONFIG, i,
197
 
                                     config.totallen, data);
198
 
      if (err)
199
 
        goto fail;
200
 
 
201
 
      /* Skip the configuration descriptor.  */
202
 
      pos = sizeof (struct grub_usb_desc_config);
203
 
 
204
 
      /* Read all interfaces.  */
205
 
      for (currif = 0; currif < dev->config[i].descconf->numif; currif++)
206
 
        {
207
 
          dev->config[i].interf[currif].descif
208
 
            = (struct grub_usb_desc_if *) &data[pos];
209
 
          pos += sizeof (struct grub_usb_desc_if);
210
 
 
211
 
          /* Point to the first endpoint.  */
212
 
          dev->config[i].interf[currif].descendp
213
 
            = (struct grub_usb_desc_endp *) &data[pos];
214
 
          pos += (sizeof (struct grub_usb_desc_endp)
215
 
                  * dev->config[i].interf[currif].descif->endpointcnt);
216
 
        }
217
 
    }
218
 
 
219
 
  return GRUB_USB_ERR_NONE;
220
 
 
221
 
 fail:
222
 
 
223
 
  for (i = 0; i < 8; i++)
224
 
    grub_free (dev->config[i].descconf);
225
 
 
226
 
  return err;
227
 
}