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 __attribute__ ((always_inline))
 Get reference to ATA device.
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, void *buffer, size_t len, void **data, size_t *data_len)
 Use provided data buffer for ATA command.
static void atacmd_data_none (struct ata_command *atacmd __unused, void *buffer __unused, size_t len __unused, void **data __unused, size_t *data_len __unused)
 Use no data buffer for ATA command.
static void atacmd_data_priv (struct ata_command *atacmd, void *buffer __unused, size_t len __unused, void **data, size_t *data_len)
 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:197
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:605
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.

◆ __attribute__()

__attribute__ ( (always_inline) )
inlinestatic

Get reference to ATA device.

Get ATA command private data.

Drop reference to ATA command.

Get reference to ATA command.

Drop reference to ATA device.

Parameters
atadevATA device
Return values
atadevATA device
Parameters
atadevATA device
atacmdATA command
Return values
atacmdATA command
Parameters
atacmdATA command
atacmdATA command
Return values
privPrivate data

Definition at line 182 of file ata.c.

183 {
184 ref_get ( &atadev->refcnt );
185 return atadev;
186}
#define ref_get(refcnt)
Get additional reference to object.
Definition refcnt.h:93

References ref_get, and ata_device::refcnt.

◆ atacmd_free()

void atacmd_free ( struct refcnt * refcnt)
static

Free ATA command.

Parameters
refcntReference count

Definition at line 236 of file ata.c.

236 {
237 struct ata_command *atacmd =
239
240 /* Remove from list of commands */
241 list_del ( &atacmd->list );
242 atadev_put ( atacmd->atadev );
243
244 /* Free command */
245 free ( atacmd );
246}
#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, 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 254 of file ata.c.

254 {
255 struct ata_device *atadev = atacmd->atadev;
256
257 if ( rc != 0 ) {
258 DBGC ( atadev, "ATA %p tag %08x closed: %s\n",
259 atadev, atacmd->tag, strerror ( rc ) );
260 }
261
262 /* Shut down interfaces */
263 intf_shutdown ( &atacmd->ata, rc );
264 intf_shutdown ( &atacmd->block, rc );
265}
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
#define DBGC(...)
Definition compiler.h:505
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 273 of file ata.c.

273 {
274
275 /* Hand over to the command completion handler */
276 atacmd->type->done ( atacmd, rc );
277}
void(* done)(struct ata_command *atacmd, int rc)
Handle ATA command completion.
Definition ata.c:173
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,
void * buffer,
size_t len,
void ** data,
size_t * data_len )
static

Use provided data buffer for ATA command.

Parameters
atacmdATA command
bufferAvailable buffer
lenAvailable buffer length
Return values
dataData buffer
data_lenData buffer length

Definition at line 288 of file ata.c.

290 {
291 *data = buffer;
292 *data_len = len;
293}
ring len
Length.
Definition dwmac.h:226
uint32_t buffer
Buffer index (or NETVSC_RNDIS_NO_BUFFER)
Definition netvsc.h:5
uint32_t data_len
Microcode data size (or 0 to indicate 2000 bytes)
Definition ucode.h:15

References __unused, buffer, data, data_len, and len.

◆ atacmd_data_none()

void atacmd_data_none ( struct ata_command *atacmd __unused,
void *buffer __unused,
size_t len __unused,
void **data __unused,
size_t *data_len __unused )
static

Use no data buffer for ATA command.

Parameters
atacmdATA command
bufferAvailable buffer
lenAvailable buffer length
Return values
dataData buffer
data_lenData buffer length

Definition at line 304 of file ata.c.

307 {
308 /* Nothing to do */
309}

References __unused, buffer, data, data_len, and len.

◆ atacmd_data_priv()

void atacmd_data_priv ( struct ata_command * atacmd,
void *buffer __unused,
size_t len __unused,
void ** data,
size_t * data_len )
static

Use private data buffer for ATA command.

Parameters
atacmdATA command
bufferAvailable buffer
lenAvailable buffer length
Return values
dataData buffer
data_lenData buffer length

Definition at line 320 of file ata.c.

322 {
323 *data = atacmd_priv ( atacmd );
324 *data_len = atacmd->type->priv_len;
325}
size_t priv_len
Additional working space.
Definition ata.c:137

References __unused, buffer, data, data_len, len, ata_command_type::priv_len, and ata_command::type.

◆ 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 359 of file ata.c.

