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

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

Implement quiesce in ISA and PCI IDE and in PC Floppy.

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