~ilya-yanok/ubuntu/precise/grub2/fix-for-948716

« back to all changes in this revision

Viewing changes to term/usb_keyboard.c

  • Committer: Bazaar Package Importer
  • Author(s): Robert Millan
  • Date: 2009-07-25 19:00:53 UTC
  • mfrom: (1.6.3 upstream)
  • mto: (17.4.13 sid)
  • mto: This revision was merged to the branch mainline in revision 53.
  • Revision ID: james.westby@ubuntu.com-20090725190053-uv3lm6ya3zxs77ep
ImportĀ upstreamĀ versionĀ 1.96+20090725

Show diffs side-by-side

added added

removed removed

Lines of Context:
58
58
 
59
59
static grub_usb_device_t usbdev;
60
60
 
61
 
/* Valid values for bmRequestType.  See HID definition version 1.11 section
62
 
   7.2.  */
63
 
#define USB_HID_HOST_TO_DEVICE  0x21
64
 
#define USB_HID_DEVICE_TO_HOST  0xA1
65
 
 
66
 
/* Valid values for bRequest.  See HID definition version 1.11 section 7.2. */
67
 
#define USB_HID_GET_REPORT      0x01
68
 
#define USB_HID_GET_IDLE        0x02
69
 
#define USB_HID_GET_PROTOCOL    0x03
70
 
#define USB_HID_SET_REPORT      0x09
71
 
#define USB_HID_SET_IDLE        0x0A
72
 
#define USB_HID_SET_PROTOCOL    0x0B
73
 
 
74
61
static void
75
62
grub_usb_hid (void)
76
63
{
103
90
  grub_usb_iterate (usb_iterate);
104
91
 
105
92
  /* Place the device in boot mode.  */
106
 
  grub_usb_control_msg (usbdev, USB_HID_HOST_TO_DEVICE, USB_HID_SET_PROTOCOL,
107
 
                        0, 0, 0, 0);
 
93
  grub_usb_control_msg (usbdev, 0x21, 0x0B, 0, 0, 0, 0);
108
94
 
109
95
  /* Reports every time an event occurs and not more often than that.  */
110
 
  grub_usb_control_msg (usbdev, USB_HID_HOST_TO_DEVICE, USB_HID_SET_IDLE,
111
 
                        0<<8, 0, 0, 0);
 
96
  grub_usb_control_msg (usbdev, 0x21, 0x0A, 0<<8, 0, 0, 0);
112
97
}
113
98
 
114
99
static grub_err_t
115
 
grub_usb_keyboard_getreport (grub_usb_device_t dev, grub_uint8_t *report)
 
100
grub_usb_keyboard_getreport (grub_usb_device_t dev, unsigned char *report)
116
101
{
117
 
  return grub_usb_control_msg (dev, USB_HID_DEVICE_TO_HOST, USB_HID_GET_REPORT,
118
 
                               0, 0, 8, (char *) report);
 
102
  return grub_usb_control_msg (dev, (1 << 7) | (1 << 5) | 1, 0x01, 0, 0,
 
103
                               8, (char *) report);
119
104
}
120
105
 
121
106
 
