source: mainline/uspace/lib/ata/src/ata.c@ d231a54

Last change on this file since d231a54 was 0dab4850, checked in by Jiri Svoboda <jiri@…>, 5 months ago

Fix driver crash when ATA channel contains no usable devices.

  • Property mode set to 100644
File size: 42.0 KB
RevLine 
[2791fbb7]1/*
[a796812c]2 * Copyright (c) 2025 Jiri Svoboda
[2791fbb7]3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup libata
30 * @{
31 */
32
33/**
34 * @file
35 * @brief ATA disk driver library
36 *
37 * This driver library implements the generic part of ATA/ATAPI. It is
38 * meant to be used by a driver which implements the actual transport
39 * (such as ISA, PCI).
40 *
41 * This driver libary supports CHS, 28-bit and 48-bit LBA addressing,
42 * as well as PACKET devices. It supports PIO transfers and IRQ.
43 *
44 * There is no support DMA, S.M.A.R.T or removable devices.
45 *
46 * This driver is based on the ATA-1, ATA-2, ATA-3 and ATA/ATAPI-4 through 7
47 * standards, as published by the ANSI, NCITS and INCITS standards bodies,
48 * which are freely available. This driver contains no vendor-specific
49 * code at this moment.
50 */
51
52#include <bd_srv.h>
53#include <byteorder.h>
54#include <errno.h>
55#include <macros.h>
56#include <scsi/mmc.h>
57#include <scsi/sbc.h>
58#include <scsi/spc.h>
59#include <stdarg.h>
60#include <stdbool.h>
61#include <stddef.h>
62#include <stdint.h>
63#include <stdio.h>
64#include <stdlib.h>
65
66#include "ata/ata.h"
67#include "ata/ata_hw.h"
68
69#define MSG_BUF_SIZE 256
70
71/**
72 * Size of data returned from Identify Device or Identify Packet Device
73 * command.
74 */
75static const size_t identify_data_size = 512;
76static void ata_msg_note(ata_channel_t *, const char *, ...);
77static void ata_msg_debug(ata_channel_t *, const char *, ...);
78static void ata_msg_warn(ata_channel_t *, const char *, ...);
79static void ata_msg_error(ata_channel_t *, const char *, ...);
80static errno_t ata_device_add(ata_device_t *);
81static errno_t ata_device_remove(ata_device_t *);
82static void ata_read_data_16(ata_channel_t *, uint16_t *, size_t);
83static void ata_write_data_16(ata_channel_t *, uint16_t *, size_t);
84static uint8_t ata_read_cmd_8(ata_channel_t *, uint16_t);
85static void ata_write_cmd_8(ata_channel_t *, uint16_t, uint8_t);
86
87static errno_t ata_bd_init_irq(ata_channel_t *);
88static void ata_bd_fini_irq(ata_channel_t *);
89
90static errno_t ata_bd_open(bd_srvs_t *, bd_srv_t *);
91static errno_t ata_bd_close(bd_srv_t *);
92static errno_t ata_bd_read_blocks(bd_srv_t *, uint64_t, size_t, void *, size_t);
93static errno_t ata_bd_read_toc(bd_srv_t *, uint8_t, void *, size_t);
94static errno_t ata_bd_write_blocks(bd_srv_t *, uint64_t, size_t, const void *,
95 size_t);
96static errno_t ata_bd_get_block_size(bd_srv_t *, size_t *);
97static errno_t ata_bd_get_num_blocks(bd_srv_t *, aoff64_t *);
98static errno_t ata_bd_sync_cache(bd_srv_t *, aoff64_t, size_t);
99
100static errno_t ata_rcmd_read(ata_device_t *, uint64_t, size_t, void *);
101static errno_t ata_rcmd_write(ata_device_t *, uint64_t, size_t,
102 const void *);
103static errno_t ata_rcmd_flush_cache(ata_device_t *);
104static errno_t ata_device_init(ata_channel_t *, ata_device_t *, int);
105static errno_t ata_identify_dev(ata_device_t *, void *);
106static errno_t ata_identify_pkt_dev(ata_device_t *, void *);
107static errno_t ata_cmd_packet(ata_device_t *, const void *, size_t, void *,
108 size_t, size_t *);
109static errno_t ata_pcmd_inquiry(ata_device_t *, void *, size_t, size_t *);
110static errno_t ata_pcmd_read_12(ata_device_t *, uint64_t, size_t, void *, size_t);
111static errno_t ata_pcmd_read_capacity(ata_device_t *, uint64_t *, size_t *);
112static errno_t ata_pcmd_read_toc(ata_device_t *, uint8_t, void *, size_t);
113static void disk_print_summary(ata_device_t *);
114static size_t ata_disk_maxnb(ata_device_t *);
115static errno_t coord_calc(ata_device_t *, uint64_t, block_coord_t *);
116static void coord_sc_program(ata_channel_t *, const block_coord_t *, uint16_t);
117static errno_t wait_status(ata_channel_t *, unsigned, unsigned, uint8_t *,
118 unsigned);
119static errno_t wait_irq(ata_channel_t *, uint8_t *, unsigned);
[645d3832]120static void ata_dma_chan_setup(ata_device_t *, void *, size_t, ata_dma_dir_t);
121static void ata_dma_chan_teardown(ata_device_t *);
[2791fbb7]122
123static bd_ops_t ata_bd_ops = {
124 .open = ata_bd_open,
125 .close = ata_bd_close,
126 .read_blocks = ata_bd_read_blocks,
127 .read_toc = ata_bd_read_toc,
128 .write_blocks = ata_bd_write_blocks,
129 .get_block_size = ata_bd_get_block_size,
130 .get_num_blocks = ata_bd_get_num_blocks,
131 .sync_cache = ata_bd_sync_cache
132};
133
134static ata_device_t *bd_srv_device(bd_srv_t *bd)
135{
136 return (ata_device_t *)bd->srvs->sarg;
137}
138
139static int disk_dev_idx(ata_device_t *device)
140{
141 return (device->device_id & 1);
142}
143
144/** Create ATA channel.
145 *
146 * @param params Channel creation parameters
147 * @param rchan Place to store pointer to new channel
148 * @return EOK on success or an error code
149 */
150errno_t ata_channel_create(ata_params_t *params, ata_channel_t **rchan)
151{
152 ata_channel_t *chan;
[145d4e2e]153 int i;
[2791fbb7]154
155 chan = calloc(1, sizeof(ata_channel_t));
156 if (chan == NULL)
157 return ENOMEM;
158
159 chan->params = *params;
160 ata_msg_debug(chan, "ata_channel_create()");
161
162 fibril_mutex_initialize(&chan->lock);
163 fibril_mutex_initialize(&chan->irq_lock);
164 fibril_condvar_initialize(&chan->irq_cv);
165
[145d4e2e]166 for (i = 0; i < MAX_DEVICES; i++)
167 chan->device[i].chan = chan;
168
[2791fbb7]169 *rchan = chan;
170 return EOK;
171}
172
173/** Initialize ATA channel.
174 *
175 * @param params Channel creation parameters
176 * @param rchan Place to store pointer to new channel
177 * @return EOK on success or an error code
178 */
179errno_t ata_channel_initialize(ata_channel_t *chan)
180{
181 int i;
182 errno_t rc;
183 int n_disks;
184 bool irq_inited = false;
[743f2cdd]185 bool dev_added[MAX_DEVICES];
186
187 for (i = 0; i < MAX_DEVICES; i++)
188 dev_added[i] = false;
[2791fbb7]189
190 ata_msg_debug(chan, "ata_channel_initialize()");
191
192 rc = ata_bd_init_irq(chan);
193 if (rc != EOK)
194 return rc;
195
196 irq_inited = true;
197
198 for (i = 0; i < MAX_DEVICES; i++) {
199 ata_msg_debug(chan, "Identify drive %d...", i);
200
201 rc = ata_device_init(chan, &chan->device[i], i);
202
203 if (rc == EOK) {
204 disk_print_summary(&chan->device[i]);
205 } else {
206 ata_msg_debug(chan, "Not found.");
207 }
208 }
209
210 n_disks = 0;
211
212 for (i = 0; i < MAX_DEVICES; i++) {
213 /* Skip unattached devices. */
214 if (chan->device[i].present == false)
215 continue;
216
217 rc = ata_device_add(&chan->device[i]);
218 if (rc != EOK) {
219 ata_msg_error(chan, "Unable to add device %d.", i);
220 goto error;
221 }
[743f2cdd]222 dev_added[i] = true;
[2791fbb7]223 ++n_disks;
224 }
225
226 if (n_disks == 0) {
227 ata_msg_warn(chan, "No devices detected.");
228 rc = ENOENT;
229 goto error;
230 }
231
232 return EOK;
233error:
234 for (i = 0; i < MAX_DEVICES; i++) {
[743f2cdd]235 if (dev_added[i]) {
236 rc = ata_device_remove(&chan->device[i]);
237 if (rc != EOK) {
238 ata_msg_error(chan,
239 "Unable to remove device %d.", i);
240 }
[2791fbb7]241 }
242 }
243 if (irq_inited)
244 ata_bd_fini_irq(chan);
245 return rc;
246}
247
248/** Destroy ATA channel. */
249errno_t ata_channel_destroy(ata_channel_t *chan)
250{
251 int i;
252 errno_t rc;
253
254 ata_msg_debug(chan, ": ata_channel_destroy()");
255
256 fibril_mutex_lock(&chan->lock);
257
258 for (i = 0; i < MAX_DEVICES; i++) {
[0dab4850]259 if (chan->device[i].present == false)
260 continue;
261
[2791fbb7]262 rc = ata_device_remove(&chan->device[i]);
263 if (rc != EOK) {
264 ata_msg_error(chan, "Unable to remove device %d.", i);
[b8fd951]265 fibril_mutex_unlock(&chan->lock);
266 return rc;
[2791fbb7]267 }
268 }
269
270 ata_bd_fini_irq(chan);
271 fibril_mutex_unlock(&chan->lock);
[b8fd951]272 free(chan);
[2791fbb7]273
[3d2d455b]274 return rc;
[2791fbb7]275}
276
277/** Add ATA device.
278 *
279 * @param d Device
280 * @return EOK on success or an error code
281 */
282static errno_t ata_device_add(ata_device_t *d)
283{
284 bd_srvs_init(&d->bds);
285 d->bds.ops = &ata_bd_ops;
286 d->bds.sarg = (void *)d;
287
288 return d->chan->params.add_device(d->chan->params.arg, d->device_id,
289 (void *)d);
290}
291
292/** Remove ATA device.
293 *
294 * @param d Device
295 * @return EOK on success or an error code
296 */
297static errno_t ata_device_remove(ata_device_t *d)
298{
299 return d->chan->params.remove_device(d->chan->params.arg, d->device_id);
300}
301
302/** Read 16 bits from data port.
303 *
304 * @param chan ATA channel
305 * @param buf Buffer to hold data
306 * @param nwords Number of words to read
307 */
308static void ata_read_data_16(ata_channel_t *chan, uint16_t *buf,
309 size_t nwords)
310{
311 chan->params.read_data_16(chan->params.arg, buf, nwords);
312}
313
314/** Write 16 bits to data port.
315 *
316 * @param chan ATA channel
317 * @param data Data
318 * @param nwords Number of words to write
319 */
320static void ata_write_data_16(ata_channel_t *chan, uint16_t *data,
321 size_t nwords)
322{
323 chan->params.write_data_16(chan->params.arg, data, nwords);
324}
325
326/** Read 8 bits from 8-bit command port.
327 *
328 * @param chan ATA channel
329 * @param port Port number
330 * @return 8-bit register value
331 */
332static uint8_t ata_read_cmd_8(ata_channel_t *chan, uint16_t port)
333{
334 return chan->params.read_cmd_8(chan->params.arg, port);
335}
336
337/** Write 8 bits to 8-bit command port.
338 *
339 * @param chan ATA channel
340 * @param port Port number
341 * @param value Register value
342 */
343static void ata_write_cmd_8(ata_channel_t *chan, uint16_t port, uint8_t value)
344{
345 return chan->params.write_cmd_8(chan->params.arg, port, value);
346}
347
348/** Log a notice message.
349 *
350 * @param chan Channel
351 * @param fmt Format
352 */
353static void ata_msg_note(ata_channel_t *chan, const char *fmt, ...)
354{
355 va_list ap;
356 char buf[MSG_BUF_SIZE];
357
358 va_start(ap, fmt);
359 vsnprintf(buf, sizeof(buf), fmt, ap);
360 va_end(ap);
361
362 chan->params.msg_note(chan->params.arg, buf);
363}
364
365/** Log a debug message.
366 *
367 * @param chan Channel
368 * @param fmt Format
369 */
370static void ata_msg_debug(ata_channel_t *chan, const char *fmt, ...)
371{
372 va_list ap;
373 char buf[MSG_BUF_SIZE];
374
375 va_start(ap, fmt);
376 vsnprintf(buf, sizeof(buf), fmt, ap);
377 va_end(ap);
378
379 chan->params.msg_debug(chan->params.arg, buf);
380}
381
382/** Log a warning message.
383 *
384 * @param chan Channel
385 * @param fmt Format
386 */
387static void ata_msg_warn(ata_channel_t *chan, const char *fmt, ...)
388{
389 va_list ap;
390 char buf[MSG_BUF_SIZE];
391
392 va_start(ap, fmt);
393 vsnprintf(buf, sizeof(buf), fmt, ap);
394 va_end(ap);
395
396 chan->params.msg_warn(chan->params.arg, buf);
397}
398
399/** Log an error message.
400 *
401 * @param chan Channel
402 * @param fmt Format
403 */
404static void ata_msg_error(ata_channel_t *chan, const char *fmt, ...)
405{
406 va_list ap;
407 char buf[MSG_BUF_SIZE];
408
409 va_start(ap, fmt);
410 vsnprintf(buf, sizeof(buf), fmt, ap);
411 va_end(ap);
412
413 chan->params.msg_error(chan->params.arg, buf);
414}
415
416/** Print one-line device summary. */
417static void disk_print_summary(ata_device_t *d)
418{
419 uint64_t mbytes;
420 char *atype = NULL;
421 char *cap = NULL;
422 int rc;
423
424 if (d->dev_type == ata_reg_dev) {
425 switch (d->amode) {
426 case am_chs:
427 rc = asprintf(&atype, "CHS %u cylinders, %u heads, "
428 "%u sectors", d->geom.cylinders, d->geom.heads,
429 d->geom.sectors);
430 if (rc < 0) {
431 /* Out of memory */
432 atype = NULL;
433 }
434 break;
435 case am_lba28:
436 atype = str_dup("LBA-28");
437 break;
438 case am_lba48:
439 atype = str_dup("LBA-48");
440 break;
441 }
442 } else {
443 atype = str_dup("PACKET");
444 }
445
446 if (atype == NULL)
447 return;
448
449 mbytes = d->blocks / (2 * 1024);
450 if (mbytes > 0) {
451 rc = asprintf(&cap, " %" PRIu64 " MB.", mbytes);
452 if (rc < 0) {
453 cap = NULL;
454 goto cleanup;
455 }
456 }
457
458 ata_msg_note(d->chan, "%s: %s %" PRIu64 " blocks%s", d->model, atype,
459 d->blocks, cap);
460cleanup:
461 free(atype);
462 free(cap);
463}
464
465/** Initialize IRQ. */
466static errno_t ata_bd_init_irq(ata_channel_t *chan)
467{
[646849b3]468 if (!chan->params.have_irq)
469 return EOK;
470
[2791fbb7]471 return chan->params.irq_enable(chan->params.arg);
472}
473
474/** Clean up IRQ. */
475static void ata_bd_fini_irq(ata_channel_t *chan)
476{
[646849b3]477 if (!chan->params.have_irq)
478 return;
479
[2791fbb7]480 (void)chan->params.irq_disable(chan->params.arg);
481}
482
483/** Initialize a device.
484 *
485 * Probes for a device, determines its parameters and initializes
486 * the device structure.
487 */
488static errno_t ata_device_init(ata_channel_t *chan, ata_device_t *d,
489 int device_id)
490{
491 identify_data_t idata;
492 uint8_t model[40];
493 scsi_std_inquiry_data_t inq_data;
494 size_t isize;
495 uint16_t w;
496 uint8_t c;
497 uint16_t bc;
498 uint64_t nblocks;
499 size_t block_size;
500 size_t pos, len;
501 errno_t rc;
502 unsigned i;
503
504 d->device_id = device_id;
505 d->present = false;
506
507 /* Try identify command. */
508 rc = ata_identify_dev(d, &idata);
509 if (rc == EOK) {
510 /* Success. It's a register (non-packet) device. */
511 ata_msg_debug(chan, "ATA register-only device found.");
512 d->dev_type = ata_reg_dev;
513 } else if (rc == EIO) {
514 /*
515 * There is something, but not a register device. Check to see
516 * whether the IDENTIFY command left the packet signature in
517 * the registers in case this is a packet device.
518 *
519 * According to the ATA specification, the LBA low and
520 * interrupt reason registers should be set to 0x01. However,
521 * there are many devices that do not follow this and only set
522 * the byte count registers. So, only check these.
523 */
524 bc = ((uint16_t)ata_read_cmd_8(chan, REG_CYLINDER_HIGH) << 8) |
525 ata_read_cmd_8(chan, REG_CYLINDER_LOW);
526
527 if (bc == PDEV_SIGNATURE_BC) {
528 rc = ata_identify_pkt_dev(d, &idata);
529 if (rc == EOK) {
530 /* We have a packet device. */
531 d->dev_type = ata_pkt_dev;
532 } else {
533 return EIO;
534 }
535 } else {
536 /* Nope. Something's there, but not recognized. */
537 return EIO;
538 }
539 } else {
540 /* Operation timed out. That means there is no device there. */
541 return EIO;
542 }
543
544 if (d->dev_type == ata_pkt_dev) {
545 /* Packet device */
546 d->amode = 0;
547
548 d->geom.cylinders = 0;
549 d->geom.heads = 0;
550 d->geom.sectors = 0;
551
552 d->blocks = 0;
553 } else if ((idata.caps & rd_cap_lba) == 0) {
554 /* Device only supports CHS addressing. */
555 d->amode = am_chs;
556
557 d->geom.cylinders = idata.cylinders;
558 d->geom.heads = idata.heads;
559 d->geom.sectors = idata.sectors;
560
561 d->blocks = d->geom.cylinders * d->geom.heads * d->geom.sectors;
562 } else if ((idata.cmd_set1 & cs1_addr48) == 0) {
563 /* Device only supports LBA-28 addressing. */
564 d->amode = am_lba28;
565
566 d->geom.cylinders = 0;
567 d->geom.heads = 0;
568 d->geom.sectors = 0;
569
570 d->blocks =
571 (uint32_t) idata.total_lba28_0 |
572 ((uint32_t) idata.total_lba28_1 << 16);
573 } else {
574 /* Device supports LBA-48 addressing. */
575 d->amode = am_lba48;
576
577 d->geom.cylinders = 0;
578 d->geom.heads = 0;
579 d->geom.sectors = 0;
580
581 d->blocks =
582 (uint64_t) idata.total_lba48_0 |
583 ((uint64_t) idata.total_lba48_1 << 16) |
584 ((uint64_t) idata.total_lba48_2 << 32) |
585 ((uint64_t) idata.total_lba48_3 << 48);
586 }
587
588 /*
589 * Convert model name to string representation.
590 */
591 for (i = 0; i < 20; i++) {
592 w = idata.model_name[i];
593 model[2 * i] = w >> 8;
594 model[2 * i + 1] = w & 0x00ff;
595 }
596
597 len = 40;
598 while (len > 0 && model[len - 1] == 0x20)
599 --len;
600
601 pos = 0;
602 for (i = 0; i < len; ++i) {
603 c = model[i];
604 if (c >= 0x80)
605 c = '?';
606
607 chr_encode(c, d->model, &pos, 40);
608 }
609 d->model[pos] = '\0';
610
611 if (d->dev_type == ata_pkt_dev) {
612 /* Send inquiry. */
613 rc = ata_pcmd_inquiry(d, &inq_data, sizeof(inq_data), &isize);
614 if (rc != EOK || isize < sizeof(inq_data)) {
615 ata_msg_error(chan, "Device inquiry failed.");
616 d->present = false;
617 return EIO;
618 }
619
620 /* Check device type. */
621 if (INQUIRY_PDEV_TYPE(inq_data.pqual_devtype) != SCSI_DEV_CD_DVD)
622 ata_msg_warn(chan, "Peripheral device type is not CD-ROM.");
623
624 rc = ata_pcmd_read_capacity(d, &nblocks, &block_size);
625 if (rc != EOK) {
626 ata_msg_error(chan, "Read capacity command failed.");
627 d->present = false;
628 return EIO;
629 }
630
631 d->blocks = nblocks;
632 d->block_size = block_size;
633 } else {
634 /* Assume register Read always uses 512-byte blocks. */
635 d->block_size = 512;
636 }
637
638 d->present = true;
639 return EOK;
640}
641
642static errno_t ata_bd_open(bd_srvs_t *bds, bd_srv_t *bd)
643{
644 return EOK;
645}
646
647static errno_t ata_bd_close(bd_srv_t *bd)
648{
649 return EOK;
650}
651
652/** Read multiple blocks from the device. */
653static errno_t ata_bd_read_blocks(bd_srv_t *bd, uint64_t ba, size_t cnt,
654 void *buf, size_t size)
655{
656 ata_device_t *device = bd_srv_device(bd);
657 size_t maxnb;
658 size_t nb;
659 errno_t rc;
660
661 if (size < cnt * device->block_size) {
662 rc = EINVAL;
663 goto error;
664 }
665
666 /* Maximum number of blocks to transfer at the same time */
667 maxnb = ata_disk_maxnb(device);
668 while (cnt > 0) {
669 nb = min(maxnb, cnt);
670 if (device->dev_type == ata_reg_dev) {
671 rc = ata_rcmd_read(device, ba, nb, buf);
672 } else {
673 rc = ata_pcmd_read_12(device, ba, nb, buf,
674 device->block_size);
675 }
676
677 if (rc != EOK)
678 goto error;
679
680 ba += nb;
681 cnt -= nb;
682 buf += device->block_size * nb;
683 }
684
685 return EOK;
686error:
687 ata_msg_debug(device->chan, "ata_bd_read_blocks: rc=%d", rc);
688 return rc;
689}
690
691/** Read TOC from device. */
692static errno_t ata_bd_read_toc(bd_srv_t *bd, uint8_t session, void *buf, size_t size)
693{
694 ata_device_t *device = bd_srv_device(bd);
695
696 return ata_pcmd_read_toc(device, session, buf, size);
697}
698
699/** Write multiple blocks to the device. */
700static errno_t ata_bd_write_blocks(bd_srv_t *bd, uint64_t ba, size_t cnt,
701 const void *buf, size_t size)
702{
703 ata_device_t *device = bd_srv_device(bd);
704 size_t maxnb;
705 size_t nb;
706 errno_t rc;
707
708 if (device->dev_type != ata_reg_dev)
709 return ENOTSUP;
710
711 if (size < cnt * device->block_size)
712 return EINVAL;
713
714 /* Maximum number of blocks to transfer at the same time */
715 maxnb = ata_disk_maxnb(device);
716 while (cnt > 0) {
717 nb = min(maxnb, cnt);
718 rc = ata_rcmd_write(device, ba, nb, buf);
719 if (rc != EOK)
720 return rc;
721
722 ba += nb;
723 cnt -= nb;
724 buf += device->block_size * nb;
725 }
726
727 return EOK;
728}
729
730/** Get device block size. */
731static errno_t ata_bd_get_block_size(bd_srv_t *bd, size_t *rbsize)
732{
733 ata_device_t *device = bd_srv_device(bd);
734
735 *rbsize = device->block_size;
736 return EOK;
737}
738
739/** Get device number of blocks. */
740static errno_t ata_bd_get_num_blocks(bd_srv_t *bd, aoff64_t *rnb)
741{
742 ata_device_t *device = bd_srv_device(bd);
743
744 *rnb = device->blocks;
745 return EOK;
746}
747
748/** Flush cache. */
749static errno_t ata_bd_sync_cache(bd_srv_t *bd, uint64_t ba, size_t cnt)
750{
751 ata_device_t *device = bd_srv_device(bd);
752
753 /* ATA cannot flush just some blocks, we just flush everything. */
754 (void)ba;
755 (void)cnt;
756
757 return ata_rcmd_flush_cache(device);
758}
759
760/** PIO data-in command protocol. */
761static errno_t ata_pio_data_in(ata_device_t *device, void *obuf, size_t obuf_size,
762 size_t blk_size, size_t nblocks)
763{
764 ata_channel_t *chan = device->chan;
765 uint8_t status;
766 errno_t rc;
767
768 assert(nblocks > 0);
769 assert(blk_size % 2 == 0);
770
771 while (nblocks > 0) {
772 if (chan->params.have_irq)
773 rc = wait_irq(chan, &status, TIMEOUT_BSY);
774 else
775 rc = wait_status(chan, 0, ~SR_BSY, &status, TIMEOUT_BSY);
776
777 if (rc != EOK) {
778 ata_msg_debug(chan, "wait_irq/wait_status failed");
779 return EIO;
780 }
781
782 if ((status & SR_DRQ) == 0) {
783 ata_msg_debug(chan, "DRQ == 0");
784 break;
785 }
786
787 /* Read data from the device buffer. */
788 ata_read_data_16(chan, (uint16_t *)obuf, blk_size / 2);
789 obuf += blk_size;
790
791 --nblocks;
792 }
793
794 if ((status & SR_ERR) != 0) {
795 ata_msg_debug(chan, "status & SR_ERR != 0");
796 return EIO;
797 }
798 if (nblocks > 0) {
799 ata_msg_debug(chan, "remaining nblocks = %zu", nblocks);
800 return EIO;
801 }
802
803 return EOK;
804}
805
806/** PIO data-out command protocol. */
807static errno_t ata_pio_data_out(ata_device_t *device, const void *buf, size_t buf_size,
808 size_t blk_size, size_t nblocks)
809{
810 ata_channel_t *chan = device->chan;
811 uint8_t status;
812 errno_t rc;
813
814 assert(nblocks > 0);
815 assert(blk_size % 2 == 0);
816
817 rc = wait_status(chan, 0, ~SR_BSY, &status, TIMEOUT_BSY);
818 if (rc != EOK)
819 return EIO;
820
821 while (nblocks > 0) {
822 if ((status & SR_DRQ) == 0) {
823 ata_msg_debug(chan, "pio_data_out: unexpected DRQ=0");
824 break;
825 }
826
827 /* Write data to the device buffer. */
828 ata_write_data_16(chan, (uint16_t *)buf, blk_size / 2);
829 buf += blk_size;
830
831 if (chan->params.have_irq)
832 rc = wait_irq(chan, &status, TIMEOUT_BSY);
833 else
834 rc = wait_status(chan, 0, ~SR_BSY, &status, TIMEOUT_BSY);
835 if (rc != EOK)
836 return EIO;
837
838 --nblocks;
839 }
840
841 if (status & SR_ERR)
842 return EIO;
843 if (nblocks > 0)
844 return EIO;
845
846 return EOK;
847}
848
849/** PIO non-data command protocol. */
850static errno_t ata_pio_nondata(ata_device_t *device)
851{
852 ata_channel_t *chan = device->chan;
853 uint8_t status;
854 errno_t rc;
855
856 if (chan->params.have_irq)
857 rc = wait_irq(chan, &status, TIMEOUT_BSY);
858 else
859 rc = wait_status(chan, 0, ~SR_BSY, &status, TIMEOUT_BSY);
860
861 if (rc != EOK)
862 return EIO;
863
864 if (status & SR_ERR)
865 return EIO;
866
867 return EOK;
868}
869
[645d3832]870/** DMA command protocol.
871 *
872 * @param device ATA device
873 * @param cmd Command code
874 * @param buf Data buffer
875 * @param buf_size Data buffer size in bytes
876 * @param dir DMA direction
877 *
878 * @return EOK on success or an error code
879 */
880static errno_t ata_dma_proto(ata_device_t *device, uint8_t cmd, void *buf,
881 size_t buf_size, ata_dma_dir_t dir)
882{
883 ata_channel_t *chan = device->chan;
884 uint8_t status;
885 errno_t rc;
886
887 /* Set up DMA channel */
888 ata_dma_chan_setup(device, buf, buf_size, dir);
889
890 ata_write_cmd_8(chan, REG_COMMAND, cmd);
891
892 if (chan->params.have_irq)
893 rc = wait_irq(chan, &status, TIMEOUT_BSY);
894 else
895 rc = wait_status(chan, 0, ~SR_BSY, &status, TIMEOUT_BSY);
896
[9739b5a]897 /* Tear down DMA channel */
898 ata_dma_chan_teardown(device);
899
[645d3832]900 if (rc != EOK) {
901 ata_msg_debug(chan, "wait_irq/wait_status failed");
902 return EIO;
903 }
904
905 if ((status & SR_ERR) != 0) {
906 ata_msg_debug(chan, "status & SR_ERR != 0");
907 return EIO;
908 }
909
910 return EOK;
911}
912
[2791fbb7]913/** Issue IDENTIFY DEVICE command.
914 *
915 * Reads @c identify data into the provided buffer. This is used to detect
916 * whether an ATA device is present and if so, to determine its parameters.
917 *
918 * @param device Device
919 * @param buf Pointer to a 512-byte buffer.
920 *
921 * @return ETIMEOUT on timeout (this can mean the device is
922 * not present). EIO if device responds with error.
923 */
924static errno_t ata_identify_dev(ata_device_t *device, void *buf)
925{
926 ata_channel_t *chan = device->chan;
927 uint8_t status;
928 uint8_t drv_head;
929
930 drv_head = ((disk_dev_idx(device) != 0) ? DHR_DRV : 0);
931
932 if (wait_status(chan, 0, ~SR_BSY, NULL, TIMEOUT_PROBE) != EOK)
933 return ETIMEOUT;
934
935 ata_write_cmd_8(chan, REG_DRIVE_HEAD, drv_head);
936
937 /*
938 * Do not wait for DRDY to be set in case this is a packet device.
939 * We determine whether the device is present by waiting for DRQ to be
940 * set after issuing the command.
941 */
942 if (wait_status(chan, 0, ~SR_BSY, NULL, TIMEOUT_PROBE) != EOK)
943 return ETIMEOUT;
944
945 ata_write_cmd_8(chan, REG_COMMAND, CMD_IDENTIFY_DRIVE);
946
947 /*
948 * For probing purposes we need to wait for some status bit to become
949 * active - otherwise we could be fooled just by receiving all zeroes.
950 */
951 if (wait_status(chan, SR_DRQ, ~SR_BSY, &status, TIMEOUT_PROBE) != EOK) {
952 if ((status & SR_ERR) == 0) {
953 /* Probably no device at all */
954 return ETIMEOUT;
955 }
956 }
957
958 return ata_pio_data_in(device, buf, identify_data_size,
959 identify_data_size, 1);
960}
961
962/** Issue Identify Packet Device command.
963 *
964 * Reads @c identify data into the provided buffer. This is used to detect
965 * whether an ATAPI device is present and if so, to determine its parameters.
966 *
967 * @param device Device
968 * @param buf Pointer to a 512-byte buffer.
969 */
970static errno_t ata_identify_pkt_dev(ata_device_t *device, void *buf)
971{
972 ata_channel_t *chan = device->chan;
973 uint8_t drv_head;
974
975 drv_head = ((disk_dev_idx(device) != 0) ? DHR_DRV : 0);
976
977 if (wait_status(chan, 0, ~SR_BSY, NULL, TIMEOUT_PROBE) != EOK)
978 return EIO;
979
980 ata_write_cmd_8(chan, REG_DRIVE_HEAD, drv_head);
981
982 /* For ATAPI commands we do not need to wait for DRDY. */
983 if (wait_status(chan, 0, ~SR_BSY, NULL, TIMEOUT_PROBE) != EOK)
984 return EIO;
985
986 ata_write_cmd_8(chan, REG_COMMAND, CMD_IDENTIFY_PKT_DEV);
987
988 return ata_pio_data_in(device, buf, identify_data_size,
989 identify_data_size, 1);
990}
991
[9739b5a]992/** Read data using PIO during a PACKET command.
993 *
994 * @param device Device
995 * @param obuf Output buffer
996 * @param obuf_size Output buffer size
997 * @param rcvd_size Place to store number of bytes actually transferred
998 * or @c NULL
999 */
1000static errno_t ata_packet_pio_data_in(ata_device_t *device, void *obuf,
1001 size_t obuf_size, size_t *rcvd_size)
1002{
1003 ata_channel_t *chan = device->chan;
1004 size_t data_size;
1005 size_t remain;
1006 uint8_t status;
1007 errno_t rc;
1008
1009 remain = obuf_size;
1010 while (remain > 0) {
1011 if (chan->params.have_irq)
1012 rc = wait_irq(chan, &status, TIMEOUT_BSY);
1013 else
1014 rc = wait_status(chan, 0, ~SR_BSY, &status, TIMEOUT_BSY);
1015
1016 if (rc != EOK) {
1017 fibril_mutex_unlock(&chan->lock);
1018 return EIO;
1019 }
1020
1021 if ((status & SR_DRQ) == 0)
1022 break;
1023
1024 /* Read byte count. */
1025 data_size = (uint16_t) ata_read_cmd_8(chan, REG_CYLINDER_LOW) +
1026 ((uint16_t) ata_read_cmd_8(chan, REG_CYLINDER_HIGH) << 8);
1027
1028 /* Check whether data fits into output buffer. */
1029 if (data_size > obuf_size) {
1030 /* Output buffer is too small to store data. */
1031 fibril_mutex_unlock(&chan->lock);
1032 return EIO;
1033 }
1034
1035 /* Read data from the device buffer. */
1036 ata_read_data_16(chan, obuf, (data_size + 1) / 2);
1037 obuf += data_size;
1038
1039 remain -= data_size;
1040 }
1041
1042 if (chan->params.have_irq)
1043 rc = wait_irq(chan, &status, TIMEOUT_BSY);
1044 else
1045 rc = wait_status(chan, 0, ~SR_BSY, &status, TIMEOUT_BSY);
1046
1047 if (status & SR_ERR)
1048 return EIO;
1049
1050 if (rcvd_size != NULL)
1051 *rcvd_size = obuf_size - remain;
1052
1053 return EOK;
1054}
1055
[c4ed9fa]1056/** Transfer data using DMA during PACKET command.
1057 *
1058 * @param device Device
1059 * @param buf Buffer
1060 * @param buf_size Buffer size
1061 * @param dir DMA direction
1062 *
1063 * @return EOK on success or an error code
1064 */
[9739b5a]1065static errno_t ata_packet_dma(ata_device_t *device, void *buf, size_t buf_size,
1066 ata_dma_dir_t dir)
1067{
1068 ata_channel_t *chan = device->chan;
1069 uint8_t status;
1070 errno_t rc;
1071
1072 if (chan->params.have_irq)
1073 rc = wait_irq(chan, &status, TIMEOUT_BSY);
1074 else
1075 rc = wait_status(chan, 0, ~SR_BSY, &status, TIMEOUT_BSY);
1076
1077 if (rc != EOK) {
1078 ata_msg_debug(chan, "wait_irq/wait_status failed");
1079 return EIO;
1080 }
1081
1082 if ((status & SR_ERR) != 0) {
1083 ata_msg_debug(chan, "status & SR_ERR != 0");
1084 return EIO;
1085 }
1086
1087 return EOK;
1088}
1089
[2791fbb7]1090/** Issue packet command (i. e. write a command packet to the device).
1091 *
1092 * Only data-in commands are supported (e.g. inquiry, read).
1093 *
1094 * @param device Device
1095 * @param obuf Buffer for storing data read from device
1096 * @param obuf_size Size of obuf in bytes
1097 * @param rcvd_size Place to store number of bytes read or @c NULL
1098 *
1099 * @return EOK on success, EIO on error.
1100 */
1101static errno_t ata_cmd_packet(ata_device_t *device, const void *cpkt, size_t cpkt_size,
1102 void *obuf, size_t obuf_size, size_t *rcvd_size)
1103{
1104 ata_channel_t *chan = device->chan;
1105 uint8_t status;
1106 uint8_t drv_head;
1107 errno_t rc;
1108
1109 fibril_mutex_lock(&chan->lock);
1110
1111 /* New value for Drive/Head register */
1112 drv_head =
1113 ((disk_dev_idx(device) != 0) ? DHR_DRV : 0);
1114
1115 if (wait_status(chan, 0, ~SR_BSY, NULL, TIMEOUT_PROBE) != EOK) {
1116 fibril_mutex_unlock(&chan->lock);
1117 return EIO;
1118 }
1119
1120 ata_write_cmd_8(chan, REG_DRIVE_HEAD, drv_head);
1121
1122 if (wait_status(chan, 0, ~(SR_BSY | SR_DRQ), NULL, TIMEOUT_BSY) != EOK) {
1123 fibril_mutex_unlock(&chan->lock);
1124 return EIO;
1125 }
1126
[9739b5a]1127 if (chan->params.use_dma) {
1128 /* Set up DMA channel */
1129 ata_dma_chan_setup(device, obuf, obuf_size, ata_dma_read);
1130 ata_write_cmd_8(chan, REG_FEATURES, 0x01); // XXX
1131 } else {
1132 /*
1133 * Byte count <- max. number of bytes we can read in one
1134 * PIO transfer.
1135 */
1136 ata_write_cmd_8(chan, REG_CYLINDER_LOW, 0xfe);
1137 ata_write_cmd_8(chan, REG_CYLINDER_HIGH, 0xff);
1138 }
[2791fbb7]1139
1140 ata_write_cmd_8(chan, REG_COMMAND, CMD_PACKET);
1141
1142 if (wait_status(chan, SR_DRQ, ~SR_BSY, &status, TIMEOUT_BSY) != EOK) {
[9739b5a]1143 if (chan->params.use_dma)
1144 ata_dma_chan_teardown(device);
[2791fbb7]1145 fibril_mutex_unlock(&chan->lock);
1146 return EIO;
1147 }
1148
1149 /* Write command packet. */
1150 ata_write_data_16(chan, ((uint16_t *) cpkt), (cpkt_size + 1) / 2);
1151
[9739b5a]1152 if (chan->params.use_dma) {
1153 /* Read data using DMA */
1154 rc = ata_packet_dma(device, obuf, obuf_size, ata_dma_read);
1155 if (rc == EOK && rcvd_size != NULL)
1156 *rcvd_size = obuf_size;
1157 ata_dma_chan_teardown(device);
1158 } else {
1159 /* Read data using PIO */
1160 rc = ata_packet_pio_data_in(device, obuf, obuf_size, rcvd_size);
[2791fbb7]1161 }
1162
1163 fibril_mutex_unlock(&chan->lock);
1164
[9739b5a]1165 if (rc != EOK)
1166 return rc;
[2791fbb7]1167
1168 return EOK;
1169}
1170
1171/** Issue ATAPI Inquiry.
1172 *
1173 * @param device Device
1174 * @param obuf Buffer for storing inquiry data read from device
1175 * @param obuf_size Size of obuf in bytes
1176 *
1177 * @return EOK on success, EIO on error.
1178 */
1179static errno_t ata_pcmd_inquiry(ata_device_t *device, void *obuf, size_t obuf_size,
1180 size_t *rcvd_size)
1181{
1182 uint8_t cpb[12];
1183 scsi_cdb_inquiry_t *cp = (scsi_cdb_inquiry_t *)cpb;
1184 errno_t rc;
1185
1186 memset(cpb, 0, sizeof(cpb));
1187
1188 /*
1189 * For SFF 8020 compliance the inquiry must be padded to 12 bytes
1190 * and allocation length must fit in one byte.
1191 */
1192 cp->op_code = SCSI_CMD_INQUIRY;
1193
1194 /* Allocation length */
1195 cp->alloc_len = host2uint16_t_be(min(obuf_size, 0xff));
1196
1197 rc = ata_cmd_packet(device, cpb, sizeof(cpb), obuf, obuf_size, rcvd_size);
1198 if (rc != EOK)
1199 return rc;
1200
1201 return EOK;
1202}
1203
1204/** Issue ATAPI read capacity(10) command.
1205 *
1206 * @param device Device
1207 * @param nblocks Place to store number of blocks
1208 * @param block_size Place to store block size
1209 *
1210 * @return EOK on success, EIO on error.
1211 */
1212static errno_t ata_pcmd_read_capacity(ata_device_t *device, uint64_t *nblocks,
1213 size_t *block_size)
1214{
1215 scsi_cdb_read_capacity_10_t cdb;
1216 scsi_read_capacity_10_data_t data;
1217 size_t rsize;
1218 errno_t rc;
1219
1220 memset(&cdb, 0, sizeof(cdb));
1221 cdb.op_code = SCSI_CMD_READ_CAPACITY_10;
1222
1223 rc = ata_cmd_packet(device, &cdb, sizeof(cdb), &data, sizeof(data), &rsize);
1224 if (rc != EOK)
1225 return rc;
1226
1227 if (rsize != sizeof(data))
1228 return EIO;
1229
1230 *nblocks = uint32_t_be2host(data.last_lba) + 1;
1231 *block_size = uint32_t_be2host(data.block_size);
1232
1233 return EOK;
1234}
1235
1236/** Issue ATAPI read(12) command.
1237 *
1238 * Output buffer must be large enough to hold the data, otherwise the
1239 * function will fail.
1240 *
1241 * @param device Device
1242 * @param ba Starting block address
1243 * @param cnt Number of blocks to read
1244 * @param obuf Buffer for storing inquiry data read from device
1245 * @param obuf_size Size of obuf in bytes
1246 *
1247 * @return EOK on success, EIO on error.
1248 */
1249static errno_t ata_pcmd_read_12(ata_device_t *device, uint64_t ba, size_t cnt,
1250 void *obuf, size_t obuf_size)
1251{
1252 scsi_cdb_read_12_t cp;
1253 errno_t rc;
1254
1255 if (ba > UINT32_MAX)
1256 return EINVAL;
1257
1258 memset(&cp, 0, sizeof(cp));
1259
1260 cp.op_code = SCSI_CMD_READ_12;
1261 cp.lba = host2uint32_t_be(ba);
1262 cp.xfer_len = host2uint32_t_be(cnt);
1263
1264 rc = ata_cmd_packet(device, &cp, sizeof(cp), obuf, obuf_size, NULL);
1265 if (rc != EOK)
1266 return rc;
1267
1268 return EOK;
1269}
1270
1271/** Issue ATAPI read TOC command.
1272 *
1273 * Read TOC in 'multi-session' format (first and last session number
1274 * with last session LBA).
1275 *
1276 * http://suif.stanford.edu/~csapuntz/specs/INF-8020.PDF page 171
1277 *
1278 * Output buffer must be large enough to hold the data, otherwise the
1279 * function will fail.
1280 *
1281 * @param device Device
1282 * @param session Starting session
1283 * @param obuf Buffer for storing inquiry data read from device
1284 * @param obuf_size Size of obuf in bytes
1285 *
1286 * @return EOK on success, EIO on error.
1287 */
1288static errno_t ata_pcmd_read_toc(ata_device_t *device, uint8_t session,
1289 void *obuf, size_t obuf_size)
1290{
1291 uint8_t cpb[12];
1292 scsi_cdb_read_toc_t *cp = (scsi_cdb_read_toc_t *)cpb;
1293 errno_t rc;
1294
1295 memset(cpb, 0, sizeof(cpb));
1296
1297 cp->op_code = SCSI_CMD_READ_TOC;
1298 cp->msf = 0;
1299 cp->format = 0x01; /* 0x01 = multi-session mode */
1300 cp->track_sess_no = session;
1301 cp->alloc_len = host2uint16_t_be(obuf_size);
1302 cp->control = 0x40; /* 0x01 = multi-session mode (shifted to MSB) */
1303
1304 rc = ata_cmd_packet(device, cpb, sizeof(cpb), obuf, obuf_size, NULL);
1305 if (rc != EOK)
1306 return rc;
1307
1308 return EOK;
1309}
1310
1311/** Read a physical block from the device.
1312 *
1313 * @param device Device
1314 * @param ba Address the first block.
1315 * @param cnt Number of blocks to transfer.
1316 * @param buf Buffer for holding the data.
1317 *
1318 * @return EOK on success, EIO on error.
1319 */
1320static errno_t ata_rcmd_read(ata_device_t *device, uint64_t ba, size_t blk_cnt,
1321 void *buf)
1322{
1323 ata_channel_t *chan = device->chan;
1324 uint8_t drv_head;
1325 block_coord_t bc;
[645d3832]1326 uint8_t cmd;
[2791fbb7]1327 errno_t rc;
1328
1329 /* Silence warning. */
1330 memset(&bc, 0, sizeof(bc));
1331
1332 /* Compute block coordinates. */
1333 if (coord_calc(device, ba, &bc) != EOK) {
1334 ata_msg_note(chan, "ata_rcmd_read() -> coord_calc failed");
1335 return EINVAL;
1336 }
1337
1338 /* New value for Drive/Head register */
1339 drv_head =
1340 ((disk_dev_idx(device) != 0) ? DHR_DRV : 0) |
1341 ((device->amode != am_chs) ? DHR_LBA : 0) |
1342 (bc.h & 0x0f);
1343
1344 fibril_mutex_lock(&chan->lock);
1345
1346 /* Program a Read Sectors operation. */
1347
1348 if (wait_status(chan, 0, ~SR_BSY, NULL, TIMEOUT_BSY) != EOK) {
1349 fibril_mutex_unlock(&chan->lock);
1350 ata_msg_note(chan, "ata_rcmd_read() -> wait_status failed");
1351 return EIO;
1352 }
1353
1354 ata_write_cmd_8(chan, REG_DRIVE_HEAD, drv_head);
1355
1356 if (wait_status(chan, SR_DRDY, ~SR_BSY, NULL, TIMEOUT_DRDY) != EOK) {
1357 fibril_mutex_unlock(&chan->lock);
1358 ata_msg_note(chan, "ata_rcmd_read() -> wait_status 2 failed");
1359 return EIO;
1360 }
1361
1362 /* Program block coordinates into the device. */
1363 coord_sc_program(chan, &bc, blk_cnt);
1364
[645d3832]1365 if (chan->params.use_dma) {
1366 cmd = (device->amode == am_lba48) ? CMD_READ_DMA_EXT :
1367 CMD_READ_DMA;
[2791fbb7]1368
[645d3832]1369 rc = ata_dma_proto(device, cmd, buf,
1370 blk_cnt * device->block_size, ata_dma_read);
1371 if (rc != EOK) {
1372 ata_msg_note(chan, "ata_rcmd_read() -> dma_proto->%d",
1373 rc);
1374 }
1375 } else {
1376 ata_write_cmd_8(chan, REG_COMMAND, device->amode == am_lba48 ?
1377 CMD_READ_SECTORS_EXT : CMD_READ_SECTORS);
1378
1379 rc = ata_pio_data_in(device, buf, blk_cnt * device->block_size,
1380 device->block_size, blk_cnt);
1381 if (rc != EOK) {
1382 ata_msg_note(chan, "ata_rcmd_read() -> pio_data_in->%d",
1383 rc);
1384 }
1385 }
[2791fbb7]1386
1387 fibril_mutex_unlock(&chan->lock);
1388
1389 return rc;
1390}
1391
1392/** Write a physical block to the device.
1393 *
1394 * @param device Device
1395 * @param ba Address of the first block.
1396 * @param cnt Number of blocks to transfer.
1397 * @param buf Buffer holding the data to write.
1398 *
1399 * @return EOK on success, EIO on error.
1400 */
1401static errno_t ata_rcmd_write(ata_device_t *device, uint64_t ba, size_t cnt,
1402 const void *buf)
1403{
1404 ata_channel_t *chan = device->chan;
1405 uint8_t drv_head;
1406 block_coord_t bc;
[645d3832]1407 uint8_t cmd;
[2791fbb7]1408 errno_t rc;
1409
1410 /* Silence warning. */
1411 memset(&bc, 0, sizeof(bc));
1412
1413 /* Compute block coordinates. */
1414 if (coord_calc(device, ba, &bc) != EOK)
1415 return EINVAL;
1416
1417 /* New value for Drive/Head register */
1418 drv_head =
1419 ((disk_dev_idx(device) != 0) ? DHR_DRV : 0) |
1420 ((device->amode != am_chs) ? DHR_LBA : 0) |
1421 (bc.h & 0x0f);
1422
1423 fibril_mutex_lock(&chan->lock);
1424
1425 /* Program a Write Sectors operation. */
1426
1427 if (wait_status(chan, 0, ~SR_BSY, NULL, TIMEOUT_BSY) != EOK) {
1428 fibril_mutex_unlock(&chan->lock);
1429 return EIO;
1430 }
1431
1432 ata_write_cmd_8(chan, REG_DRIVE_HEAD, drv_head);
1433
1434 if (wait_status(chan, SR_DRDY, ~SR_BSY, NULL, TIMEOUT_DRDY) != EOK) {
1435 fibril_mutex_unlock(&chan->lock);
1436 return EIO;
1437 }
1438
1439 /* Program block coordinates into the device. */
1440 coord_sc_program(chan, &bc, cnt);
1441
[645d3832]1442 if (chan->params.use_dma) {
1443 cmd = (device->amode == am_lba48) ? CMD_WRITE_DMA_EXT :
1444 CMD_WRITE_DMA;
1445
1446 rc = ata_dma_proto(device, cmd, (void *)buf,
1447 cnt * device->block_size, ata_dma_write);
1448 if (rc != EOK) {
1449 ata_msg_note(chan, "ata_rcmd_write() -> dma_proto->%d",
1450 rc);
1451 }
1452 } else {
1453 ata_write_cmd_8(chan, REG_COMMAND, device->amode == am_lba48 ?
1454 CMD_WRITE_SECTORS_EXT : CMD_WRITE_SECTORS);
[2791fbb7]1455
[645d3832]1456 rc = ata_pio_data_out(device, buf, cnt * device->block_size,
1457 device->block_size, cnt);
1458 if (rc != EOK) {
1459 ata_msg_note(chan,
1460 "ata_rcmd_read() -> pio_data_out->%d", rc);
1461 }
1462 }
[2791fbb7]1463
1464 fibril_mutex_unlock(&chan->lock);
1465 return rc;
1466}
1467
1468/** Flush cached data to nonvolatile storage.
1469 *
1470 * @param device Device
1471 *
1472 * @return EOK on success, EIO on error.
1473 */
1474static errno_t ata_rcmd_flush_cache(ata_device_t *device)
1475{
1476 ata_channel_t *chan = device->chan;
1477 uint8_t drv_head;
1478 errno_t rc;
1479
1480 /* New value for Drive/Head register */
1481 drv_head =
1482 (disk_dev_idx(device) != 0) ? DHR_DRV : 0;
1483
1484 fibril_mutex_lock(&chan->lock);
1485
1486 /* Program a Flush Cache operation. */
1487
1488 if (wait_status(chan, 0, ~SR_BSY, NULL, TIMEOUT_BSY) != EOK) {
1489 fibril_mutex_unlock(&chan->lock);
1490 return EIO;
1491 }
1492
1493 ata_write_cmd_8(chan, REG_DRIVE_HEAD, drv_head);
1494
1495 if (wait_status(chan, SR_DRDY, ~SR_BSY, NULL, TIMEOUT_DRDY) != EOK) {
1496 fibril_mutex_unlock(&chan->lock);
1497 return EIO;
1498 }
1499
1500 ata_write_cmd_8(chan, REG_COMMAND, CMD_FLUSH_CACHE);
1501
1502 rc = ata_pio_nondata(device);
1503
1504 fibril_mutex_unlock(&chan->lock);
1505 return rc;
1506}
1507
1508/** Get the maximum number of blocks to be transferred in one I/O
1509 *
1510 * @param d Device
1511 * @return Maximum number of blocks
1512 */
1513static size_t ata_disk_maxnb(ata_device_t *d)
1514{
1515 size_t maxnb;
[a38d504]1516 size_t dma_maxnb;
[2791fbb7]1517
1518 maxnb = 0;
1519
1520 if (d->dev_type == ata_pkt_dev) {
1521 /* Could be more depending on SCSI command support */
1522 maxnb = 0x100;
1523 } else {
1524 switch (d->amode) {
1525 case am_chs:
1526 case am_lba28:
1527 maxnb = 0x100;
1528 break;
1529 case am_lba48:
1530 maxnb = 0x10000;
1531 break;
1532 }
1533 }
1534
1535 /*
1536 * If using DMA, this needs to be further restricted not to
1537 * exceed DMA buffer size.
1538 */
[a796812c]1539 if (d->chan->params.use_dma) {
1540 dma_maxnb = d->chan->params.max_dma_xfer / d->block_size;
1541 if (dma_maxnb < maxnb)
1542 maxnb = dma_maxnb;
1543 }
[a38d504]1544
[2791fbb7]1545 return maxnb;
1546}
1547
1548/** Calculate block coordinates.
1549 *
1550 * Calculates block coordinates in the best coordinate system supported
1551 * by the device. These can be later programmed into the device using
1552 * @c coord_sc_program().
1553 *
1554 * @return EOK on success or EINVAL if block index is past end of device.
1555 */
1556static errno_t coord_calc(ata_device_t *d, uint64_t ba, block_coord_t *bc)
1557{
1558 uint64_t c;
1559 uint64_t idx;
1560
1561 /* Check device bounds. */
1562 if (ba >= d->blocks)
1563 return EINVAL;
1564
1565 bc->amode = d->amode;
1566
1567 switch (d->amode) {
1568 case am_chs:
1569 /* Compute CHS coordinates. */
1570 c = ba / (d->geom.heads * d->geom.sectors);
1571 idx = ba % (d->geom.heads * d->geom.sectors);
1572
1573 bc->cyl_lo = c & 0xff;
1574 bc->cyl_hi = (c >> 8) & 0xff;
1575 bc->h = (idx / d->geom.sectors) & 0x0f;
1576 bc->sector = (1 + (idx % d->geom.sectors)) & 0xff;
1577 break;
1578
1579 case am_lba28:
1580 /* Compute LBA-28 coordinates. */
1581 bc->c0 = ba & 0xff; /* bits 0-7 */
1582 bc->c1 = (ba >> 8) & 0xff; /* bits 8-15 */
1583 bc->c2 = (ba >> 16) & 0xff; /* bits 16-23 */
1584 bc->h = (ba >> 24) & 0x0f; /* bits 24-27 */
1585 break;
1586
1587 case am_lba48:
1588 /* Compute LBA-48 coordinates. */
1589 bc->c0 = ba & 0xff; /* bits 0-7 */
1590 bc->c1 = (ba >> 8) & 0xff; /* bits 8-15 */
1591 bc->c2 = (ba >> 16) & 0xff; /* bits 16-23 */
1592 bc->c3 = (ba >> 24) & 0xff; /* bits 24-31 */
1593 bc->c4 = (ba >> 32) & 0xff; /* bits 32-39 */
1594 bc->c5 = (ba >> 40) & 0xff; /* bits 40-47 */
1595 bc->h = 0;
1596 break;
1597 }
1598
1599 return EOK;
1600}
1601
1602/** Program block coordinates and sector count into ATA registers.
1603 *
1604 * Note that bc->h must be programmed separately into the device/head register.
1605 *
1606 * @param chan Channel
1607 * @param bc Block coordinates
1608 * @param scnt Sector count
1609 */
1610static void coord_sc_program(ata_channel_t *chan, const block_coord_t *bc,
1611 uint16_t scnt)
1612{
1613 if (bc->amode == am_lba48) {
1614 /* Write high-order bits. */
1615 ata_write_cmd_8(chan, REG_SECTOR_COUNT, scnt >> 8);
1616 ata_write_cmd_8(chan, REG_SECTOR_NUMBER, bc->c3);
1617 ata_write_cmd_8(chan, REG_CYLINDER_LOW, bc->c4);
1618 ata_write_cmd_8(chan, REG_CYLINDER_HIGH, bc->c5);
1619 }
1620
1621 /* Write low-order bits. */
1622 ata_write_cmd_8(chan, REG_SECTOR_COUNT, scnt & 0x00ff);
1623 ata_write_cmd_8(chan, REG_SECTOR_NUMBER, bc->c0);
1624 ata_write_cmd_8(chan, REG_CYLINDER_LOW, bc->c1);
1625 ata_write_cmd_8(chan, REG_CYLINDER_HIGH, bc->c2);
1626}
1627
1628/** Wait until some status bits are set and some are reset.
1629 *
1630 * Example: wait_status(chan, SR_DRDY, ~SR_BSY, ...) waits for SR_DRDY to become
1631 * set and SR_BSY to become reset.
1632 *
1633 * @param chan Channel
1634 * @param set Combination if bits which must be all set.
1635 * @param n_reset Negated combination of bits which must be all reset.
1636 * @param pstatus Pointer where to store last read status or NULL.
1637 * @param timeout Timeout in 10ms units.
1638 *
1639 * @return EOK on success, EIO on timeout.
1640 */
1641static errno_t wait_status(ata_channel_t *chan, unsigned set, unsigned n_reset,
1642 uint8_t *pstatus, unsigned timeout)
1643{
1644 uint8_t status;
1645 int cnt;
1646
1647 status = ata_read_cmd_8(chan, REG_STATUS);
1648
1649 /*
1650 * This is crude, yet simple. First try with 1us delays
1651 * (most likely the device will respond very fast). If not,
1652 * start trying every 10 ms.
1653 */
1654
1655 cnt = 100;
1656 while ((status & ~n_reset) != 0 || (status & set) != set) {
1657 --cnt;
1658 if (cnt <= 0)
1659 break;
1660
1661 status = ata_read_cmd_8(chan, REG_STATUS);
1662 }
1663
1664 cnt = timeout;
1665 while ((status & ~n_reset) != 0 || (status & set) != set) {
1666 fibril_usleep(10000);
1667 --cnt;
1668 if (cnt <= 0)
1669 break;
1670
1671 status = ata_read_cmd_8(chan, REG_STATUS);
1672 }
1673
1674 if (pstatus)
1675 *pstatus = status;
1676
1677 if (cnt == 0)
1678 return EIO;
1679
1680 return EOK;
1681}
1682
1683/** Wait for IRQ and return status.
1684 *
1685 * @param chan Channel
1686 * @param pstatus Pointer where to store last read status or NULL.
1687 * @param timeout Timeout in 10ms units.
1688 *
1689 * @return EOK on success, EIO on timeout.
1690 */
1691static errno_t wait_irq(ata_channel_t *chan, uint8_t *pstatus, unsigned timeout)
1692{
1693 fibril_mutex_lock(&chan->irq_lock);
1694 while (!chan->irq_fired)
1695 fibril_condvar_wait(&chan->irq_cv, &chan->irq_lock);
1696
1697 chan->irq_fired = false;
1698 *pstatus = chan->irq_status;
1699 fibril_mutex_unlock(&chan->irq_lock);
1700 return EOK;
1701}
1702
[645d3832]1703/** Set up DMA channel.
1704 *
1705 * @param device ATA device
1706 * @param buf Data buffer
1707 * @param buf_size Data buffer size in bytes
1708 * @param dir DMA direction
1709 */
1710static void ata_dma_chan_setup(ata_device_t *device, void *buf,
1711 size_t buf_size, ata_dma_dir_t dir)
1712{
1713 device->chan->params.dma_chan_setup(device->chan->params.arg,
1714 buf, buf_size, dir);
1715}
1716
1717/** Tear down DMA channel.
1718 *
1719 * @param device ATA device
1720 */
1721static void ata_dma_chan_teardown(ata_device_t *device)
1722{
1723 device->chan->params.dma_chan_teardown(device->chan->params.arg);
1724}
1725
[2791fbb7]1726/** Interrupt handler.
1727 *
1728 * @param chan ATA channel
1729 * @param status Status read by interrupt handler
1730 */
1731void ata_channel_irq(ata_channel_t *chan, uint8_t status)
1732{
1733 fibril_mutex_lock(&chan->irq_lock);
1734 chan->irq_fired = true;
1735 chan->irq_status = status;
1736 fibril_mutex_unlock(&chan->irq_lock);
1737 fibril_condvar_broadcast(&chan->irq_cv);
1738}
1739
1740/** Block device connection handler */
1741void ata_connection(ipc_call_t *icall, ata_device_t *device)
1742{
1743 bd_conn(icall, &device->bds);
1744}
1745
1746/**
1747 * @}
1748 */
Note: See TracBrowser for help on using the repository browser.