359 {
360 static union {
361 uint16_t words[ sizeof ( identity->model ) / 2 ];
362 char text[ sizeof ( identity->model ) + 1 /* NUL */ ];
363 } buf;
364 unsigned int i;
365
366 for ( i = 0 ; i < ( sizeof ( identity->model ) / 2 ) ; i++ )
367 buf.words[i] = bswap_16 ( identity->model[i] );
368
369 return buf.text;
370}
unsigned short uint16_t
Definition stdint.h:11
#define bswap_16(value)
Definition byteswap.h:59
uint16_t model[20]
Definition ata.h:151

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 378 of file ata.c.

378 {
379 struct ata_device *atadev = atacmd->atadev;
380 struct ata_identify_private *priv = atacmd_priv ( atacmd );
381 struct ata_identity *identity = &priv->identity;
382 struct block_device_capacity capacity;
383
384 /* Close if command failed */
385 if ( rc != 0 ) {
386 atacmd_close ( atacmd, rc );
387 return;
388 }
389
390 /* Extract capacity */
391 if ( identity->supports_lba48 & cpu_to_le16 ( ATA_SUPPORTS_LBA48 ) ) {
392 atadev->lba48 = 1;
393 capacity.blocks = le64_to_cpu ( identity->lba48_sectors );
394 } else {
395 capacity.blocks = le32_to_cpu ( identity->lba_sectors );
396 }
397 capacity.blksize = ATA_SECTOR_SIZE;
398 capacity.max_count = atadev->max_count;
399 DBGC ( atadev, "ATA %p is a %s\n", atadev, ata_model ( identity ) );
400 DBGC ( atadev, "ATA %p has %#llx blocks (%ld MB) and uses %s\n",
401 atadev, capacity.blocks,
402 ( ( signed long ) ( capacity.blocks >> 11 ) ),
403 ( atadev->lba48 ? "LBA48" : "LBA" ) );
404
405 /* Return capacity to caller */
406 block_capacity ( &atacmd->block, &capacity );
407
408 /* Close command */
409 atacmd_close ( atacmd, 0 );
410}
static const char * ata_model(struct ata_identity *identity)
Return ATA model string (for debugging)
Definition ata.c:359
static void atacmd_close(struct ata_command *atacmd, int rc)
Close ATA command.
Definition ata.c:254
#define ATA_SECTOR_SIZE
ATA sector size.
Definition ata.h:165
#define ATA_SUPPORTS_LBA48
Supports LBA48 flag.
Definition ata.h:162
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:348
Structure returned by ATA IDENTIFY command.
Definition ata.h:149
uint64_t lba48_sectors
Definition ata.h:157
uint32_t lba_sectors
Definition ata.h:153
uint16_t supports_lba48
Definition ata.h:155
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(), 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 455 of file ata.c.

