soc/intel/xeon_sp/util: Enhance lock_pam0123
[coreboot2.git] / payloads / libpayload / drivers / storage / storage.c
bloba1c1b459cfa0e6132899b617b2725abf56d8e26e
1 /*
3 * Copyright (C) 2012 secunet Security Networks AG
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
29 #include <libpayload.h>
30 #include <pci/pci.h>
31 #include <storage/ahci.h>
32 #include <storage/nvme.h>
33 #include <storage/storage.h>
35 static storage_dev_t **devices = NULL;
36 static size_t devices_length = 0;
37 static size_t dev_count = 0;
39 int storage_attach_device(storage_dev_t *const dev)
41 if (dev_count == devices_length) {
42 const size_t new_len =
43 (0 == devices_length) ? 4 : devices_length << 1;
44 storage_dev_t **const new_devices =
45 realloc(devices, new_len * sizeof(storage_dev_t *));
46 if (!new_devices)
47 return -1;
48 devices = new_devices;
49 memset(devices + devices_length, '\0',
50 (new_len - devices_length) * sizeof(storage_dev_t *));
51 devices_length = new_len;
53 devices[dev_count++] = dev;
55 return 0;
58 int storage_device_count(void)
60 return dev_count;
63 /**
64 * Probe for drive with given number
66 * Looks for a drive with number dev_num and polls for a medium
67 * in the drive if appropriate.
69 * @dev_num device number counted from 0
71 storage_poll_t storage_probe(const size_t dev_num)
73 if (dev_num >= dev_count)
74 return POLL_NO_DEVICE;
75 else if (devices[dev_num]->poll)
76 return devices[dev_num]->poll(devices[dev_num]);
77 else
78 return POLL_MEDIUM_PRESENT;
81 /**
82 * Read 512-byte blocks
84 * Reads count blocks of 512 bytes from block start of drive dev_num
85 * into buf.
87 * @dev_num device number counted from 0
88 * @start number of first block to read from
89 * @count number of blocks to read
90 * @buf buffer where the read data should be written
92 ssize_t storage_read_blocks512(const size_t dev_num,
93 const lba_t start, const size_t count,
94 unsigned char *const buf)
96 if ((dev_num < dev_count) && devices[dev_num]->read_blocks512)
97 return devices[dev_num]->read_blocks512(
98 devices[dev_num], start, count, buf);
99 else
100 return -1;
104 * Initializes storage controllers
106 * This function should be called once at startup to bring up supported
107 * storage controllers.
109 void storage_initialize(void)
111 #if CONFIG(LP_PCI)
112 struct pci_dev *dev;
113 for (dev = lib_sysinfo.pacc.devices; dev; dev = dev->next) {
114 switch (dev->device_class) {
115 #if CONFIG(LP_STORAGE_AHCI)
116 case PCI_CLASS_STORAGE_AHCI:
117 ahci_initialize(dev);
118 break;
119 #endif
120 #if CONFIG(LP_STORAGE_NVME)
121 case PCI_CLASS_STORAGE_NVME:
122 nvme_initialize(dev);
123 break;
124 #endif
125 default:
126 break;
129 #endif