iPXE
ata.c File Reference

ATA block device. More...

#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <errno.h>
#include <byteswap.h>
#include <ipxe/list.h>
#include <ipxe/interface.h>
#include <ipxe/blockdev.h>
#include <ipxe/edd.h>
#include <ipxe/ata.h>

Go to the source code of this file.

Data Structures

struct  ata_device
 An ATA device. More...
struct  ata_command
 An ATA command. More...
struct  ata_command_type
 An ATA command type. More...
struct  ata_identify_private
 ATA IDENTIFY private data. More...

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 FILE_SECBOOT (PERMITTED)
int ata_command (struct interface *control, struct interface *data, struct ata_cmd *command)
 Issue ATA command.
static LIST_HEAD (ata_commands)
 List of all ATA commands.
static struct ata_deviceatadev_get (struct ata_device *atadev)
 Get reference to ATA device.
static void atadev_put (struct ata_device *atadev)
 Drop reference to ATA device.
static struct ata_commandatacmd_get (struct ata_command *atacmd)
 Get reference to ATA command.
static void atacmd_put (struct ata_command *atacmd)
 Drop reference to ATA command.
static void * atacmd_priv (struct ata_command *atacmd)
 Get ATA command private data.
static void atacmd_free (struct refcnt *refcnt)
 Free ATA command.
static void atacmd_close (struct ata_command *atacmd, int rc)
 Close ATA command.
static void atacmd_done (struct ata_command *atacmd, int rc)
 Handle ATA command completion.
static void atacmd_data_buffer (struct ata_command *atacmd __unused, struct xfer_buffer *xferbuf, void *buffer, size_t len)
 Use provided data buffer for ATA command.
static void atacmd_data_none (struct ata_command *atacmd __unused, struct xfer_buffer *xferbuf, void *buffer __unused, size_t len __unused)
 Use no data buffer for ATA command.
static void atacmd_data_priv (struct ata_command *atacmd, struct xfer_buffer *xferbuf, void *buffer __unused, size_t len __unused)
 Use private data buffer for ATA command.
static const char * ata_model (struct ata_identity *identity)
 Return ATA model string (for debugging).
static void atacmd_identify_done (struct ata_command *atacmd, int rc)
 Handle ATA IDENTIFY command completion.
static int atadev_command (struct ata_device *atadev, struct interface *block, struct ata_command_type *type, uint64_t lba, unsigned int count, void *buffer, size_t len)
 Create ATA command.
static int atadev_read (struct ata_device *atadev, struct interface *block, uint64_t lba, unsigned int count, void *buffer, size_t len)
 Issue ATA block read.
static int atadev_write (struct ata_device *atadev, struct interface *block, uint64_t lba, unsigned int count, void *buffer, size_t len)
 Issue ATA block write.
static int atadev_read_capacity (struct ata_device *atadev, struct interface *block)
 Read ATA device capacity.
static void atadev_close (struct ata_device *atadev, int rc)
 Close ATA device.
static int atadev_edd_describe (struct ata_device *atadev, struct edd_interface_type *type, union edd_device_path *path)
 Describe ATA device using EDD.
int ata_open (struct interface *block, struct interface *ata, unsigned int device, unsigned int max_count)
 Open ATA device.

Variables

static struct ata_command_type atacmd_read
 ATA READ command type.
static struct ata_command_type atacmd_write
 ATA WRITE command type.
static struct ata_command_type atacmd_identify
 ATA IDENTITY command type.
static struct interface_operation atacmd_block_op []
 ATA command block interface operations.
static struct interface_descriptor atacmd_block_desc
 ATA command block interface descriptor.
static struct interface_operation atacmd_ata_op []
 ATA command ATA interface operations.
static struct interface_descriptor atacmd_ata_desc
 ATA command ATA interface descriptor.
static struct interface_operation atadev_block_op []
 ATA device block interface operations.
static struct interface_descriptor atadev_block_desc
 ATA device block interface descriptor.
static struct interface_operation atadev_ata_op []
 ATA device ATA interface operations.
static struct interface_descriptor atadev_ata_desc
 ATA device ATA interface descriptor.

Detailed Description

ATA block device.

Definition in file ata.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )

◆ FILE_SECBOOT()

FILE_SECBOOT ( PERMITTED )

◆ ata_command()

int ata_command ( struct interface * control,
struct interface * data,
struct ata_cmd * command )

Issue ATA command.

Parameters
controlATA control interface
dataATA data interface
commandATA command
Return values
tagCommand tag, or negative error

Definition at line 60 of file ata.c.

