KallistiOS git master
Independent SDK for the Sega Dreamcast
Loading...
Searching...
No Matches
g1ata.h
Go to the documentation of this file.
1/* KallistiOS ##version##
2
3 dc/g1ata.h
4 Copyright (C) 2013, 2014 Lawrence Sebald
5 Copyright (C) 2023 Ruslan Rostovtsev
6*/
7
8/** \file dc/g1ata.h
9 \brief G1 bus ATA interface.
10 \ingroup g1ata
11
12 This file provides support for accessing an ATA device on the G1 bus in the
13 Dreamcast. The G1 bus usually contains a few useful pieces of the system,
14 including the flashrom and the GD-ROM drive. The interesting piece here is
15 that the GD-ROM drive itself is actually an ATA device.
16
17 Luckily, Sega left everything in place to access both a master and slave
18 device on this ATA port. The GD-ROM drive should always be the master device
19 on the chain, but you can hook up a hard drive or some other device as a
20 slave. The functions herein are for accessing just such a slave device.
21
22 \note The functions herein do not provide for direct access to the GD-ROM
23 drive. There is not really any sort of compelling reason to access
24 the GD-ROM drive directly instead of using the system calls, so you
25 should continue to use the normal cdrom_* functions for accessing
26 the GD-ROM drive. Also, currently there is no locking done to
27 prevent you from doing "bad things" with concurrent access on the
28 bus, so be careful. ;)
29
30 \author Lawrence Sebald
31 \author Ruslan Rostovtsev
32*/
33
34#ifndef __DC_G1ATA_H
35#define __DC_G1ATA_H
36
37#include <sys/cdefs.h>
38__BEGIN_DECLS
39
40#include <stdint.h>
41#include <kos/blockdev.h>
42
43/** \defgroup g1ata G1 ATA
44 \brief Driver for Accessing an ATA device on the G1 Bus
45 \ingroup vfs_drivers
46*/
47
48/** \defgroup ata_devices Device Definitions
49 \brief ATA device definitions
50 \ingroup g1ata
51
52 The constants here represent the valid values that can be set as the active
53 device on the ATA bus. You should pass one of these values to the
54 g1_ata_select_device() function to select the appropriate device.
55
56 \note Many times, the value returned by the g1_ata_select_device()
57 function will have other bits set than the constants below. You
58 should AND the value returned from that function with 0x10 if you
59 really need to know what device is actually selected. If the value
60 returned is true when ANDed with 0x10, then the slave device was
61 selected, otherwise the master device was. The other bits are either
62 command-specific or are reserved for compatibility sake.
63
64 @{
65*/
66/** \brief ATA master device.
67 \ingroup g1ata
68
69 This constant selects the master device on the ATA bus. This is normally the
70 GD-ROM drive.
71
72 \note The GD-ROM really does not like the reserved bits being set in the
73 device select register, hence why this constant doesn't select them.
74 Some hard drives may require them, however. If you find one that
75 does, then you should use the \ref G1_ATA_MASTER_ALT constant to
76 access it if it is the master device on the bus.
77*/
78#define G1_ATA_MASTER 0x00
79
80/** \brief ATA master device (compatible with old drives).
81 \ingroup g1ata
82
83 This constant selects the master device on the ATA bus, with the old
84 reserved bits set to 1. If you have a drive that predates ATA-2, then this
85 will probably be the constant you want to access it as the master device.
86
87 \note Do not use this constant to access the GD-ROM. It will not work. Use
88 \ref G1_ATA_MASTER instead.
89*/
90#define G1_ATA_MASTER_ALT 0x90
91
92/** \brief ATA slave device.
93 \ingroup g1ata
94
95 This constant selects the slave device on the ATA bus. This is where you
96 would find a hard drive, if the user has an adapter installed.
97*/
98#define G1_ATA_SLAVE 0xB0
99
100/** \brief Select LBA addressing mode.
101 \ingroup g1ata
102
103 OR this constant with one of the device constants (\ref G1_ATA_MASTER or
104 \ref G1_ATA_SLAVE) to select LBA addressing mode. The various g1_ata_*
105 functions all do this as appropriate already, so you shouldn't have to worry
106 about this one at all. This bit is irrelevant for packet devices.
107*/
108#define G1_ATA_LBA_MODE 0x40
109/** @} */
110
111/** \brief Is there a G1 DMA in progress currently?
112 \ingroup g1ata
113
114 This function returns non-zero if a DMA is in progress. This can be used to
115 check on the completion of DMA transfers when non-blocking mode was selected
116 at transfer time.
117
118 \return 0 if no DMA is in progress, nonzero otherwise.
119*/
121
122/** \brief Lock the G1 ATA mutex.
123 \ingroup g1ata
124
125 This function locks the mutex that arbitrates access to the ATA bus. You
126 should never have to do this on your own unless you're accessing devices
127 manually yourself.
128
129 \return 0 on success, -1 on failure.
130 \note Failure conditions are exactly the same as the
131 \ref mutex_lock() function.
132*/
134
135/** \brief Unlock the G1 ATA mutex.
136 \ingroup g1ata
137
138 This function unlocks the mutex that arbitrates access to the ATA bus. You
139 should never have to do this on your own unless you're accessing devices
140 manually yourself.
141
142 \return 0 on success, -1 on failure.
143 \note Failure conditions are exactly the same as the
144 \ref mutex_unlock() function.
145*/
147
148/** \brief Set the active ATA device.
149 \ingroup g1ata
150
151 This function sets the device that any further ATA commands will go to. You
152 shouldn't have to ever call this yourself, as it should be done for you by
153 any of the access functions. This must be called with the ATA lock held.
154
155 \param dev The device to access (generally either
156 \ref G1_ATA_MASTER or \ref G1_ATA_SLAVE).
157 \return The previous active device (or 0x0F if the function
158 would block in an IRQ handler).
159
160 \note This function may block if there is a transfer
161 ongoing. If called in an IRQ handler and the call
162 would otherwise block, 0x0F is returned.
163*/
164uint8_t g1_ata_select_device(uint8_t dev);
165
166/** \brief Read one or more disk sectors with Cylinder-Head-Sector addressing.
167 \ingroup g1ata
168
169 This function reads one or more 512-byte disk blocks from the slave device
170 on the G1 ATA bus using Cylinder-Head-Sector addressing. This function uses
171 PIO and blocks until the data is read in.
172
173 \param c The cylinder to start reading from.
174 \param h The head to start reading from.
175 \param s The sector to start reading from.
176 \param count The number of disk sectors to read.
177 \param buf Storage for the read-in disk sectors. This should be
178 at least (count * 512) bytes in length, and must be
179 at least 16-bit aligned.
180 \return 0 on success. < 0 on failure, setting errno as
181 appropriate.
182
183 \note Unless you're accessing a really old hard drive, you
184 probably do not want to use this function to access
185 the disk. Use the g1_ata_read_lba() function instead
186 of this one, unless you get an error from that
187 function indicating that LBA addressing is not
188 supported.
189
190 \par Error Conditions:
191 \em EIO - an I/O error occurred in reading data \n
192 \em ENXIO - ATA support not initialized or no device attached \n
193 \em EOVERFLOW - one or more of the requested sectors is out of the
194 range of the disk
195*/
196int g1_ata_read_chs(uint16_t c, uint8_t h, uint8_t s, size_t count,
197 void *buf);
198
199/** \brief Write one or more disk sectors with Cylinder-Head-Sector addressing.
200 \ingroup g1ata
201
202 This function writes one or more 512-byte disk blocks to the slave device
203 on the G1 ATA bus using Cylinder-Head-Sector addressing. This function uses
204 PIO and blocks until the data is written.
205
206 \param c The cylinder to start writing to.
207 \param h The head to start writing to.
208 \param s The sector to start writing to.
209 \param count The number of disk sectors to write.
210 \param buf The data to write to the disk. This should be
211 (count * 512) bytes in length and must be at least
212 16-bit aligned.
213 \return 0 on success. < 0 on failure, setting errno as
214 appropriate.
215
216 \note Unless you're accessing a really old hard drive, you
217 probably do not want to use this function to access
218 the disk. Use the g1_ata_write_lba() function
219 instead of this one, unless you get an error from
220 that function indicating that LBA addressing is not
221 supported.
222
223 \par Error Conditions:
224 \em ENXIO - ATA support not initialized or no device attached \n
225 \em EOVERFLOW - one or more of the requested sectors is out of the
226 range of the disk
227*/
228int g1_ata_write_chs(uint16_t c, uint8_t h, uint8_t s, size_t count,
229 const void *buf);
230
231/** \brief Read one or more disk sectors with Linear Block Addressing (LBA).
232 \ingroup g1ata
233
234 This function reads one or more 512-byte disk blocks from the slave device
235 on the G1 ATA bus using LBA mode (either 28 or 48 bits, as appropriate).
236 This function uses PIO and blocks until the data is read.
237
238 \param sector The sector to start reading from.
239 \param count The number of disk sectors to read.
240 \param buf Storage for the read-in disk sectors. This should be
241 at least (count * 512) bytes in length, and must be
242 at least 16-bit aligned.
243 \return 0 on success. < 0 on failure, setting errno as
244 appropriate.
245
246 \note If errno is set to ENOTSUP after calling this
247 function, you must use the g1_ata_read_chs()
248 function instead.
249
250 \par Error Conditions:
251 \em EIO - an I/O error occurred in reading data \n
252 \em ENXIO - ATA support not initialized or no device attached \n
253 \em EOVERFLOW - one or more of the requested sectors is out of the
254 range of the disk \n
255 \em ENOTSUP - LBA mode not supported by the device
256*/
257int g1_ata_read_lba(uint64_t sector, size_t count, void *buf);
258
259/** \brief DMA read disk sectors with Linear Block Addressing (LBA).
260 \ingroup g1ata
261
262 This function reads one or more 512-byte disk blocks from the slave device
263 on the G1 ATA bus using LBA mode (either 28 or 48 bits, as appropriate).
264 This function uses DMA and optionally blocks until the data is read.
265
266 \param sector The sector to start reading from.
267 \param count The number of disk sectors to read.
268 \param buf Storage for the read-in disk sectors. This should be
269 at least (count * 512) bytes in length, and must be
270 at least 32-byte aligned.
271 \param block Non-zero to block until the transfer completes.
272 \return 0 on success. < 0 on failure, setting errno as
273 appropriate.
274
275 \note If errno is set to ENOTSUP after calling this
276 function, you must use a CHS addressed transfer
277 function instead, like g1_ata_read_chs().
278
279 \note If errno is set to EPERM after calling this
280 function, DMA mode is not supported. You should use
281 a PIO transfer function like g1_ata_read_lba()
282 instead.
283
284 \par Error Conditions:
285 \em EIO - an I/O error occurred in reading data \n
286 \em ENXIO - ATA support not initialized or no device attached \n
287 \em EOVERFLOW - one or more of the requested sectors is out of the
288 range of the disk \n
289 \em ENOTSUP - LBA mode not supported by the device \n
290 \em EPERM - device does not support DMA
291*/
292int g1_ata_read_lba_dma(uint64_t sector, size_t count, void *buf,
293 int block);
294
295/** \brief Write one or more disk sectors with Linear Block Addressing (LBA).
296 \ingroup g1ata
297
298 This function writes one or more 512-byte disk blocks to the slave device
299 on the G1 ATA bus using LBA mode (either 28 or 48 bits, as appropriate).
300 This function uses PIO and blocks until the data is written.
301
302 \param sector The sector to start writing to.
303 \param count The number of disk sectors to write.
304 \param buf The data to write to the disk. This should be
305 (count * 512) bytes in length and must be at least
306 16-bit aligned.
307 \return 0 on success. < 0 on failure, setting errno as
308 appropriate.
309
310 \note If errno is set to ENOTSUP after calling this
311 function, you must use the g1_ata_write_chs()
312 function instead.
313
314 \par Error Conditions:
315 \em ENXIO - ATA support not initialized or no device attached \n
316 \em EOVERFLOW - one or more of the requested sectors is out of the
317 range of the disk \n
318 \em ENOTSUP - LBA mode not supported by the device
319*/
320int g1_ata_write_lba(uint64_t sector, size_t count, const void *buf);
321
322/** \brief DMA Write disk sectors with Linear Block Addressing (LBA).
323 \ingroup g1ata
324
325 This function writes one or more 512-byte disk blocks to the slave device
326 on the G1 ATA bus using LBA mode (either 28 or 48 bits, as appropriate).
327 This function uses DMA and optionally blocks until the data is written.
328
329 \param sector The sector to start writing to.
330 \param count The number of disk sectors to write.
331 \param buf The data to write to the disk. This should be
332 (count * 512) bytes in length and must be at least
333 32-byte aligned.
334 \param block Non-zero to block until the transfer completes.
335 \return 0 on success. < 0 on failure, setting errno as
336 appropriate.
337
338 \note If errno is set to ENOTSUP after calling this
339 function, you must use the g1_ata_write_chs()
340 function instead.
341
342 \note If errno is set to EPERM after calling this
343 function, DMA mode is not supported. You should use
344 a PIO transfer function like g1_ata_write_lba()
345 instead.
346
347 \par Error Conditions:
348 \em ENXIO - ATA support not initialized or no device attached \n
349 \em EOVERFLOW - one or more of the requested sectors is out of the
350 range of the disk \n
351 \em ENOTSUP - LBA mode not supported by the device \n
352 \em EPERM - device does not support DMA
353*/
354int g1_ata_write_lba_dma(uint64_t sector, size_t count, const void *buf,
355 int block);
356
357/** \brief Flush the write cache on the attached disk.
358 \ingroup g1ata
359
360 This function flushes the write cache on the disk attached as the slave
361 device on the G1 ATA bus. This ensures that all writes that have previously
362 completed are fully persisted to the disk. You should do this before
363 unmounting any disks or exiting your program if you have called any of the
364 write functions in here.
365
366 \return 0 on success. <0 on error, setting errno as
367 appropriate.
368
369 \par Error Conditions:
370 \em ENXIO - ATA support not initialized or no device attached
371*/
372int g1_ata_flush(void);
373
374/** \brief Get LBA mode of the attached disk.
375 \ingroup g1ata
376
377 \return -1 on error, 0 - CHS, 28 - LBA28, 48 - LBA48
378
379 \par Error Conditions:
380 \em ENXIO - ATA support not initialized or no device attached
381*/
383
384/** \brief Get a block device for a given partition on the slave ATA device.
385 \ingroup g1ata
386
387 This function creates a block device descriptor for the given partition on
388 the attached ATA device. This block device is used to interface with various
389 filesystems on the device.
390
391 \param partition The partition number (0-3) to use.
392 \param dma Set to 1 to use DMA for reads/writes on the device,
393 if available.
394 \param rv Used to return the block device. Must be non-NULL.
395 \param partition_type Used to return the partition type. Must be non-NULL.
396 \retval 0 On success.
397 \retval -1 On error, errno will be set as appropriate.
398
399 \par Error Conditions:
400 \em ENXIO - ATA support not initialized or no device attached \n
401 \em EIO - an I/O error occurred in reading data \n
402 \em EINVAL - invalid partition number was given \n
403 \em EFAULT - rv or partition_type was NULL \n
404 \em ENOENT - no MBR found \n
405 \em ENOENT - no partition at the specified position \n
406 \em ENOMEM - out of memory
407
408 \note This interface currently only supports MBR-formatted disks. There
409 is currently no support for GPT partition tables.
410*/
411int g1_ata_blockdev_for_partition(int partition, int dma, kos_blockdev_t *rv,
412 uint8_t *partition_type);
413
414/** \brief Get a block device for the attached ATA device.
415 \ingroup g1ata
416
417 This function creates a block device descriptor for the attached ATA device.
418
419 \param dma Set to 1 to use DMA for reads/writes on the device,
420 if available.
421 \param rv Used to return the block device. Must be non-NULL.
422 \retval 0 On success.
423 \retval -1 On error, errno will be set as appropriate.
424
425 \par Error Conditions:
426 \em ENXIO - ATA support not initialized or no device attached \n
427 \em EFAULT - rv was NULL \n
428 \em ENOMEM - out of memory
429*/
431
432/** \brief Initialize G1 ATA support.
433 \ingroup g1ata
434
435 This function initializes the rest of this subsystem and completes a scan of
436 the G1 ATA bus for devices. This function may take a while to complete with
437 some devices. Currently only the slave device is scanned, as the master
438 device should always be the GD-ROM drive.
439
440 \return 0 on success, <0 on error or if no device is present
441*/
442int g1_ata_init(void);
443
444/** \brief Shut down G1 ATA support.
445 \ingroup g1ata
446
447 This function shuts down the rest of this subsystem, and attempts to flush
448 the write cache of any attached slave devices. Accessing any ATA devices
449 using this subsystem after this function is called may produce undefined
450 results.
451*/
453
454__END_DECLS
455
456#endif /* __DC_G1ATA_H */
Definitions for a simple block device interface.
int g1_ata_flush(void)
Flush the write cache on the attached disk.
int g1_ata_lba_mode(void)
Get LBA mode of the attached disk.
int g1_ata_blockdev_for_partition(int partition, int dma, kos_blockdev_t *rv, uint8_t *partition_type)
Get a block device for a given partition on the slave ATA device.
void g1_ata_shutdown(void)
Shut down G1 ATA support.
int g1_ata_read_lba_dma(uint64_t sector, size_t count, void *buf, int block)
DMA read disk sectors with Linear Block Addressing (LBA).
int g1_ata_write_lba(uint64_t sector, size_t count, const void *buf)
Write one or more disk sectors with Linear Block Addressing (LBA).
int g1_dma_in_progress(void)
Is there a G1 DMA in progress currently?
int g1_ata_mutex_unlock(void)
Unlock the G1 ATA mutex.
int g1_ata_write_lba_dma(uint64_t sector, size_t count, const void *buf, int block)
DMA Write disk sectors with Linear Block Addressing (LBA).
int g1_ata_blockdev_for_device(int dma, kos_blockdev_t *rv)
Get a block device for the attached ATA device.
int g1_ata_read_chs(uint16_t c, uint8_t h, uint8_t s, size_t count, void *buf)
Read one or more disk sectors with Cylinder-Head-Sector addressing.
uint8_t g1_ata_select_device(uint8_t dev)
Set the active ATA device.
int g1_ata_init(void)
Initialize G1 ATA support.
int g1_ata_mutex_lock(void)
Lock the G1 ATA mutex.
int g1_ata_read_lba(uint64_t sector, size_t count, void *buf)
Read one or more disk sectors with Linear Block Addressing (LBA).
int g1_ata_write_chs(uint16_t c, uint8_t h, uint8_t s, size_t count, const void *buf)
Write one or more disk sectors with Cylinder-Head-Sector addressing.
A simple block device.
Definition blockdev.h:54