1 /*
2  * Copyright (C) 2017 Michael Brown <mbrown@fensystems.co.uk>.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  * 02110-1301, USA.
18  *
19  * You can also choose to distribute this program under the terms of
20  * the Unmodified Binary Distribution Licence (as given in the file
21  * COPYING.UBDL), provided that you have satisfied its requirements.
22  */
23 
24 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25 
26 /** @file
27  *
28  * Dummy SAN device
29  *
30  */
31 
32 #include <errno.h>
33 #include <ipxe/sanboot.h>
34 
35 /**
36  * Hook dummy SAN device
37  *
38  * @v drive		Drive number
39  * @v uris		List of URIs
40  * @v count		Number of URIs
41  * @v flags		Flags
42  * @ret drive		Drive number, or negative error
43  */
dummy_san_hook(unsigned int drive,struct uri ** uris,unsigned int count,unsigned int flags)44 static int dummy_san_hook ( unsigned int drive, struct uri **uris,
45 			    unsigned int count, unsigned int flags ) {
46 	struct san_device *sandev;
47 	int rc;
48 
49 	/* Allocate SAN device */
50 	sandev = alloc_sandev ( uris, count, 0 );
51 	if ( ! sandev ) {
52 		rc = -ENOMEM;
53 		goto err_alloc;
54 	}
55 
56 	/* Register SAN device */
57 	if ( ( rc = register_sandev ( sandev, drive, flags ) ) != 0 ) {
58 		DBGC ( sandev, "SAN %#02x could not register: %s\n",
59 		       sandev->drive, strerror ( rc ) );
60 		goto err_register;
61 	}
62 
63 	return drive;
64 
65 	unregister_sandev ( sandev );
66  err_register:
67 	sandev_put ( sandev );
68  err_alloc:
69 	return rc;
70 }
71 
72 /**
73  * Unhook dummy SAN device
74  *
75  * @v drive		Drive number
76  */
dummy_san_unhook(unsigned int drive)77 static void dummy_san_unhook ( unsigned int drive ) {
78 	struct san_device *sandev;
79 
80 	/* Find drive */
81 	sandev = sandev_find ( drive );
82 	if ( ! sandev ) {
83 		DBG ( "SAN %#02x does not exist\n", drive );
84 		return;
85 	}
86 
87 	/* Unregister SAN device */
88 	unregister_sandev ( sandev );
89 
90 	/* Drop reference to drive */
91 	sandev_put ( sandev );
92 }
93 
94 /**
95  * Boot from dummy SAN device
96  *
97  * @v drive		Drive number
98  * @v filename		Filename (or NULL to use default)
99  * @ret rc		Return status code
100  */
dummy_san_boot(unsigned int drive __unused,const char * filename __unused)101 static int dummy_san_boot ( unsigned int drive __unused,
102 			    const char *filename __unused ) {
103 
104 	return -EOPNOTSUPP;
105 }
106 
107 /**
108  * Install ACPI table
109  *
110  * @v acpi		ACPI description header
111  * @ret rc		Return status code
112  */
dummy_install(struct acpi_header * acpi)113 static int dummy_install ( struct acpi_header *acpi ) {
114 
115 	DBGC ( acpi, "ACPI table %s:\n", acpi_name ( acpi->signature ) );
116 	DBGC_HDA ( acpi, 0, acpi, le32_to_cpu ( acpi->length ) );
117 	return 0;
118 }
119 
120 /**
121  * Describe dummy SAN device
122  *
123  * @ret rc		Return status code
124  */
dummy_san_describe(void)125 static int dummy_san_describe ( void ) {
126 
127 	return acpi_install ( dummy_install );
128 }
129 
130 PROVIDE_SANBOOT ( dummy, san_hook, dummy_san_hook );
131 PROVIDE_SANBOOT ( dummy, san_unhook, dummy_san_unhook );
132 PROVIDE_SANBOOT ( dummy, san_boot, dummy_san_boot );
133 PROVIDE_SANBOOT ( dummy, san_describe, dummy_san_describe );
134