123
108
static int
124
109
grub_usb_keyboard_checkkey (void)
125
110
{
126
 
  grub_uint8_t data[8];
 
111
  unsigned char data[8];
127
112
  int key;
 
113
  int i;
128
114
  grub_err_t err;
129
 
  grub_uint64_t currtime;
130
 
  int timeout = 50;
131
115
 
132
116
  data[2] = 0;
133
 
  currtime = grub_get_time_ms ();
134
 
  do
 
117
  for (i = 0; i < 50; i++)
135
118
    {
136
119
      /* Get_Report.  */
137
120
      err = grub_usb_keyboard_getreport (usbdev, data);
138
121
 
139
 
      /* Implement a timeout.  */
140
 
      if (grub_get_time_ms () > currtime + timeout)
 
122
      if (! err && data[2])
141
123
        break;
142
124
    }
143
 
  while (err || !data[2]);
144
125
 
145
126
  if (err || !data[2])
146
127
    return -1;
166
147
  /* Wait until the key is released.  */
167
148
  while (!err && data[2])
168
149
    {
169
 
      err = grub_usb_control_msg (usbdev, USB_HID_DEVICE_TO_HOST,
170
 
                                  USB_HID_GET_REPORT, 0, 0,
 
150
      err = grub_usb_control_msg (usbdev, (1 << 7) | (1 << 5) | 1, 0x01, 0, 0,
171
151
                                  sizeof (data), (char *) data);
172
152
      grub_dprintf ("usb_keyboard",
173
153
                    "report2: 0x%02x 0x%02x 0x%02x 0x%02x"
194
174
{
195
175
  int key;
196
176
  grub_err_t err;
197
 
  grub_uint8_t data[8];
 
177
  unsigned char data[8];
198
178
  grub_uint64_t currtime;
199
179
  int timeout;
200
180
  static grub_usb_keyboard_repeat_t repeat = GRUB_HIDBOOT_REPEAT_NONE;
254
234
  return key;
255
235
}
256
236
 
257
 
static int
258
 
grub_usb_keyboard_getkeystatus (void)
259
 
{
260
 
  grub_uint8_t data[8];
261
 
  int mods = 0;
262
 
  grub_err_t err;
263
 
  grub_uint64_t currtime;
264
 
  int timeout = 50;
265
 
 
266
 
  /* Set idle time to the minimum offered by the spec (4 milliseconds) so
267
 
     that we can find out the current state.  */
268
 
  grub_usb_control_msg (usbdev, USB_HID_HOST_TO_DEVICE, USB_HID_SET_IDLE,
269
 
                        0<<8, 0, 0, 0);
270
 
 
271
 
  currtime = grub_get_time_ms ();
272
 
  do
273
 
    {
274
 
      /* Get_Report.  */
275
 
      err = grub_usb_keyboard_getreport (usbdev, data);
276
 
 
277
 
      /* Implement a timeout.  */
278
 
      if (grub_get_time_ms () > currtime + timeout)
279
 
        break;
280
 
    }
281
 
  while (err || !data[0]);
282
 
 
283
 
  /* Go back to reporting every time an event occurs and not more often than
284
 
     that.  */
285
 
  grub_usb_control_msg (usbdev, USB_HID_HOST_TO_DEVICE, USB_HID_SET_IDLE,
286
 
                        0<<8, 0, 0, 0);
287
 
 
288
 
  /* We allowed a while for modifiers to show up in the report, but it is
289
 
     not an error if they never did.  */
290
 
  if (err)
291
 
    return -1;
292
 
 
293
 
  grub_dprintf ("usb_keyboard",
294
 
                "report: 0x%02x 0x%02x 0x%02x 0x%02x"
295
 
                " 0x%02x 0x%02x 0x%02x 0x%02x\n",
296
 
                data[0], data[1], data[2], data[3],
297
 
                data[4], data[5], data[6], data[7]);
298
 
 
299
 
  /* Check Shift, Control, and Alt status.  */
300
 
  if (data[0] & 0x02 || data[0] & 0x20)
301
 
    mods |= GRUB_TERM_STATUS_SHIFT;
302
 
  if (data[0] & 0x01 || data[0] & 0x10)
303
 
    mods |= GRUB_TERM_STATUS_CTRL;
304
 
  if (data[0] & 0x04 || data[0] & 0x40)
305
 
    mods |= GRUB_TERM_STATUS_ALT;
306
 
 
307
 
  grub_errno = GRUB_ERR_NONE;
308
 
 
309
 
  return mods;
310
 
}
311
 
 
312
237
static struct grub_term_input grub_usb_keyboard_term =
313
238
  {
314
239
    .name = "usb_keyboard",
315
240
    .checkkey = grub_usb_keyboard_checkkey,
316
241
    .getkey = grub_usb_keyboard_getkey,
317
 
    .getkeystatus = grub_usb_keyboard_getkeystatus,
318
242
    .next = 0
319
243
  };
320
244