61 {
62 struct interface *dest;
63 ata_command_TYPE ( void * ) *op =
65 void *object = intf_object ( dest );
66 int tag;
67
68 if ( op ) {
69 tag = op ( object, data, command );
70 } else {
71 /* Default is to fail to issue the command */
72 tag = -EOPNOTSUPP;
73 }
74
75 intf_put ( dest );
76 return tag;
77}
if(len >=6 *4) __asm__ __volatile__("movsl" if(len >=5 *4) __asm__ __volatile__("movsl" if(len >=4 *4) __asm__ __volatile__("movsl" if(len >=3 *4) __asm__ __volatile__("movsl" if(len >=2 *4) __asm__ __volatile__("movsl" if(len >=1 *4) __asm__ __volatile__("movsl" if((len % 4) >=2) __asm__ __volatile__("movsw" if((len % 2) >=1) __asm__ __volatile__("movsb" retur dest)
Definition string.h:151
#define ata_command_TYPE(object_type)
Definition ata.h:180
uint64_t tag
Identity tag.
Definition edd.h:1
uint8_t data[48]
Additional event data.
Definition ena.h:11
#define EOPNOTSUPP
Operation not supported on socket.
Definition errno.h:648
void * intf_object(struct interface *intf)
Get pointer to object containing object interface.
Definition interface.c:160
void intf_put(struct interface *intf)
Decrement reference count on an object interface.
Definition interface.c:150
#define intf_get_dest_op(intf, type, dest)
Get object interface destination and operation method.
Definition interface.h:270
uint32_t control
Control.
Definition myson.h:3
static uint16_t struct vmbus_xfer_pages_operations * op
Definition netvsc.h:327
An ATA command.
Definition ata.c:110
A command-line command.
Definition command.h:10
An object interface.
Definition interface.h:125

References ata_command_TYPE, control, data, dest, EOPNOTSUPP, intf_get_dest_op, intf_object(), intf_put(), op, and tag.

◆ LIST_HEAD()

LIST_HEAD ( ata_commands )
static

List of all ATA commands.

◆ atadev_get()

struct ata_device * atadev_get ( struct ata_device * atadev)
inlinestatic

Get reference to ATA device.

Parameters
atadevATA device
Return values
atadevATA device

Definition at line 180 of file ata.c.

180 {
181 ref_get ( &atadev->refcnt );
182 return atadev;
183}
#define ref_get(refcnt)
Get additional reference to object.
Definition refcnt.h:93
struct refcnt refcnt
Reference count.
Definition ata.c:92

References ref_get, and ata_device::refcnt.

Referenced by atadev_command().

◆ atadev_put()

void atadev_put ( struct ata_device * atadev)
inlinestatic

Drop reference to ATA device.

Parameters
atadevATA device

Definition at line 191 of file ata.c.

191 {
192 ref_put ( &atadev->refcnt );
193}
#define ref_put(refcnt)
Drop reference to object.
Definition refcnt.h:107

References ref_put, and ata_device::refcnt.

Referenced by atacmd_free().

◆ atacmd_get()

struct ata_command * atacmd_get ( struct ata_command * atacmd)
inlinestatic

Get reference to ATA command.

Parameters
atacmdATA command
Return values
atacmdATA command

Definition at line 202 of file ata.c.

202 {
203 ref_get ( &atacmd->refcnt );
204 return atacmd;
205}
struct refcnt refcnt
Reference count.
Definition ata.c:112

References ref_get, and ata_command::refcnt.

Referenced by atadev_close().

◆ atacmd_put()

void atacmd_put ( struct ata_command * atacmd)
inlinestatic

Drop reference to ATA command.

Parameters
atacmdATA command

Definition at line 213 of file ata.c.

213 {
214 ref_put ( &atacmd->refcnt );
215}

References ref_put, and ata_command::refcnt.

Referenced by atadev_close().

◆ atacmd_priv()

void * atacmd_priv ( struct ata_command * atacmd)
inlinestatic

Get ATA command private data.

Parameters
atacmdATA command
Return values
privPrivate data

Definition at line 224 of file ata.c.

224 {
225 return atacmd->priv;
226}
uint8_t priv[0]
Private data.
Definition ata.c:129

References ata_command::priv.

Referenced by atacmd_data_priv(), and atacmd_identify_done().

◆ atacmd_free()

void atacmd_free ( struct refcnt * refcnt)
static

Free ATA command.

Parameters
refcntReference count

Definition at line 233 of file ata.c.

233 {
234 struct ata_command *atacmd =
236
237 /* Remove from list of commands */
238 list_del ( &atacmd->list );
239 atadev_put ( atacmd->atadev );
240
241 /* Free command */
242 free ( atacmd );
243}
static void atadev_put(struct ata_device *atadev)
Drop reference to ATA device.
Definition ata.c:191
#define list_del(list)
Delete an entry from a list.
Definition list.h:120
static void(* free)(struct refcnt *refcnt))
Definition refcnt.h:55
#define container_of(ptr, type, field)
Get containing structure.
Definition stddef.h:36
struct ata_device * atadev
ATA device.
Definition ata.c:114
struct list_head list
List of ATA commands.
Definition ata.c:116
A reference counter.
Definition refcnt.h:27

References ata_command::atadev, atadev_put(), container_of, free, ata_command::list, and list_del.

Referenced by atadev_command().

◆ atacmd_close()

void atacmd_close ( struct ata_command * atacmd,
int rc )
static

Close ATA command.

Parameters
atacmdATA command
rcReason for close

Definition at line 251 of file ata.c.

251 {
252 struct ata_device *atadev = atacmd->atadev;
253
254 if ( rc != 0 ) {
255 DBGC ( atadev, "ATA %p tag %08x closed: %s\n",
256 atadev, atacmd->tag, strerror ( rc ) );
257 }
258
259 /* Shut down interfaces */
260 intf_shutdown ( &atacmd->ata, rc );
261 intf_shutdown ( &atacmd->block, rc );
262}
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
#define DBGC(...)
Definition compiler.h:530
void intf_shutdown(struct interface *intf, int rc)
Shut down an object interface.
Definition interface.c:279
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79
uint32_t tag
Command tag.
Definition ata.c:126
struct interface ata
ATA data interface.
Definition ata.c:121
struct interface block
Block data interface.
Definition ata.c:119
An ATA device.
Definition ata.c:90

References ata_command::ata, ata_command::atadev, ata_command::block, DBGC, intf_shutdown(), rc, strerror(), and ata_command::tag.

Referenced by atacmd_identify_done(), atadev_close(), and atadev_command().

◆ atacmd_done()

void atacmd_done ( struct ata_command * atacmd,
int rc )
static

Handle ATA command completion.

Parameters
atacmdATA command
rcReason for close

Definition at line 270 of file ata.c.

270 {
271
272 /* Hand over to the command completion handler */
273 atacmd->type->done ( atacmd, rc );
274}
void(* done)(struct ata_command *atacmd, int rc)
Handle ATA command completion.
Definition ata.c:170
struct ata_command_type * type
Command type.
Definition ata.c:124

References ata_command_type::done, rc, and ata_command::type.

◆ atacmd_data_buffer()

void atacmd_data_buffer ( struct ata_command *atacmd __unused,
struct xfer_buffer * xferbuf,
void * buffer,
size_t len )
static

Use provided data buffer for ATA command.

Parameters
atacmdATA command
xferbufData transfer buffer
bufferAvailable buffer
lenAvailable buffer length

Definition at line 284 of file ata.c.

286 {
287 xferbuf_fixed_init ( xferbuf, buffer, len );
288}
ring len
Length.
Definition dwmac.h:226
uint32_t buffer
Buffer index (or NETVSC_RNDIS_NO_BUFFER).
Definition netvsc.h:5
static void xferbuf_fixed_init(struct xfer_buffer *xferbuf, void *data, size_t len)
Initialise fixed-size data transfer buffer.
Definition xferbuf.h:93

References __unused, buffer, len, and xferbuf_fixed_init().

◆ atacmd_data_none()

void atacmd_data_none ( struct ata_command *atacmd __unused,
struct xfer_buffer * xferbuf,
void *buffer __unused,
size_t len __unused )
static

Use no data buffer for ATA command.

Parameters
atacmdATA command
xferbufData transfer buffer
bufferAvailable buffer
lenAvailable buffer length

Definition at line 298 of file ata.c.

300 {
301 xferbuf_void_init ( xferbuf );
302}
static void xferbuf_void_init(struct xfer_buffer *xferbuf)
Initialise void data transfer buffer.
Definition xferbuf.h:108

References __unused, buffer, len, and xferbuf_void_init().

◆ atacmd_data_priv()

void atacmd_data_priv ( struct ata_command * atacmd,
struct xfer_buffer * xferbuf,
void *buffer __unused,
size_t len __unused )
static

Use private data buffer for ATA command.

Parameters
atacmdATA command
xferbufData transfer buffer
bufferAvailable buffer
lenAvailable buffer length

Definition at line 312 of file ata.c.

314 {
315
316 xferbuf_fixed_init ( xferbuf, atacmd_priv ( atacmd ),
317 atacmd->type->priv_len );
318}
static void * atacmd_priv(struct ata_command *atacmd)
Get ATA command private data.
Definition ata.c:224
size_t priv_len
Additional working space.
Definition ata.c:137

References __unused, atacmd_priv(), buffer, len, ata_command_type::priv_len, ata_command::type, and xferbuf_fixed_init().

◆ ata_model()

const char * ata_model ( struct ata_identity * identity)
static

Return ATA model string (for debugging).

Parameters
identifyATA identity data
Return values
modelModel string

Definition at line 352 of file ata.c.

352 {
353 static union {
354 uint16_t words[ sizeof ( identity->model ) / 2 ];
355 char text[ sizeof ( identity->model ) + 1 /* NUL */ ];
356 } buf;
357 unsigned int i;
358
359 for ( i = 0 ; i < ( sizeof ( identity->model ) / 2 ) ; i++ )
360 buf.words[i] = bswap_16 ( identity->model[i] );
361
362 return buf.text;
363}
unsigned short uint16_t
Definition stdint.h:11
#define bswap_16(value)
Definition byteswap.h:59
uint16_t model[20]
Definition ata.h:152

References bswap_16, and ata_identity::model.

Referenced by atacmd_identify_done().

◆ atacmd_identify_done()

void atacmd_identify_done ( struct ata_command * atacmd,
int rc )
static

Handle ATA IDENTIFY command completion.

Parameters
atacmdATA command
rcReason for completion

Definition at line 371 of file ata.c.

371 {
372 struct ata_device *atadev = atacmd->atadev;
373 struct ata_identify_private *priv = atacmd_priv ( atacmd );
374 struct ata_identity *identity = &priv->identity;
375 struct block_device_capacity capacity;
376
377 /* Close if command failed */
378 if ( rc != 0 ) {
379 atacmd_close ( atacmd, rc );
380 return;
381 }
382
383 /* Extract capacity */
384 if ( identity->supports_lba48 & cpu_to_le16 ( ATA_SUPPORTS_LBA48 ) ) {
385 atadev->lba48 = 1;
386 capacity.blocks = le64_to_cpu ( identity->lba48_sectors );
387 } else {
388 capacity.blocks = le32_to_cpu ( identity->lba_sectors );
389 }
390 capacity.blksize = ATA_SECTOR_SIZE;
391 capacity.max_count = atadev->max_count;
392 DBGC ( atadev, "ATA %p is a %s\n", atadev, ata_model ( identity ) );
393 DBGC ( atadev, "ATA %p has %#llx blocks (%ld MB) and uses %s\n",
394 atadev, capacity.blocks,
395 ( ( signed long ) ( capacity.blocks >> 11 ) ),
396 ( atadev->lba48 ? "LBA48" : "LBA" ) );
397
398 /* Return capacity to caller */
399 block_capacity ( &atacmd->block, &capacity );
400
401 /* Close command */
402 atacmd_close ( atacmd, 0 );
403}
static const char * ata_model(struct ata_identity *identity)
Return ATA model string (for debugging).
Definition ata.c:352
static void atacmd_close(struct ata_command *atacmd, int rc)
Close ATA command.
Definition ata.c:251
#define ATA_SECTOR_SIZE
ATA sector size.
Definition ata.h:166
#define ATA_SUPPORTS_LBA48
Supports LBA48 flag.
Definition ata.h:163
void block_capacity(struct interface *intf, struct block_device_capacity *capacity)
Report block device capacity.
Definition blockdev.c:130
#define le64_to_cpu(value)
Definition byteswap.h:115
#define le32_to_cpu(value)
Definition byteswap.h:114
#define cpu_to_le16(value)
Definition byteswap.h:107
int lba48
Device uses LBA48 extended addressing.
Definition ata.c:106
unsigned int max_count
Maximum number of blocks per single transfer.
Definition ata.c:104
ATA IDENTIFY private data.
Definition ata.c:341
Structure returned by ATA IDENTIFY command.
Definition ata.h:150
uint64_t lba48_sectors
Definition ata.h:158
uint32_t lba_sectors
Definition ata.h:154
uint16_t supports_lba48
Definition ata.h:156
Block device capacity.
Definition blockdev.h:18
size_t blksize
Block size.
Definition blockdev.h:22
static struct tlan_private * priv
Definition tlan.c:225

References ata_model(), ATA_SECTOR_SIZE, ATA_SUPPORTS_LBA48, atacmd_close(), atacmd_priv(), ata_command::atadev, block_device_capacity::blksize, ata_command::block, block_capacity(), block_device_capacity::blocks, cpu_to_le16, DBGC, ata_device::lba48, ata_identity::lba48_sectors, ata_identity::lba_sectors, le32_to_cpu, le64_to_cpu, ata_device::max_count, block_device_capacity::max_count, priv, rc, and ata_identity::supports_lba48.

◆ atadev_command()

int atadev_command ( struct ata_device * atadev,
struct interface * block,
struct ata_command_type * type,
uint64_t lba,
unsigned int count,
void * buffer,
size_t len )
static

Create ATA command.

Parameters
atadevATA device
blockBlock data interface
typeATA command type
lbaStarting logical block address
countNumber of blocks to transfer
bufferData buffer
lenLength of data buffer
Return values
rcReturn status code

Definition at line 448 of file ata.c.

452 {
453 struct ata_command *atacmd;
454 struct ata_cmd command;
455 int tag;
456 int rc;
457
458 /* Allocate and initialise structure */
459 atacmd = zalloc ( sizeof ( *atacmd ) + type->priv_len );
460 if ( ! atacmd ) {
461 rc = -ENOMEM;
462 goto err_zalloc;
463 }
464 ref_init ( &atacmd->refcnt, atacmd_free );
465 intf_init ( &atacmd->block, &atacmd_block_desc, &atacmd->refcnt );
466 intf_init ( &atacmd->ata, &atacmd_ata_desc,
467 &atacmd->refcnt );
468 atacmd->atadev = atadev_get ( atadev );
469 list_add ( &atacmd->list, &ata_commands );
470 atacmd->type = type;
471
472 /* Sanity check */
473 if ( len != ( count * ATA_SECTOR_SIZE ) ) {
474 DBGC ( atadev, "ATA %p tag %08x buffer length mismatch (count "
475 "%d len %zd)\n", atadev, atacmd->tag, count, len );
476 rc = -EINVAL;
477 goto err_len;
478 }
479
480 /* Construct command */
481 memset ( &command, 0, sizeof ( command ) );
482 command.cb.lba.native = lba;
483 command.cb.count.native = count;
484 command.cb.device = ( atadev->device | ATA_DEV_OBSOLETE | ATA_DEV_LBA );
485 command.cb.lba48 = atadev->lba48;
486 if ( ! atadev->lba48 )
487 command.cb.device |= command.cb.lba.bytes.low_prev;
488 command.cb.cmd_stat =
489 ( atadev->lba48 ? type->cmd_lba48 : type->cmd_lba );
490 type->data_in ( atacmd, &command.data_in, buffer, len );
491 type->data_out ( atacmd, &command.data_out, buffer, len );
492
493 /* Issue command */
494 if ( ( tag = ata_command ( &atadev->ata, &atacmd->ata,
495 &command ) ) < 0 ) {
496 rc = tag;
497 DBGC ( atadev, "ATA %p tag %08x could not issue command: %s\n",
498 atadev, atacmd->tag, strerror ( rc ) );
499 goto err_command;
500 }
501 atacmd->tag = tag;
502
503 DBGC2 ( atadev, "ATA %p tag %08x %s cmd %02x dev %02x LBA%s %08llx "
504 "count %04x\n", atadev, atacmd->tag, atacmd->type->name,
505 command.cb.cmd_stat, command.cb.device,
506 ( command.cb.lba48 ? "48" : "" ),
507 ( unsigned long long ) command.cb.lba.native,
508 command.cb.count.native );
509
510 /* Attach to parent interface, mortalise self, and return */
511 intf_plug_plug ( &atacmd->block, block );
512 ref_put ( &atacmd->refcnt );
513 return 0;
514
515 err_command:
516 err_len:
517 atacmd_close ( atacmd, rc );
518 ref_put ( &atacmd->refcnt );
519 err_zalloc:
520 return rc;
521}
static void atacmd_free(struct refcnt *refcnt)
Free ATA command.
Definition ata.c:233
static struct interface_descriptor atacmd_ata_desc
ATA command ATA interface descriptor.
Definition ata.c:432
static struct ata_device * atadev_get(struct ata_device *atadev)
Get reference to ATA device.
Definition ata.c:180
static struct interface_descriptor atacmd_block_desc
ATA command block interface descriptor.
Definition ata.c:422
#define ATA_DEV_OBSOLETE
Obsolete bits in the ATA device register.
Definition ata.h:112
#define ATA_DEV_LBA
LBA flag in the ATA device register.
Definition ata.h:115
uint32_t type
Operating system type.
Definition ena.h:1
#define DBGC2(...)
Definition compiler.h:547
uint64_t lba
Starting block number.
Definition int13.h:11
static unsigned int count
Number of entries.
Definition dwmac.h:220
#define EINVAL
Invalid argument.
Definition errno.h:472
#define ENOMEM
Not enough space.
Definition errno.h:578
void * memset(void *dest, int character, size_t len) __nonnull
void intf_plug_plug(struct interface *a, struct interface *b)
Plug two object interfaces together.
Definition interface.c:108
static void intf_init(struct interface *intf, struct interface_descriptor *desc, struct refcnt *refcnt)
Initialise an object interface.
Definition interface.h:204
#define list_add(new, head)
Add a new entry to the head of a list.
Definition list.h:70
void * zalloc(size_t size)
Allocate cleared memory.
Definition malloc.c:718
uint8_t block[3][8]
DES-encrypted blocks.
Definition mschapv2.h:1
#define ref_init(refcnt, free)
Initialise a reference counter.
Definition refcnt.h:65
An ATA command information unit.
Definition ata.h:169
const char * name
Name.
Definition ata.c:135
unsigned int device
Device number.
Definition ata.c:102
struct interface ata
ATA control interface.
Definition ata.c:96

References ata_command::ata, ata_device::ata, ATA_DEV_LBA, ATA_DEV_OBSOLETE, ATA_SECTOR_SIZE, atacmd_ata_desc, atacmd_block_desc, atacmd_close(), atacmd_free(), ata_command::atadev, atadev_get(), ata_command::block, block, buffer, count, DBGC, DBGC2, ata_device::device, EINVAL, ENOMEM, intf_init(), intf_plug_plug(), lba, ata_device::lba48, len, ata_command::list, list_add, memset(), ata_command_type::name, rc, ref_init, ref_put, ata_command::refcnt, strerror(), ata_command::tag, tag, ata_command::type, type, and zalloc().

Referenced by atadev_read(), atadev_read_capacity(), and atadev_write().

◆ atadev_read()

int atadev_read ( struct ata_device * atadev,
struct interface * block,
uint64_t lba,
unsigned int count,
void * buffer,
size_t len )
static

Issue ATA block read.

Parameters
atadevATA device
blockBlock data interface
lbaStarting logical block address
countNumber of blocks to transfer
bufferData buffer
lenLength of data buffer
Return values
rcReturn status code

Definition at line 535 of file ata.c.

538 {
539 return atadev_command ( atadev, block, &atacmd_read,
540 lba, count, buffer, len );
541}
static int atadev_command(struct ata_device *atadev, struct interface *block, struct ata_command_type *type, uint64_t lba, unsigned int count, void *buffer, size_t len)
Create ATA command.
Definition ata.c:448
static struct ata_command_type atacmd_read
ATA READ command type.
Definition ata.c:321

References atacmd_read, atadev_command(), block, buffer, count, lba, and len.

◆ atadev_write()

int atadev_write ( struct ata_device * atadev,
struct interface * block,
uint64_t lba,
unsigned int count,
void * buffer,
size_t len )
static

Issue ATA block write.

Parameters
atadevATA device
blockBlock data interface
lbaStarting logical block address
countNumber of blocks to transfer
bufferData buffer
lenLength of data buffer
Return values
rcReturn status code

Definition at line 554 of file ata.c.

557 {
558 return atadev_command ( atadev, block, &atacmd_write,
559 lba, count, buffer, len );
560}
static struct ata_command_type atacmd_write
ATA WRITE command type.
Definition ata.c:331

References atacmd_write, atadev_command(), block, buffer, count, lba, and len.

◆ atadev_read_capacity()

int atadev_read_capacity ( struct ata_device * atadev,
struct interface * block )
static

Read ATA device capacity.

Parameters
atadevATA device
blockBlock data interface
Return values
rcReturn status code

Definition at line 569 of file ata.c.

570 {
571 struct ata_identity *identity;
572
573 assert ( atacmd_identify.priv_len == sizeof ( *identity ) );
574 assert ( atacmd_identify.priv_len == ATA_SECTOR_SIZE );
575 return atadev_command ( atadev, block, &atacmd_identify,
576 0, 1, NULL, ATA_SECTOR_SIZE );
577}
#define NULL
NULL pointer (VOID *).
Definition Base.h:321
#define assert(condition)
Assert a condition at run-time.
Definition assert.h:61
static struct ata_command_type atacmd_identify
ATA IDENTITY command type.
Definition ata.c:406

References assert, ATA_SECTOR_SIZE, atacmd_identify, atadev_command(), block, and NULL.

◆ atadev_close()

void atadev_close ( struct ata_device * atadev,
int rc )
static

Close ATA device.

Parameters
atadevATA device
rcReason for close

Definition at line 585 of file ata.c.

585 {
586 struct ata_command *atacmd;
587 struct ata_command *tmp;
588
589 /* Shut down interfaces */
591 intf_shutdown ( &atadev->ata, rc );
592
593 /* Shut down any remaining commands */
594 list_for_each_entry_safe ( atacmd, tmp, &ata_commands, list ) {
595 if ( atacmd->atadev != atadev )
596 continue;
597 atacmd_get ( atacmd );
598 atacmd_close ( atacmd, rc );
599 atacmd_put ( atacmd );
600 }
601}
static struct ata_command * atacmd_get(struct ata_command *atacmd)
Get reference to ATA command.
Definition ata.c:202
static void atacmd_put(struct ata_command *atacmd)
Drop reference to ATA command.
Definition ata.c:213
unsigned long tmp
Definition linux_pci.h:65
#define list_for_each_entry_safe(pos, tmp, head, member)
Iterate over entries in a list, safe against deletion of the current entry.
Definition list.h:459
struct interface block
Block control interface.
Definition ata.c:94

References ata_device::ata, atacmd_close(), atacmd_get(), atacmd_put(), ata_command::atadev, ata_device::block, intf_shutdown(), ata_command::list, list_for_each_entry_safe, rc, and tmp.

◆ atadev_edd_describe()

int atadev_edd_describe ( struct ata_device * atadev,
struct edd_interface_type * type,
union edd_device_path * path )
static

Describe ATA device using EDD.

Parameters
atadevATA device
typeEDD interface type
pathEDD device path
Return values
rcReturn status code

Definition at line 611 of file ata.c.

613 {
614
616 path->ata.slave = ( ( atadev->device == ATA_DEV_SLAVE ) ? 0x01 : 0x00 );
617 return 0;
618}
#define ATA_DEV_SLAVE
Slave ("device 1") flag in the ATA device register.
Definition ata.h:118
#define EDD_INTF_TYPE_ATA
EDD ATA interface type.
Definition edd.h:56
#define cpu_to_le64(value)
Definition byteswap.h:109
uint8_t slave
Slave.
Definition edd.h:103

References ATA_DEV_SLAVE, ata_command::atadev, cpu_to_le64, ata_device::device, EDD_INTF_TYPE_ATA, edd_device_path::slave, and type.

◆ ata_open()

int ata_open ( struct interface * block,
struct interface * ata,
unsigned int device,
unsigned int max_count )

Open ATA device.

Parameters
blockBlock control interface
ataATA control interface
deviceATA device number
max_countMaximum number of blocks per single transfer
Return values
rcReturn status code

Definition at line 654 of file ata.c.

655 {
656 struct ata_device *atadev;
657
658 /* Allocate and initialise structure */
659 atadev = zalloc ( sizeof ( *atadev ) );
660 if ( ! atadev )
661 return -ENOMEM;
662 ref_init ( &atadev->refcnt, NULL );
663 intf_init ( &atadev->block, &atadev_block_desc, &atadev->refcnt );
664 intf_init ( &atadev->ata, &atadev_ata_desc, &atadev->refcnt );
665 atadev->device = device;
666 atadev->max_count = max_count;
667
668 /* Attach to ATA and parent and interfaces, mortalise self,
669 * and return
670 */
671 intf_plug_plug ( &atadev->ata, ata );
672 intf_plug_plug ( &atadev->block, block );
673 ref_put ( &atadev->refcnt );
674 return 0;
675}
static struct interface_descriptor atadev_ata_desc
ATA device ATA interface descriptor.
Definition ata.c:641
static struct interface_descriptor atadev_block_desc
ATA device block interface descriptor.
Definition ata.c:631
A hardware device.
Definition device.h:77

References ata_device::ata, atadev_ata_desc, atadev_block_desc, ata_device::block, block, ata_device::device, ENOMEM, intf_init(), intf_plug_plug(), ata_device::max_count, NULL, ref_init, ref_put, ata_device::refcnt, and zalloc().

Referenced by aoedev_open().

Variable Documentation

◆ atacmd_read

struct ata_command_type atacmd_read
static
Initial value:
= {
.name = "READ",
.cmd_lba = ATA_CMD_READ,
.cmd_lba48 = ATA_CMD_READ_EXT,
.data_in = atacmd_data_buffer,
.data_out = atacmd_data_none,
.done = atacmd_close,
}
static void atacmd_data_buffer(struct ata_command *atacmd __unused, struct xfer_buffer *xferbuf, void *buffer, size_t len)
Use provided data buffer for ATA command.
Definition ata.c:284
static void atacmd_data_none(struct ata_command *atacmd __unused, struct xfer_buffer *xferbuf, void *buffer __unused, size_t len __unused)
Use no data buffer for ATA command.
Definition ata.c:298
#define ATA_CMD_READ_EXT
"Read sectors (ext)" command
Definition ata.h:130
#define ATA_CMD_READ
"Read sectors" command
Definition ata.h:127

ATA READ command type.

Definition at line 321 of file ata.c.

321 {
322 .name = "READ",
323 .cmd_lba = ATA_CMD_READ,
324 .cmd_lba48 = ATA_CMD_READ_EXT,
325 .data_in = atacmd_data_buffer,
326 .data_out = atacmd_data_none,
327 .done = atacmd_close,
328};

Referenced by atadev_read().

◆ atacmd_write

struct ata_command_type atacmd_write
static
Initial value:
= {
.name = "WRITE",
.cmd_lba = ATA_CMD_WRITE,
.cmd_lba48 = ATA_CMD_WRITE_EXT,
.data_in = atacmd_data_none,
.data_out = atacmd_data_buffer,
.done = atacmd_close,
}
#define ATA_CMD_WRITE
"Write sectors" command
Definition ata.h:133
#define ATA_CMD_WRITE_EXT
"Write sectors (ext)" command
Definition ata.h:136

ATA WRITE command type.

Definition at line 331 of file ata.c.

331 {
332 .name = "WRITE",
333 .cmd_lba = ATA_CMD_WRITE,
334 .cmd_lba48 = ATA_CMD_WRITE_EXT,
335 .data_in = atacmd_data_none,
336 .data_out = atacmd_data_buffer,
337 .done = atacmd_close,
338};

Referenced by atadev_write().

◆ atacmd_identify

struct ata_command_type atacmd_identify
static
Initial value:
= {
.name = "IDENTIFY",
.priv_len = sizeof ( struct ata_identify_private ),
.cmd_lba = ATA_CMD_IDENTIFY,
.cmd_lba48 = ATA_CMD_IDENTIFY,
.data_in = atacmd_data_priv,
.data_out = atacmd_data_none,
}
static void atacmd_identify_done(struct ata_command *atacmd, int rc)
Handle ATA IDENTIFY command completion.
Definition ata.c:371
static void atacmd_data_priv(struct ata_command *atacmd, struct xfer_buffer *xferbuf, void *buffer __unused, size_t len __unused)
Use private data buffer for ATA command.
Definition ata.c:312
#define ATA_CMD_IDENTIFY
"Identify" command
Definition ata.h:139

ATA IDENTITY command type.

Definition at line 406 of file ata.c.

406 {
407 .name = "IDENTIFY",
408 .priv_len = sizeof ( struct ata_identify_private ),
409 .cmd_lba = ATA_CMD_IDENTIFY,
410 .cmd_lba48 = ATA_CMD_IDENTIFY,
411 .data_in = atacmd_data_priv,
412 .data_out = atacmd_data_none,
413 .done = atacmd_identify_done,
414};

Referenced by atadev_read_capacity().

◆ atacmd_block_op

struct interface_operation atacmd_block_op[]
static
Initial value:
= {
}
void intf_close(struct interface *intf, int rc)
Close an object interface.
Definition interface.c:250
#define INTF_OP(op_type, object_type, op_func)
Define an object interface operation.
Definition interface.h:33

ATA command block interface operations.

Definition at line 417 of file ata.c.

417 {
419};

◆ atacmd_block_desc

struct interface_descriptor atacmd_block_desc
static
Initial value:
=
static struct interface_operation atacmd_block_op[]
ATA command block interface operations.
Definition ata.c:417
#define INTF_DESC_PASSTHRU(object_type, intf, operations, passthru)
Define an object interface descriptor with pass-through interface.
Definition interface.h:98

ATA command block interface descriptor.

Definition at line 422 of file ata.c.

Referenced by atadev_command().

◆ atacmd_ata_op

struct interface_operation atacmd_ata_op[]
static
Initial value:
= {
}
static void atacmd_done(struct ata_command *atacmd, int rc)
Handle ATA command completion.
Definition ata.c:270

ATA command ATA interface operations.

Definition at line 427 of file ata.c.

427 {
429};

◆ atacmd_ata_desc

struct interface_descriptor atacmd_ata_desc
static
Initial value:
=
static struct interface_operation atacmd_ata_op[]
ATA command ATA interface operations.
Definition ata.c:427

ATA command ATA interface descriptor.

Definition at line 432 of file ata.c.

Referenced by atadev_command().

◆ atadev_block_op

struct interface_operation atadev_block_op[]
static
Initial value:
= {
}
static int atadev_read_capacity(struct ata_device *atadev, struct interface *block)
Read ATA device capacity.
Definition ata.c:569
static int atadev_edd_describe(struct ata_device *atadev, struct edd_interface_type *type, union edd_device_path *path)
Describe ATA device using EDD.
Definition ata.c:611
static void atadev_close(struct ata_device *atadev, int rc)
Close ATA device.
Definition ata.c:585
static int atadev_read(struct ata_device *atadev, struct interface *block, uint64_t lba, unsigned int count, void *buffer, size_t len)
Issue ATA block read.
Definition ata.c:535
static int atadev_write(struct ata_device *atadev, struct interface *block, uint64_t lba, unsigned int count, void *buffer, size_t len)
Issue ATA block write.
Definition ata.c:554
int block_read_capacity(struct interface *control, struct interface *data)
Read block device capacity.
Definition blockdev.c:106
int block_write(struct interface *control, struct interface *data, uint64_t lba, unsigned int count, void *buffer, size_t len)
Write to block device.
Definition blockdev.c:79
int block_read(struct interface *control, struct interface *data, uint64_t lba, unsigned int count, void *buffer, size_t len)
Read from block device.
Definition blockdev.c:48
int edd_describe(struct interface *intf, struct edd_interface_type *type, union edd_device_path *path)
Describe a disk device using EDD.
Definition edd.c:45

ATA device block interface operations.

Definition at line 621 of file ata.c.

◆ atadev_block_desc

struct interface_descriptor atadev_block_desc
static
Initial value:
=
static struct interface_operation atadev_block_op[]
ATA device block interface operations.
Definition ata.c:621

ATA device block interface descriptor.

Definition at line 631 of file ata.c.

Referenced by ata_open().

◆ atadev_ata_op

struct interface_operation atadev_ata_op[]
static
Initial value:
= {
}

ATA device ATA interface operations.

Definition at line 636 of file ata.c.

636 {
638};

◆ atadev_ata_desc

struct interface_descriptor atadev_ata_desc
static
Initial value:
=
static struct interface_operation atadev_ata_op[]
ATA device ATA interface operations.
Definition ata.c:636

ATA device ATA interface descriptor.

Definition at line 641 of file ata.c.

Referenced by ata_open().