459 {
460 struct ata_command *atacmd;
461 struct ata_cmd command;
462 int tag;
463 int rc;
464
465 /* Allocate and initialise structure */
466 atacmd = zalloc ( sizeof ( *atacmd ) + type->priv_len );
467 if ( ! atacmd ) {
468 rc = -ENOMEM;
469 goto err_zalloc;
470 }
471 ref_init ( &atacmd->refcnt, atacmd_free );
472 intf_init ( &atacmd->block, &atacmd_block_desc, &atacmd->refcnt );
473 intf_init ( &atacmd->ata, &atacmd_ata_desc,
474 &atacmd->refcnt );
475 atacmd->atadev = atadev_get ( atadev );
476 list_add ( &atacmd->list, &ata_commands );
477 atacmd->type = type;
478
479 /* Sanity check */
480 if ( len != ( count * ATA_SECTOR_SIZE ) ) {
481 DBGC ( atadev, "ATA %p tag %08x buffer length mismatch (count "
482 "%d len %zd)\n", atadev, atacmd->tag, count, len );
483 rc = -EINVAL;
484 goto err_len;
485 }
486
487 /* Construct command */
488 memset ( &command, 0, sizeof ( command ) );
489 command.cb.lba.native = lba;
490 command.cb.count.native = count;
491 command.cb.device = ( atadev->device | ATA_DEV_OBSOLETE | ATA_DEV_LBA );
492 command.cb.lba48 = atadev->lba48;
493 if ( ! atadev->lba48 )
494 command.cb.device |= command.cb.lba.bytes.low_prev;
495 command.cb.cmd_stat =
496 ( atadev->lba48 ? type->cmd_lba48 : type->cmd_lba );
497 type->data_in ( atacmd, buffer, len,
498 &command.data_in, &command.data_in_len );
499 type->data_out ( atacmd, buffer, len,
500 &command.data_out, &command.data_out_len );
501
502 /* Issue command */
503 if ( ( tag = ata_command ( &atadev->ata, &atacmd->ata,
504 &command ) ) < 0 ) {
505 rc = tag;
506 DBGC ( atadev, "ATA %p tag %08x could not issue command: %s\n",
507 atadev, atacmd->tag, strerror ( rc ) );
508 goto err_command;
509 }
510 atacmd->tag = tag;
511
512 DBGC2 ( atadev, "ATA %p tag %08x %s cmd %02x dev %02x LBA%s %08llx "
513 "count %04x\n", atadev, atacmd->tag, atacmd->type->name,
514 command.cb.cmd_stat, command.cb.device,
515 ( command.cb.lba48 ? "48" : "" ),
516 ( unsigned long long ) command.cb.lba.native,
517 command.cb.count.native );
518
519 /* Attach to parent interface, mortalise self, and return */
520 intf_plug_plug ( &atacmd->block, block );
521 ref_put ( &atacmd->refcnt );
522 return 0;
523
524 err_command:
525 err_len:
526 atacmd_close ( atacmd, rc );
527 ref_put ( &atacmd->refcnt );
528 err_zalloc:
529 return rc;
530}
static void atacmd_free(struct refcnt *refcnt)
Free ATA command.
Definition ata.c:236
static struct interface_descriptor atacmd_ata_desc
ATA command ATA interface descriptor.
Definition ata.c:439
static struct interface_descriptor atacmd_block_desc
ATA command block interface descriptor.
Definition ata.c:429
#define ATA_DEV_OBSOLETE
Obsolete bits in the ATA device register.
Definition ata.h:111
#define ATA_DEV_LBA
LBA flag in the ATA device register.
Definition ata.h:114
uint32_t type
Operating system type.
Definition ena.h:1
#define DBGC2(...)
Definition compiler.h:522
static unsigned int count
Number of entries.
Definition dwmac.h:220
uint64_t lba
Starting block number.
Definition int13.h:11
#define EINVAL
Invalid argument.
Definition errno.h:429
#define ENOMEM
Not enough space.
Definition errno.h:535
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:662
uint8_t block[3][8]
DES-encrypted blocks.
Definition mschapv2.h:1
#define ref_put(refcnt)
Drop reference to object.
Definition refcnt.h:107
#define ref_init(refcnt, free)
Initialise a reference counter.
Definition refcnt.h:65
An ATA command information unit.
Definition ata.h:168
const char * name
Name.
Definition ata.c:135
struct refcnt refcnt
Reference count.
Definition ata.c:112
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, 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 544 of file ata.c.

547 {
548 return atadev_command ( atadev, block, &atacmd_read,
549 lba, count, buffer, len );
550}
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:455
static struct ata_command_type atacmd_read
ATA READ command type.
Definition ata.c:328

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 563 of file ata.c.

566 {
567 return atadev_command ( atadev, block, &atacmd_write,
568 lba, count, buffer, len );
569}
static struct ata_command_type atacmd_write
ATA WRITE command type.
Definition ata.c:338

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 578 of file ata.c.

579 {
580 struct ata_identity *identity;
581
582 assert ( atacmd_identify.priv_len == sizeof ( *identity ) );
583 assert ( atacmd_identify.priv_len == ATA_SECTOR_SIZE );
584 return atadev_command ( atadev, block, &atacmd_identify,
585 0, 1, NULL, ATA_SECTOR_SIZE );
586}
#define NULL
NULL pointer (VOID *)
Definition Base.h:322
#define assert(condition)
Assert a condition at run-time.
Definition assert.h:50
static struct ata_command_type atacmd_identify
ATA IDENTITY command type.
Definition ata.c:413

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 594 of file ata.c.

594 {
595 struct ata_command *atacmd;
596 struct ata_command *tmp;
597
598 /* Shut down interfaces */
600 intf_shutdown ( &atadev->ata, rc );
601
602 /* Shut down any remaining commands */
603 list_for_each_entry_safe ( atacmd, tmp, &ata_commands, list ) {
604 if ( atacmd->atadev != atadev )
605 continue;
606 atacmd_get ( atacmd );
607 atacmd_close ( atacmd, rc );
608 atacmd_put ( atacmd );
609 }
610}
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(), 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 620 of file ata.c.

