blob: c4cfd4029339f7d12a48b31806da2112d1d6f90f [file] [log] [blame]
Nico Huber1f6bd942012-08-30 15:36:57 +02001/*
2 * This file is part of the libpayload project.
3 *
4 * Copyright (C) 2012 secunet Security Networks AG
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30#include <libpayload.h>
Stefan Reinauer1b4d3942015-06-29 15:47:34 -070031#if IS_ENABLED(CONFIG_LP_STORAGE_AHCI)
Nico Huber1f6bd942012-08-30 15:36:57 +020032# include <storage/ahci.h>
33#endif
34#include <storage/storage.h>
35
36
37static storage_dev_t **devices = NULL;
38static size_t devices_length = 0;
39static size_t dev_count = 0;
40
41int storage_attach_device(storage_dev_t *const dev)
42{
43 if (dev_count == devices_length) {
44 const size_t new_len =
45 (0 == devices_length) ? 4 : devices_length << 1;
46 storage_dev_t **const new_devices =
47 realloc(devices, new_len * sizeof(storage_dev_t *));
48 if (!new_devices)
49 return -1;
50 devices = new_devices;
51 memset(devices + devices_length, '\0',
52 (new_len - devices_length) * sizeof(storage_dev_t *));
53 devices_length = new_len;
54 }
55 devices[dev_count++] = dev;
56
57 return 0;
58}
59
Patrick Georgi45b94bc2012-10-09 12:52:05 +020060int storage_device_count(void)
61{
62 return dev_count;
63}
64
Nico Huber1f6bd942012-08-30 15:36:57 +020065/**
66 * Probe for drive with given number
67 *
68 * Looks for a drive with number dev_num and polls for a medium
69 * in the drive if appropriate.
70 *
71 * @dev_num device number counted from 0
72 */
73storage_poll_t storage_probe(const size_t dev_num)
74{
75 if (dev_num >= dev_count)
76 return POLL_NO_DEVICE;
77 else if (devices[dev_num]->poll)
78 return devices[dev_num]->poll(devices[dev_num]);
79 else
80 return POLL_MEDIUM_PRESENT;
81}
82
83/**
84 * Read 512-byte blocks
85 *
86 * Reads count blocks of 512 bytes from block start of drive dev_num
87 * into buf.
88 *
89 * @dev_num device number counted from 0
90 * @start number of first block to read from
91 * @count number of blocks to read
92 * @buf buffer where the read data should be written
93 */
94ssize_t storage_read_blocks512(const size_t dev_num,
95 const lba_t start, const size_t count,
96 unsigned char *const buf)
97{
98 if ((dev_num < dev_count) && devices[dev_num]->read_blocks512)
99 return devices[dev_num]->read_blocks512(
100 devices[dev_num], start, count, buf);
101 else
102 return -1;
103}
104
105/**
106 * Initializes storage controllers
107 *
108 * This function should be called once at startup to bring up supported
Paul Menzel109a7102013-04-11 15:19:04 +0200109 * storage controllers.
Nico Huber1f6bd942012-08-30 15:36:57 +0200110 */
111void storage_initialize(void)
112{
Stefan Reinauer1b4d3942015-06-29 15:47:34 -0700113#if IS_ENABLED(CONFIG_LP_STORAGE_AHCI)
Nico Huber1f6bd942012-08-30 15:36:57 +0200114 ahci_initialize();
115#endif
116}