]> git.proxmox.com Git - grub2.git/blob - grub-core/disk/pata.c
Import grub2_2.02+dfsg1.orig.tar.xz
[grub2.git] / grub-core / disk / pata.c
1 /* ata_pthru.c - ATA pass through for ata.mod. */
2 /*
3 * GRUB -- GRand Unified Bootloader
4 * Copyright (C) 2009 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/ata.h>
21 #include <grub/scsi.h>
22 #include <grub/disk.h>
23 #include <grub/dl.h>
24 #include <grub/mm.h>
25 #ifndef GRUB_MACHINE_MIPS_QEMU_MIPS
26 #include <grub/pci.h>
27 #include <grub/cs5536.h>
28 #else
29 #define GRUB_MACHINE_PCI_IO_BASE 0xb4000000
30 #endif
31 #include <grub/time.h>
32
33 GRUB_MOD_LICENSE ("GPLv3+");
34
35 /* At the moment, only two IDE ports are supported. */
36 static const grub_port_t grub_pata_ioaddress[] = { GRUB_ATA_CH0_PORT1,
37 GRUB_ATA_CH1_PORT1 };
38
39 struct grub_pata_device
40 {
41 /* IDE port to use. */
42 int port;
43
44 /* IO addresses on which the registers for this device can be
45 found. */
46 grub_port_t ioaddress;
47
48 /* Two devices can be connected to a single cable. Use this field
49 to select device 0 (commonly known as "master") or device 1
50 (commonly known as "slave"). */
51 int device;
52
53 int present;
54
55 struct grub_pata_device *next;
56 };
57
58 static struct grub_pata_device *grub_pata_devices;
59
60 static inline void
61 grub_pata_regset (struct grub_pata_device *dev, int reg, int val)
62 {
63 grub_outb (val, dev->ioaddress + reg);
64 }
65
66 static inline grub_uint8_t
67 grub_pata_regget (struct grub_pata_device *dev, int reg)
68 {
69 return grub_inb (dev->ioaddress + reg);
70 }
71
72 /* Wait for !BSY. */
73 static grub_err_t
74 grub_pata_wait_not_busy (struct grub_pata_device *dev, int milliseconds)
75 {
76 /* ATA requires 400ns (after a write to CMD register) or
77 1 PIO cycle (after a DRQ block transfer) before
78 first check of BSY. */
79 grub_millisleep (1);
80
81 int i = 1;
82 grub_uint8_t sts;
83 while ((sts = grub_pata_regget (dev, GRUB_ATA_REG_STATUS))
84 & GRUB_ATA_STATUS_BUSY)
85 {
86 if (i >= milliseconds)
87 {
88 grub_dprintf ("pata", "timeout: %dms, status=0x%x\n",
89 milliseconds, sts);
90 return grub_error (GRUB_ERR_TIMEOUT, "PATA timeout");
91 }
92
93 grub_millisleep (1);
94 i++;
95 }
96
97 return GRUB_ERR_NONE;
98 }
99
100 static inline grub_err_t
101 grub_pata_check_ready (struct grub_pata_device *dev, int spinup)
102 {
103 if (grub_pata_regget (dev, GRUB_ATA_REG_STATUS) & GRUB_ATA_STATUS_BUSY)
104 return grub_pata_wait_not_busy (dev, spinup ? GRUB_ATA_TOUT_SPINUP
105 : GRUB_ATA_TOUT_STD);
106
107 return GRUB_ERR_NONE;
108 }
109
110 static inline void
111 grub_pata_wait (void)
112 {
113 grub_millisleep (50);
114 }
115
116 #ifdef GRUB_MACHINE_MIPS_QEMU_MIPS
117 #define grub_ata_to_cpu16(x) ((grub_uint16_t) (x))
118 #define grub_cpu_to_ata16(x) ((grub_uint16_t) (x))
119 #else
120 #define grub_ata_to_cpu16 grub_le_to_cpu16
121 #define grub_cpu_to_ata16 grub_cpu_to_le16
122 #endif
123
124 static void
125 grub_pata_pio_read (struct grub_pata_device *dev, char *buf, grub_size_t size)
126 {
127 unsigned int i;
128
129 /* Read in the data, word by word. */
130 for (i = 0; i < size / 2; i++)
131 grub_set_unaligned16 (buf + 2 * i,
132 grub_ata_to_cpu16 (grub_inw(dev->ioaddress
133 + GRUB_ATA_REG_DATA)));
134 if (size & 1)
135 buf[size - 1] = (char) grub_ata_to_cpu16 (grub_inw (dev->ioaddress
136 + GRUB_ATA_REG_DATA));
137 }
138
139 static void
140 grub_pata_pio_write (struct grub_pata_device *dev, char *buf, grub_size_t size)
141 {
142 unsigned int i;
143
144 /* Write the data, word by word. */
145 for (i = 0; i < size / 2; i++)
146 grub_outw(grub_cpu_to_ata16 (grub_get_unaligned16 (buf + 2 * i)), dev->ioaddress + GRUB_ATA_REG_DATA);
147 }
148
149 /* ATA pass through support, used by hdparm.mod. */
150 static grub_err_t
151 grub_pata_readwrite (struct grub_ata *disk,
152 struct grub_disk_ata_pass_through_parms *parms,
153 int spinup)
154 {
155 struct grub_pata_device *dev = (struct grub_pata_device *) disk->data;
156 grub_size_t nread = 0;
157 int i;
158
159 if (! (parms->cmdsize == 0 || parms->cmdsize == 12))
160 return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
161 "ATAPI non-12 byte commands not supported");
162
163 grub_dprintf ("pata", "pata_pass_through: cmd=0x%x, features=0x%x, sectors=0x%x\n",
164 parms->taskfile.cmd,
165 parms->taskfile.features,
166 parms->taskfile.sectors);
167 grub_dprintf ("pata", "lba_high=0x%x, lba_mid=0x%x, lba_low=0x%x, size=%"
168 PRIuGRUB_SIZE "\n",
169 parms->taskfile.lba_high,
170 parms->taskfile.lba_mid,
171 parms->taskfile.lba_low, parms->size);
172
173 /* Set registers. */
174 grub_pata_regset (dev, GRUB_ATA_REG_DISK, (dev->device << 4)
175 | (parms->taskfile.disk & 0xef));
176 if (grub_pata_check_ready (dev, spinup))
177 return grub_errno;
178
179 for (i = GRUB_ATA_REG_SECTORS; i <= GRUB_ATA_REG_LBAHIGH; i++)
180 grub_pata_regset (dev, i,
181 parms->taskfile.raw[7 + (i - GRUB_ATA_REG_SECTORS)]);
182 for (i = GRUB_ATA_REG_FEATURES; i <= GRUB_ATA_REG_LBAHIGH; i++)
183 grub_pata_regset (dev, i, parms->taskfile.raw[i - GRUB_ATA_REG_FEATURES]);
184
185 /* Start command. */
186 grub_pata_regset (dev, GRUB_ATA_REG_CMD, parms->taskfile.cmd);
187
188 /* Wait for !BSY. */
189 if (grub_pata_wait_not_busy (dev, GRUB_ATA_TOUT_DATA))
190 return grub_errno;
191
192 /* Check status. */
193 grub_int8_t sts = grub_pata_regget (dev, GRUB_ATA_REG_STATUS);
194 grub_dprintf ("pata", "status=0x%x\n", sts);
195
196 if (parms->cmdsize)
197 {
198 grub_uint8_t irs;
199 /* Wait for !BSY. */
200 if (grub_pata_wait_not_busy (dev, GRUB_ATA_TOUT_DATA))
201 return grub_errno;
202
203 irs = grub_pata_regget (dev, GRUB_ATAPI_REG_IREASON);
204 /* OK if DRQ is asserted and interrupt reason is as expected. */
205 if (!((sts & GRUB_ATA_STATUS_DRQ)
206 && (irs & GRUB_ATAPI_IREASON_MASK) == GRUB_ATAPI_IREASON_CMD_OUT))
207 return grub_error (GRUB_ERR_READ_ERROR, "ATAPI protocol error");
208 /* Write the packet. */
209 grub_pata_pio_write (dev, parms->cmd, parms->cmdsize);
210 }
211
212 /* Transfer data. */
213 while (nread < parms->size
214 && (sts & (GRUB_ATA_STATUS_DRQ | GRUB_ATA_STATUS_ERR))
215 == GRUB_ATA_STATUS_DRQ)
216 {
217 unsigned cnt;
218
219 /* Wait for !BSY. */
220 if (grub_pata_wait_not_busy (dev, GRUB_ATA_TOUT_DATA))
221 return grub_errno;
222
223 if (parms->cmdsize)
224 {
225 if ((grub_pata_regget (dev, GRUB_ATAPI_REG_IREASON)
226 & GRUB_ATAPI_IREASON_MASK) != GRUB_ATAPI_IREASON_DATA_IN)
227 return grub_error (GRUB_ERR_READ_ERROR, "ATAPI protocol error");
228
229 cnt = grub_pata_regget (dev, GRUB_ATAPI_REG_CNTHIGH) << 8
230 | grub_pata_regget (dev, GRUB_ATAPI_REG_CNTLOW);
231 grub_dprintf("pata", "DRQ count=%u\n", cnt);
232
233 /* Count of last transfer may be uneven. */
234 if (! (0 < cnt && cnt <= parms->size - nread
235 && (! (cnt & 1) || cnt == parms->size - nread)))
236 return grub_error (GRUB_ERR_READ_ERROR,
237 "invalid ATAPI transfer count");
238 }
239 else
240 cnt = GRUB_DISK_SECTOR_SIZE;
241 if (cnt > parms->size - nread)
242 cnt = parms->size - nread;
243
244 if (parms->write)
245 grub_pata_pio_write (dev, (char *) parms->buffer + nread, cnt);
246 else
247 grub_pata_pio_read (dev, (char *) parms->buffer + nread, cnt);
248
249 nread += cnt;
250 }
251 if (parms->write)
252 {
253 /* Check for write error. */
254 if (grub_pata_wait_not_busy (dev, GRUB_ATA_TOUT_DATA))
255 return grub_errno;
256
257 if (grub_pata_regget (dev, GRUB_ATA_REG_STATUS)
258 & (GRUB_ATA_STATUS_DRQ | GRUB_ATA_STATUS_ERR))
259 return grub_error (GRUB_ERR_WRITE_ERROR, "ATA write error");
260 }
261 parms->size = nread;
262
263 /* Wait for !BSY. */
264 if (grub_pata_wait_not_busy (dev, GRUB_ATA_TOUT_DATA))
265 return grub_errno;
266
267 /* Return registers. */
268 for (i = GRUB_ATA_REG_ERROR; i <= GRUB_ATA_REG_STATUS; i++)
269 parms->taskfile.raw[i - GRUB_ATA_REG_FEATURES] = grub_pata_regget (dev, i);
270
271 grub_dprintf ("pata", "status=0x%x, error=0x%x, sectors=0x%x\n",
272 parms->taskfile.status,
273 parms->taskfile.error,
274 parms->taskfile.sectors);
275
276 if (parms->taskfile.status
277 & (GRUB_ATA_STATUS_DRQ | GRUB_ATA_STATUS_ERR))
278 return grub_error (GRUB_ERR_READ_ERROR, "PATA passthrough failed");
279
280 return GRUB_ERR_NONE;
281 }
282
283 static grub_err_t
284 check_device (struct grub_pata_device *dev)
285 {
286 grub_pata_regset (dev, GRUB_ATA_REG_DISK, dev->device << 4);
287 grub_pata_wait ();
288
289 /* Try to detect if the port is in use by writing to it,
290 waiting for a while and reading it again. If the value
291 was preserved, there is a device connected. */
292 grub_pata_regset (dev, GRUB_ATA_REG_SECTORS, 0x5A);
293 grub_pata_wait ();
294 grub_uint8_t sec = grub_pata_regget (dev, GRUB_ATA_REG_SECTORS);
295 grub_dprintf ("ata", "sectors=0x%x\n", sec);
296 if (sec != 0x5A)
297 return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no device connected");
298
299 /* The above test may detect a second (slave) device
300 connected to a SATA controller which supports only one
301 (master) device. It is not safe to use the status register
302 READY bit to check for controller channel existence. Some
303 ATAPI commands (RESET, DIAGNOSTIC) may clear this bit. */
304
305 return GRUB_ERR_NONE;
306 }
307
308 static grub_err_t
309 grub_pata_device_initialize (int port, int device, int addr)
310 {
311 struct grub_pata_device *dev;
312 struct grub_pata_device **devp;
313 grub_err_t err;
314
315 grub_dprintf ("pata", "detecting device %d,%d (0x%x)\n",
316 port, device, addr);
317
318 dev = grub_malloc (sizeof(*dev));
319 if (! dev)
320 return grub_errno;
321
322 /* Setup the device information. */
323 dev->port = port;
324 dev->device = device;
325 dev->ioaddress = addr + GRUB_MACHINE_PCI_IO_BASE;
326 dev->present = 1;
327 dev->next = NULL;
328
329 /* Register the device. */
330 for (devp = &grub_pata_devices; *devp; devp = &(*devp)->next);
331 *devp = dev;
332
333 err = check_device (dev);
334 if (err)
335 grub_print_error ();
336
337 return 0;
338 }
339
340 #ifndef GRUB_MACHINE_MIPS_QEMU_MIPS
341 static int
342 grub_pata_pciinit (grub_pci_device_t dev,
343 grub_pci_id_t pciid,
344 void *data __attribute__ ((unused)))
345 {
346 static int compat_use[2] = { 0 };
347 grub_pci_address_t addr;
348 grub_uint32_t class;
349 grub_uint32_t bar1;
350 grub_uint32_t bar2;
351 int rega;
352 int i;
353 static int controller = 0;
354 int cs5536 = 0;
355 int nports = 2;
356
357 /* Read class. */
358 addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS);
359 class = grub_pci_read (addr);
360
361 /* AMD CS5536 Southbridge. */
362 if (pciid == GRUB_CS5536_PCIID)
363 {
364 cs5536 = 1;
365 nports = 1;
366 }
367
368 /* Check if this class ID matches that of a PCI IDE Controller. */
369 if (!cs5536 && (class >> 16 != 0x0101))
370 return 0;
371
372 for (i = 0; i < nports; i++)
373 {
374 /* Set to 0 when the channel operated in compatibility mode. */
375 int compat;
376
377 /* We don't support non-compatibility mode for CS5536. */
378 if (cs5536)
379 compat = 0;
380 else
381 compat = (class >> (8 + 2 * i)) & 1;
382
383 rega = 0;
384
385 /* If the channel is in compatibility mode, just assign the
386 default registers. */
387 if (compat == 0 && !compat_use[i])
388 {
389 rega = grub_pata_ioaddress[i];
390 compat_use[i] = 1;
391 }
392 else if (compat)
393 {
394 /* Read the BARs, which either contain a mmapped IO address
395 or the IO port address. */
396 addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESSES
397 + sizeof (grub_uint64_t) * i);
398 bar1 = grub_pci_read (addr);
399 addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESSES
400 + sizeof (grub_uint64_t) * i
401 + sizeof (grub_uint32_t));
402 bar2 = grub_pci_read (addr);
403
404 /* Check if the BARs describe an IO region. */
405 if ((bar1 & 1) && (bar2 & 1) && (bar1 & ~3))
406 {
407 rega = bar1 & ~3;
408 addr = grub_pci_make_address (dev, GRUB_PCI_REG_COMMAND);
409 grub_pci_write_word (addr, grub_pci_read_word (addr)
410 | GRUB_PCI_COMMAND_IO_ENABLED
411 | GRUB_PCI_COMMAND_MEM_ENABLED
412 | GRUB_PCI_COMMAND_BUS_MASTER);
413
414 }
415 }
416
417 grub_dprintf ("pata",
418 "PCI dev (%d,%d,%d) compat=%d rega=0x%x\n",
419 grub_pci_get_bus (dev), grub_pci_get_device (dev),
420 grub_pci_get_function (dev), compat, rega);
421
422 if (rega)
423 {
424 grub_errno = GRUB_ERR_NONE;
425 grub_pata_device_initialize (controller * 2 + i, 0, rega);
426
427 /* Most errors raised by grub_ata_device_initialize() are harmless.
428 They just indicate this particular drive is not responding, most
429 likely because it doesn't exist. We might want to ignore specific
430 error types here, instead of printing them. */
431 if (grub_errno)
432 {
433 grub_print_error ();
434 grub_errno = GRUB_ERR_NONE;
435 }
436
437 grub_pata_device_initialize (controller * 2 + i, 1, rega);
438
439 /* Likewise. */
440 if (grub_errno)
441 {
442 grub_print_error ();
443 grub_errno = GRUB_ERR_NONE;
444 }
445 }
446 }
447
448 controller++;
449
450 return 0;
451 }
452
453 static grub_err_t
454 grub_pata_initialize (void)
455 {
456 grub_pci_iterate (grub_pata_pciinit, NULL);
457 return 0;
458 }
459 #else
460 static grub_err_t
461 grub_pata_initialize (void)
462 {
463 int i;
464 for (i = 0; i < 2; i++)
465 {
466 grub_pata_device_initialize (i, 0, grub_pata_ioaddress[i]);
467 grub_pata_device_initialize (i, 1, grub_pata_ioaddress[i]);
468 }
469 return 0;
470 }
471 #endif
472
473 static grub_err_t
474 grub_pata_open (int id, int devnum, struct grub_ata *ata)
475 {
476 struct grub_pata_device *dev;
477 struct grub_pata_device *devfnd = 0;
478 grub_err_t err;
479
480 if (id != GRUB_SCSI_SUBSYSTEM_PATA)
481 return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a PATA device");
482
483 for (dev = grub_pata_devices; dev; dev = dev->next)
484 {
485 if (dev->port * 2 + dev->device == devnum)
486 {
487 devfnd = dev;
488 break;
489 }
490 }
491
492 grub_dprintf ("pata", "opening PATA dev `ata%d'\n", devnum);
493
494 if (! devfnd)
495 return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no such PATA device");
496
497 err = check_device (devfnd);
498 if (err)
499 return err;
500
501 ata->data = devfnd;
502 ata->dma = 0;
503 ata->maxbuffer = 256 * 512;
504 ata->present = &devfnd->present;
505
506 return GRUB_ERR_NONE;
507 }
508
509 static int
510 grub_pata_iterate (grub_ata_dev_iterate_hook_t hook, void *hook_data,
511 grub_disk_pull_t pull)
512 {
513 struct grub_pata_device *dev;
514
515 if (pull != GRUB_DISK_PULL_NONE)
516 return 0;
517
518 for (dev = grub_pata_devices; dev; dev = dev->next)
519 if (hook (GRUB_SCSI_SUBSYSTEM_PATA, dev->port * 2 + dev->device,
520 hook_data))
521 return 1;
522
523 return 0;
524 }
525
526
527 static struct grub_ata_dev grub_pata_dev =
528 {
529 .iterate = grub_pata_iterate,
530 .open = grub_pata_open,
531 .readwrite = grub_pata_readwrite,
532 };
533
534
535 \f
536
537 GRUB_MOD_INIT(ata_pthru)
538 {
539 grub_stop_disk_firmware ();
540
541 /* ATA initialization. */
542 grub_pata_initialize ();
543
544 grub_ata_dev_register (&grub_pata_dev);
545 }
546
547 GRUB_MOD_FINI(ata_pthru)
548 {
549 grub_ata_dev_unregister (&grub_pata_dev);
550 }