622 {
623
625 path->ata.slave = ( ( atadev->device == ATA_DEV_SLAVE ) ? 0x01 : 0x00 );
626 return 0;
627}
#define ATA_DEV_SLAVE
Slave ("device 1") flag in the ATA device register.
Definition ata.h:117
#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 663 of file ata.c.

664 {
665 struct ata_device *atadev;
666
667 /* Allocate and initialise structure */
668 atadev = zalloc ( sizeof ( *atadev ) );
669 if ( ! atadev )
670 return -ENOMEM;
671 ref_init ( &atadev->refcnt, NULL );
672 intf_init ( &atadev->block, &atadev_block_desc, &atadev->refcnt );
673 intf_init ( &atadev->ata, &atadev_ata_desc, &atadev->refcnt );
674 atadev->device = device;
675 atadev->max_count = max_count;
676
677 /* Attach to ATA and parent and interfaces, mortalise self,
678 * and return
679 */
680 intf_plug_plug ( &atadev->ata, ata );
681 intf_plug_plug ( &atadev->block, block );
682 ref_put ( &atadev->refcnt );
683 return 0;
684}
static struct interface_descriptor atadev_ata_desc
ATA device ATA interface descriptor.
Definition ata.c:650
static struct interface_descriptor atadev_block_desc
ATA device block interface descriptor.
Definition ata.c:640
struct refcnt refcnt
Reference count.
Definition ata.c:92
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_none(struct ata_command *atacmd __unused, void *buffer __unused, size_t len __unused, void **data __unused, size_t *data_len __unused)
Use no data buffer for ATA command.
Definition ata.c:304
static void atacmd_data_buffer(struct ata_command *atacmd __unused, void *buffer, size_t len, void **data, size_t *data_len)
Use provided data buffer for ATA command.
Definition ata.c:288
#define ATA_CMD_READ_EXT
"Read sectors (ext)" command
Definition ata.h:129
#define ATA_CMD_READ
"Read sectors" command
Definition ata.h:126

ATA READ command type.

Definition at line 328 of file ata.c.

328 {
329 .name = "READ",
330 .cmd_lba = ATA_CMD_READ,
331 .cmd_lba48 = ATA_CMD_READ_EXT,
332 .data_in = atacmd_data_buffer,
333 .data_out = atacmd_data_none,
334 .done = atacmd_close,
335};

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:132
#define ATA_CMD_WRITE_EXT
"Write sectors (ext)" command
Definition ata.h:135

ATA WRITE command type.

Definition at line 338 of file ata.c.

338 {
339 .name = "WRITE",
340 .cmd_lba = ATA_CMD_WRITE,
341 .cmd_lba48 = ATA_CMD_WRITE_EXT,
342 .data_in = atacmd_data_none,
343 .data_out = atacmd_data_buffer,
344 .done = atacmd_close,
345};

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_data_priv(struct ata_command *atacmd, void *buffer __unused, size_t len __unused, void **data, size_t *data_len)
Use private data buffer for ATA command.
Definition ata.c:320
static void atacmd_identify_done(struct ata_command *atacmd, int rc)
Handle ATA IDENTIFY command completion.
Definition ata.c:378
#define ATA_CMD_IDENTIFY
"Identify" command
Definition ata.h:138

ATA IDENTITY command type.

Definition at line 413 of file ata.c.

413 {
414 .name = "IDENTIFY",
415 .priv_len = sizeof ( struct ata_identify_private ),
416 .cmd_lba = ATA_CMD_IDENTIFY,
417 .cmd_lba48 = ATA_CMD_IDENTIFY,
418 .data_in = atacmd_data_priv,
419 .data_out = atacmd_data_none,
420 .done = atacmd_identify_done,
421};

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 424 of file ata.c.

424 {
426};

◆ 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:424
#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 429 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:273

ATA command ATA interface operations.

Definition at line 434 of file ata.c.

434 {
436};

◆ 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:434

ATA command ATA interface descriptor.

Definition at line 439 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:578
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:620
static void atadev_close(struct ata_device *atadev, int rc)
Close ATA device.
Definition ata.c:594
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:544
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:563
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 630 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:630

ATA device block interface descriptor.

Definition at line 640 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 645 of file ata.c.

645 {
647};

◆ 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:645

ATA device ATA interface descriptor.

Definition at line 650 of file ata.c.

Referenced by ata_open().