ata.c File Reference

ATA block device. More...

#include <stddef.h>
#include <string.h>
#include <assert.h>
#include <errno.h>
#include <byteswap.h>
#include <gpxe/blockdev.h>
#include <gpxe/process.h>
#include <gpxe/ata.h>

Go to the source code of this file.

Functions

 FILE_LICENCE (GPL2_OR_LATER)
static struct ata_deviceblock_to_ata (struct block_device *blockdev)
static int ata_command (struct ata_device *ata, struct ata_command *command)
 Issue ATA command.
static int ata_read (struct block_device *blockdev, uint64_t block, unsigned long count, userptr_t buffer)
 Read block from ATA device.
static int ata_write (struct block_device *blockdev, uint64_t block, unsigned long count, userptr_t buffer)
 Write block to ATA device.
static int ata_identify (struct block_device *blockdev)
 Identify ATA device.
int init_atadev (struct ata_device *ata)
 Initialise ATA device.

Variables

static struct
block_device_operations 
ata_operations


Detailed Description

ATA block device.

Definition in file ata.c.


Function Documentation

FILE_LICENCE ( GPL2_OR_LATER   ) 

static struct ata_device* block_to_ata ( struct block_device blockdev  )  [static, read]

Definition at line 37 of file ata.c.

References container_of.

Referenced by ata_identify(), ata_read(), and ata_write().

00037                                                {
00038         return container_of ( blockdev, struct ata_device, blockdev );
00039 }

static int ata_command ( struct ata_device ata,
struct ata_command command 
) [inline, static]

Issue ATA command.

Parameters:
ata ATA device
command ATA command
Return values:
rc Return status code

Definition at line 49 of file ata.c.

References DBG, EINPROGRESS, step(), and strerror().

Referenced by ata_read(), and ata_write().

00049                                                                     {
00050         int rc;
00051 
00052         DBG ( "ATA cmd %02x dev %02x LBA%s %llx count %04x\n",
00053               command->cb.cmd_stat, command->cb.device,
00054               ( command->cb.lba48 ? "48" : "" ),
00055               ( unsigned long long ) command->cb.lba.native,
00056               command->cb.count.native );
00057 
00058         /* Flag command as in-progress */
00059         command->rc = -EINPROGRESS;
00060 
00061         /* Issue ATA command */
00062         if ( ( rc = ata->command ( ata, command ) ) != 0 ) {
00063                 /* Something went wrong with the issuing mechanism */
00064                 DBG ( "ATA could not issue command: %s\n", strerror ( rc ) );
00065                 return rc;
00066         }
00067 
00068         /* Wait for command to complete */
00069         while ( command->rc == -EINPROGRESS )
00070                 step();
00071         if ( ( rc = command->rc ) != 0 ) {
00072                 /* Something went wrong with the command execution */
00073                 DBG ( "ATA command failed: %s\n", strerror ( rc ) );
00074                 return rc;
00075         }
00076 
00077         return 0;
00078 }

static int ata_read ( struct block_device blockdev,
uint64_t  block,
unsigned long  count,
userptr_t  buffer 
) [static]

Read block from ATA device.

Parameters:
blockdev Block device
block LBA block number
count Block count
buffer Data buffer
Return values:
rc Return status code

Definition at line 89 of file ata.c.

References ATA_CMD_READ, ATA_CMD_READ_EXT, ata_command(), ATA_DEV_LBA, ATA_DEV_OBSOLETE, block_to_ata(), ata_lba::bytes, ata_command::cb, ata_cb::cmd_stat, ata_cb::count, ata_command::data_in, ata_device::device, ata_cb::device, ata_cb::lba, ata_device::lba48, ata_cb::lba48, ata_lba::low_prev, memset(), ata_fifo::native, and ata_lba::native.

00090                                                               {
00091         struct ata_device *ata = block_to_ata ( blockdev );
00092         struct ata_command command;
00093 
00094         memset ( &command, 0, sizeof ( command ) );
00095         command.cb.lba.native = block;
00096         command.cb.count.native = count;
00097         command.cb.device = ( ata->device | ATA_DEV_OBSOLETE | ATA_DEV_LBA );
00098         command.cb.lba48 = ata->lba48;
00099         if ( ! ata->lba48 )
00100                 command.cb.device |= command.cb.lba.bytes.low_prev;
00101         command.cb.cmd_stat = ( ata->lba48 ? ATA_CMD_READ_EXT : ATA_CMD_READ );
00102         command.data_in = buffer;
00103         return ata_command ( ata, &command );
00104 }

static int ata_write ( struct block_device blockdev,
uint64_t  block,
unsigned long  count,
userptr_t  buffer 
) [static]

Write block to ATA device.

