ata: ide-sff: add LBA48 support
PATCH v2 1/1 ata: ide-sff: add LBA48 support
See http://wiki.osdev.org/ATA_PIO_Mode#48_bit_PIO for details.
Signed-off-by Antony Pavlov <[email protected]>
---
Changes since v1:
* fix typo in the commit message;
* trivial change: put "port->lba48 = ata_id_has_lba48(port->id);"
just after debug stuff (ata_dump_id(port->id)).
--- drivers/ata/disk_ata_drive.c | 3 +++ drivers/ata/ide-sff.c | 54 +++++++++++++++++++++++++++++++++++--------- include/ata_drive.h | 3 +++ 3 files changed, 49 insertions(+), 11 deletions(-)
drivers/ata/disk_ata_drive.c +3 -0
@@ -237,6 +237,9 @@ static int ata_port_init(struct ata_port *port)#ifdef DEBUG ata_dump_id (port->id);#endif + + port->lba48 =ata_id_has_lba48 (port->id); +if (port->devname) { port->blk.cdev.name =xstrdup (port->devname); }else {
drivers/ata/ide-sff.c +43 -11
80 lines not on this page · raw message
include/ata_drive.h +3 -0
@@ -37,8 +37,10 @@#define ATA_CMD_ID_ATA 0xEC#define ATA_CMD_READ 0x20 +#define ATA_CMD_PIO_READ_EXT 0x24#define ATA_CMD_READ_EXT 0x25#define ATA_CMD_WRITE 0x30 +#define ATA_CMD_PIO_WRITE_EXT 0x34#define ATA_CMD_WRITE_EXT 0x35/* drive's status flags */
@@ -140,6 +142,7 @@ struct ata_port {void *drvdata;struct block_device blk;uint16_t *id; +int lba48;int initialized;int probe; };
Signature · 7 lines
2.11.0 _______________________________________________ barebox mailing list [email protected] http://lists.infradead.org/mailman/listinfo/barebox
Sascha Hauer
AppliedQuoted 10 lines · Antony Pavlov
See http://wiki.osdev.org/ATA_PIO_Mode#48_bit_PIO for details.
Signed-off-by Antony Pavlov <[email protected]>---
Changes since v1:
* fix typo in the commit message;
* trivial change: put "port->lba48=ata_id_has_lba48(port->id);"just after debug stuff (ata_dump_id(port->id)).
Applied, thanks
Sascha
Quoted 135 lines
--- drivers/ata/disk_ata_drive.c | 3 +++ drivers/ata/ide-sff.c | 54 +++++++++++++++++++++++++++++++++++--------- include/ata_drive.h | 3 +++ 3 files changed, 49 insertions(+), 11 deletions(-)drivers/ata/disk_ata_drive.c +3
-0@@ -237,6 +237,9 @@ static int ata_port_init(struct ata_port *port)#ifdef DEBUG ata_dump_id (port->id);#endif + + port->lba48 =ata_id_has_lba48 (port->id); +if (port->devname) { port->blk.cdev.name =xstrdup (port->devname); }else {drivers/ata/ide-sff.c +43
-11@@ -136,17 +136,33 @@ static int ata_wait_ready(struct ide_port *ide, unsigned timeout)* @param io Register file * @param drive 0 master drive, 1 slave drive * @param num Sector number -* -* @todo LBA48 support */ -static int ata_set_lba_sector (struct ide_port *ide,unsigned drive,uint64_t num) +static int ata_set_lba_sector (struct ata_port *port,unsigned drive, +uint64_t num) { -if (num >0x0FFFFFFF || drive >1 ) +struct ide_port *ide =to_ata_drive_access (port); + +if (drive >1 )return -EINVAL ; -ata_wr_byte (ide,0xA0 |LBA_FLAG | drive <<4 | num >>24 , - ide->io.device_addr); -ata_wr_byte (ide,0x00 , ide->io.error_addr); +if (port->lba48) { +if (num > (1ULL <<48 ) -1 ) +return -EINVAL ; + +ata_wr_byte (ide,LBA_FLAG | drive <<4 , ide->io.device_addr); + +ata_wr_byte (ide,0x00 , ide->io.nsect_addr); +ata_wr_byte (ide, num >>24 , ide->io.lbal_addr); +ata_wr_byte (ide, num >>32 , ide->io.lbam_addr); +ata_wr_byte (ide, num >>40 , ide->io.lbah_addr); + }else { +if (num > (1ULL <<28 ) -1 ) +return -EINVAL ; + +ata_wr_byte (ide,0xA0 |LBA_FLAG | drive <<4 | num >>24 , + ide->io.device_addr); + } +ata_wr_byte (ide,0x01 , ide->io.nsect_addr);ata_wr_byte (ide, num, ide->io.lbal_addr);/* 0 ... 7 */ ata_wr_byte (ide, num >>8 , ide->io.lbam_addr);/* 8 ... 15 */ @@ -316,10 +332,18 @@ static int ide_read(struct ata_port *port, void *buffer, unsigned int block,struct ide_port *ide =to_ata_drive_access (port);while (num_blocks) { - rc =ata_set_lba_sector (ide,DISK_MASTER , sector); +uint8_t cmd; + + rc =ata_set_lba_sector (port,DISK_MASTER , sector);if (rc !=0 )return rc; - rc =ata_wr_cmd (ide,ATA_CMD_READ ); + +if (port->lba48) + cmd =ATA_CMD_PIO_READ_EXT ; +else + cmd =ATA_CMD_READ ; + + rc =ata_wr_cmd (ide, cmd);if (rc !=0 )return rc; rc =ata_wait_ready (ide,MAX_TIMEOUT );@@ -355,10 +379,18 @@ static int __maybe_unused ide_write(struct ata_port *port,struct ide_port *ide =to_ata_drive_access (port);while (num_blocks) { - rc =ata_set_lba_sector (ide,DISK_MASTER , sector); +uint8_t cmd; + + rc =ata_set_lba_sector (port,DISK_MASTER , sector);if (rc !=0 )return rc; - rc =ata_wr_cmd (ide,ATA_CMD_WRITE ); + +if (port->lba48) + cmd =ATA_CMD_PIO_WRITE_EXT ; +else + cmd =ATA_CMD_WRITE ; + + rc =ata_wr_cmd (ide, cmd);if (rc !=0 )return rc; rc =ata_wait_ready (ide,MAX_TIMEOUT );include/ata_drive.h +3
-0@@ -37,8 +37,10 @@#define ATA_CMD_ID_ATA 0xEC#define ATA_CMD_READ 0x20 +#define ATA_CMD_PIO_READ_EXT 0x24#define ATA_CMD_READ_EXT 0x25#define ATA_CMD_WRITE 0x30 +#define ATA_CMD_PIO_WRITE_EXT 0x34#define ATA_CMD_WRITE_EXT 0x35/* drive's status flags */ @@ -140,6 +142,7 @@ struct ata_port {void *drvdata;struct block_device blk;uint16_t *id; +int lba48;int initialized;int probe; };Signature · 1 line
2.11.0
Signature · 9 lines
Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 | _______________________________________________ barebox mailing list [email protected] http://lists.infradead.org/mailman/listinfo/barebox