Parameters:
blockdev Block device
block LBA block number
count Block count
buffer Data buffer
Return values:
rc Return status code

Definition at line 115 of file ata.c.

References ATA_CMD_WRITE, ATA_CMD_WRITE_EXT, ata_command(), ATA_DEV_LBA, ATA_DEV_OBSOLETE, block_to_ata(), ata_lba::bytes, ata_command::cb, ata_cb::cmd_stat, ata_cb::count, ata_command::data_out, ata_device::device, ata_cb::device, ata_cb::lba, ata_device::lba48, ata_cb::lba48, ata_lba::low_prev, memset(), ata_fifo::native, and ata_lba::native.

00116                                                                {
00117         struct ata_device *ata = block_to_ata ( blockdev );
00118         struct ata_command command;
00119         
00120         memset ( &command, 0, sizeof ( command ) );
00121         command.cb.lba.native = block;
00122         command.cb.count.native = count;
00123         command.cb.device = ( ata->device | ATA_DEV_OBSOLETE | ATA_DEV_LBA );
00124         command.cb.lba48 = ata->lba48;
00125         if ( ! ata->lba48 )
00126                 command.cb.device |= command.cb.lba.bytes.low_prev;
00127         command.cb.cmd_stat = ( ata->lba48 ?
00128                                 ATA_CMD_WRITE_EXT : ATA_CMD_WRITE );
00129         command.data_out = buffer;
00130         return ata_command ( ata, &command );
00131 }

static int ata_identify ( struct block_device blockdev  )  [static]

Identify ATA device.

Parameters:
blockdev Block device
Return values:
rc Return status code

Definition at line 139 of file ata.c.

References ATA_CMD_IDENTIFY, ATA_DEV_LBA, ATA_DEV_OBSOLETE, ATA_SECTOR_SIZE, ATA_SUPPORTS_LBA48, block_device::blksize, block_to_ata(), block_device::blocks, ata_command::cb, ata_cb::cmd_stat, ata_cb::count, cpu_to_le16, ata_command::data_in, ata_device::device, ata_cb::device, ata_device::lba48, ata_identity::lba48_sectors, ata_identity::lba_sectors, le32_to_cpu, le64_to_cpu, linker_assert, memset(), ata_fifo::native, ata_identity::supports_lba48, and virt_to_user().

Referenced by init_atadev().

00139                                                           {
00140         struct ata_device *ata = block_to_ata ( blockdev );
00141         struct ata_command command;
00142         struct ata_identity identity;
00143         int rc;
00144 
00145         /* Issue IDENTIFY */
00146         memset ( &command, 0, sizeof ( command ) );
00147         command.cb.count.native = 1;
00148         command.cb.device = ( ata->device | ATA_DEV_OBSOLETE | ATA_DEV_LBA );
00149         command.cb.cmd_stat = ATA_CMD_IDENTIFY;
00150         command.data_in = virt_to_user ( &identity );
00151         linker_assert ( sizeof ( identity ) == ATA_SECTOR_SIZE,
00152                         __ata_identity_bad_size__ );
00153         if ( ( rc = ata_command ( ata, &command ) ) != 0 )
00154                 return rc;
00155 
00156         /* Fill in block device parameters */
00157         blockdev->blksize = ATA_SECTOR_SIZE;
00158         if ( identity.supports_lba48 & cpu_to_le16 ( ATA_SUPPORTS_LBA48 ) ) {
00159                 ata->lba48 = 1;
00160                 blockdev->blocks = le64_to_cpu ( identity.lba48_sectors );
00161         } else {
00162                 blockdev->blocks = le32_to_cpu ( identity.lba_sectors );
00163         }
00164         return 0;
00165 }

int init_atadev ( struct ata_device ata  ) 

Initialise ATA device.

Parameters:
ata ATA device
Return values:
rc Return status code
Initialises an ATA device. The ata_device::command field and the ATA_FL_SLAVE portion of the ata_device::flags field must already be filled in. This function will configure ata_device::blockdev, including issuing an IDENTIFY DEVICE call to determine the block size and total device size.

Fill in read and write methods, and get device capacity

Definition at line 184 of file ata.c.

References ata_identify(), ata_device::blockdev, and block_device::op.

Referenced by aoeboot().

00184                                            {
00185         /** Fill in read and write methods, and get device capacity */
00186         ata->blockdev.op = &ata_operations;
00187         return ata_identify ( &ata->blockdev );
00188 }


Variable Documentation

Initial value:

 {
        .read   = ata_read,
        .write  = ata_write
}

Definition at line 167 of file ata.c.


Generated on Tue Apr 6 20:01:16 2010 for gPXE by  doxygen 1.5.7.1