Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

sanboot.c 20KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769
  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. FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
  24. /**
  25. * @file
  26. *
  27. * SAN booting
  28. *
  29. */
  30. #include <stdint.h>
  31. #include <stdlib.h>
  32. #include <errno.h>
  33. #include <assert.h>
  34. #include <ipxe/xfer.h>
  35. #include <ipxe/open.h>
  36. #include <ipxe/timer.h>
  37. #include <ipxe/process.h>
  38. #include <ipxe/iso9660.h>
  39. #include <ipxe/dhcp.h>
  40. #include <ipxe/settings.h>
  41. #include <ipxe/sanboot.h>
  42. /**
  43. * Default SAN drive number
  44. *
  45. * The drive number is a meaningful concept only in a BIOS
  46. * environment, where it represents the INT13 drive number (0x80 for
  47. * the first hard disk). We retain it in other environments to allow
  48. * for a simple way for iPXE commands to refer to SAN drives.
  49. */
  50. #define SAN_DEFAULT_DRIVE 0x80
  51. /**
  52. * Timeout for block device commands (in ticks)
  53. *
  54. * Underlying devices should ideally never become totally stuck.
  55. * However, if they do, then the blocking SAN APIs provide no means
  56. * for the caller to cancel the operation, and the machine appears to
  57. * hang. Use an overall timeout for all commands to avoid this
  58. * problem and bounce timeout failures to the caller.
  59. */
  60. #define SAN_COMMAND_TIMEOUT ( 15 * TICKS_PER_SEC )
  61. /**
  62. * Number of times to retry commands
  63. *
  64. * We may need to retry commands. For example, the underlying
  65. * connection may be closed by the SAN target due to an inactivity
  66. * timeout, or the SAN target may return pointless "error" messages
  67. * such as "SCSI power-on occurred".
  68. */
  69. #define SAN_COMMAND_MAX_RETRIES 10
  70. /** List of SAN devices */
  71. LIST_HEAD ( san_devices );
  72. /**
  73. * Find SAN device by drive number
  74. *
  75. * @v drive Drive number
  76. * @ret sandev SAN device, or NULL
  77. */
  78. struct san_device * sandev_find ( unsigned int drive ) {
  79. struct san_device *sandev;
  80. list_for_each_entry ( sandev, &san_devices, list ) {
  81. if ( sandev->drive == drive )
  82. return sandev;
  83. }
  84. return NULL;
  85. }
  86. /**
  87. * Free SAN device
  88. *
  89. * @v refcnt Reference count
  90. */
  91. static void sandev_free ( struct refcnt *refcnt ) {
  92. struct san_device *sandev =
  93. container_of ( refcnt, struct san_device, refcnt );
  94. struct san_path *sanpath;
  95. assert ( ! timer_running ( &sandev->timer ) );
  96. assert ( ! sandev->active );
  97. assert ( list_empty ( &sandev->opened ) );
  98. list_for_each_entry ( sanpath, &sandev->closed, list )
  99. uri_put ( sanpath->uri );
  100. free ( sandev );
  101. }
  102. /**
  103. * Close SAN device command
  104. *
  105. * @v sandev SAN device
  106. * @v rc Reason for close
  107. */
  108. static void sandev_command_close ( struct san_device *sandev, int rc ) {
  109. /* Stop timer */
  110. stop_timer ( &sandev->timer );
  111. /* Restart interface */
  112. intf_restart ( &sandev->command, rc );
  113. /* Record command status */
  114. sandev->command_rc = rc;
  115. }
  116. /**
  117. * Record SAN device capacity
  118. *
  119. * @v sandev SAN device
  120. * @v capacity SAN device capacity
  121. */
  122. static void sandev_command_capacity ( struct san_device *sandev,
  123. struct block_device_capacity *capacity ) {
  124. /* Record raw capacity information */
  125. memcpy ( &sandev->capacity, capacity, sizeof ( sandev->capacity ) );
  126. }
  127. /** SAN device command interface operations */
  128. static struct interface_operation sandev_command_op[] = {
  129. INTF_OP ( intf_close, struct san_device *, sandev_command_close ),
  130. INTF_OP ( block_capacity, struct san_device *,
  131. sandev_command_capacity ),
  132. };
  133. /** SAN device command interface descriptor */
  134. static struct interface_descriptor sandev_command_desc =
  135. INTF_DESC ( struct san_device, command, sandev_command_op );
  136. /**
  137. * Handle SAN device command timeout
  138. *
  139. * @v retry Retry timer
  140. */
  141. static void sandev_command_expired ( struct retry_timer *timer,
  142. int over __unused ) {
  143. struct san_device *sandev =
  144. container_of ( timer, struct san_device, timer );
  145. sandev_command_close ( sandev, -ETIMEDOUT );
  146. }
  147. /**
  148. * Open SAN path
  149. *
  150. * @v sanpath SAN path
  151. * @ret rc Return status code
  152. */
  153. static int sanpath_open ( struct san_path *sanpath ) {
  154. struct san_device *sandev = sanpath->sandev;
  155. int rc;
  156. /* Sanity check */
  157. list_check_contains_entry ( sanpath, &sandev->closed, list );
  158. /* Open interface */
  159. if ( ( rc = xfer_open_uri ( &sanpath->block, sanpath->uri ) ) != 0 ) {
  160. DBGC ( sandev, "SAN %#02x.%d could not (re)open URI: "
  161. "%s\n", sandev->drive, sanpath->index, strerror ( rc ) );
  162. return rc;
  163. }
  164. /* Start process */
  165. process_add ( &sanpath->process );
  166. /* Mark as opened */
  167. list_del ( &sanpath->list );
  168. list_add_tail ( &sanpath->list, &sandev->opened );
  169. /* Record as in progress */
  170. sanpath->path_rc = -EINPROGRESS;
  171. return 0;
  172. }
  173. /**
  174. * Close SAN path
  175. *
  176. * @v sanpath SAN path
  177. * @v rc Reason for close
  178. */
  179. static void sanpath_close ( struct san_path *sanpath, int rc ) {
  180. struct san_device *sandev = sanpath->sandev;
  181. /* Record status */
  182. sanpath->path_rc = rc;
  183. /* Mark as closed */
  184. list_del ( &sanpath->list );
  185. list_add_tail ( &sanpath->list, &sandev->closed );
  186. /* Stop process */
  187. process_del ( &sanpath->process );
  188. /* Restart interfaces, avoiding potential loops */
  189. if ( sanpath == sandev->active ) {
  190. intfs_restart ( rc, &sandev->command, &sanpath->block, NULL );
  191. sandev->active = NULL;
  192. sandev_command_close ( sandev, rc );
  193. } else {
  194. intf_restart ( &sanpath->block, rc );
  195. }
  196. }
  197. /**
  198. * Handle closure of underlying block device interface
  199. *
  200. * @v sanpath SAN path
  201. * @v rc Reason for close
  202. */
  203. static void sanpath_block_close ( struct san_path *sanpath, int rc ) {
  204. struct san_device *sandev = sanpath->sandev;
  205. /* Any closure is an error from our point of view */
  206. if ( rc == 0 )
  207. rc = -ENOTCONN;
  208. DBGC ( sandev, "SAN %#02x.%d closed: %s\n",
  209. sandev->drive, sanpath->index, strerror ( rc ) );
  210. /* Close path */
  211. sanpath_close ( sanpath, rc );
  212. }
  213. /**
  214. * Check flow control window
  215. *
  216. * @v sanpath SAN path
  217. */
  218. static size_t sanpath_block_window ( struct san_path *sanpath __unused ) {
  219. /* We are never ready to receive data via this interface.
  220. * This prevents objects that support both block and stream
  221. * interfaces from attempting to send us stream data.
  222. */
  223. return 0;
  224. }
  225. /**
  226. * SAN path process
  227. *
  228. * @v sanpath SAN path
  229. */
  230. static void sanpath_step ( struct san_path *sanpath ) {
  231. struct san_device *sandev = sanpath->sandev;
  232. /* Wait until path has become available */
  233. if ( ! xfer_window ( &sanpath->block ) )
  234. return;
  235. /* Record status */
  236. sanpath->path_rc = 0;
  237. /* Mark as active path or close as applicable */
  238. if ( ! sandev->active ) {
  239. DBGC ( sandev, "SAN %#02x.%d is active\n",
  240. sandev->drive, sanpath->index );
  241. sandev->active = sanpath;
  242. } else {
  243. DBGC ( sandev, "SAN %#02x.%d is available\n",
  244. sandev->drive, sanpath->index );
  245. sanpath_close ( sanpath, 0 );
  246. }
  247. }
  248. /** SAN path block interface operations */
  249. static struct interface_operation sanpath_block_op[] = {
  250. INTF_OP ( intf_close, struct san_path *, sanpath_block_close ),
  251. INTF_OP ( xfer_window, struct san_path *, sanpath_block_window ),
  252. INTF_OP ( xfer_window_changed, struct san_path *, sanpath_step ),
  253. };
  254. /** SAN path block interface descriptor */
  255. static struct interface_descriptor sanpath_block_desc =
  256. INTF_DESC ( struct san_path, block, sanpath_block_op );
  257. /** SAN path process descriptor */
  258. static struct process_descriptor sanpath_process_desc =
  259. PROC_DESC_ONCE ( struct san_path, process, sanpath_step );
  260. /**
  261. * Restart SAN device interface
  262. *
  263. * @v sandev SAN device
  264. * @v rc Reason for restart
  265. */
  266. static void sandev_restart ( struct san_device *sandev, int rc ) {
  267. struct san_path *sanpath;
  268. /* Restart all block device interfaces */
  269. while ( ( sanpath = list_first_entry ( &sandev->opened,
  270. struct san_path, list ) ) ) {
  271. sanpath_close ( sanpath, rc );
  272. }
  273. /* Clear active path */
  274. sandev->active = NULL;
  275. /* Close any outstanding command */
  276. sandev_command_close ( sandev, rc );
  277. }
  278. /**
  279. * (Re)open SAN device
  280. *
  281. * @v sandev SAN device
  282. * @ret rc Return status code
  283. *
  284. * This function will block until the device is available.
  285. */
  286. int sandev_reopen ( struct san_device *sandev ) {
  287. struct san_path *sanpath;
  288. int rc;
  289. /* Close any outstanding command and restart interfaces */
  290. sandev_restart ( sandev, -ECONNRESET );
  291. assert ( sandev->active == NULL );
  292. assert ( list_empty ( &sandev->opened ) );
  293. /* Open all paths */
  294. while ( ( sanpath = list_first_entry ( &sandev->closed,
  295. struct san_path, list ) ) ) {
  296. if ( ( rc = sanpath_open ( sanpath ) ) != 0 )
  297. goto err_open;
  298. }
  299. /* Wait for any device to become available, or for all devices
  300. * to fail.
  301. */
  302. while ( sandev->active == NULL ) {
  303. step();
  304. if ( list_empty ( &sandev->opened ) ) {
  305. /* Get status of the first device to be
  306. * closed. Do this on the basis that earlier
  307. * errors (e.g. "invalid IQN") are probably
  308. * more interesting than later errors
  309. * (e.g. "TCP timeout").
  310. */
  311. rc = -ENODEV;
  312. list_for_each_entry ( sanpath, &sandev->closed, list ) {
  313. rc = sanpath->path_rc;
  314. break;
  315. }
  316. DBGC ( sandev, "SAN %#02x never became available: %s\n",
  317. sandev->drive, strerror ( rc ) );
  318. goto err_none;
  319. }
  320. }
  321. assert ( ! list_empty ( &sandev->opened ) );
  322. return 0;
  323. err_none:
  324. err_open:
  325. sandev_restart ( sandev, rc );
  326. return rc;
  327. }
  328. /** SAN device read/write command parameters */
  329. struct san_command_rw_params {
  330. /** SAN device read/write operation */
  331. int ( * block_rw ) ( struct interface *control, struct interface *data,
  332. uint64_t lba, unsigned int count,
  333. userptr_t buffer, size_t len );
  334. /** Data buffer */
  335. userptr_t buffer;
  336. /** Starting LBA */
  337. uint64_t lba;
  338. /** Block count */
  339. unsigned int count;
  340. };
  341. /** SAN device command parameters */
  342. union san_command_params {
  343. /** Read/write command parameters */
  344. struct san_command_rw_params rw;
  345. };
  346. /**
  347. * Initiate SAN device read/write command
  348. *
  349. * @v sandev SAN device
  350. * @v params Command parameters
  351. * @ret rc Return status code
  352. */
  353. static int sandev_command_rw ( struct san_device *sandev,
  354. const union san_command_params *params ) {
  355. struct san_path *sanpath = sandev->active;
  356. size_t len = ( params->rw.count * sandev->capacity.blksize );
  357. int rc;
  358. /* Sanity check */
  359. assert ( sanpath != NULL );
  360. /* Initiate read/write command */
  361. if ( ( rc = params->rw.block_rw ( &sanpath->block, &sandev->command,
  362. params->rw.lba, params->rw.count,
  363. params->rw.buffer, len ) ) != 0 ) {
  364. DBGC ( sandev, "SAN %#02x.%d could not initiate read/write: "
  365. "%s\n", sandev->drive, sanpath->index, strerror ( rc ) );
  366. return rc;
  367. }
  368. return 0;
  369. }
  370. /**
  371. * Initiate SAN device read capacity command
  372. *
  373. * @v sandev SAN device
  374. * @v params Command parameters
  375. * @ret rc Return status code
  376. */
  377. static int
  378. sandev_command_read_capacity ( struct san_device *sandev,
  379. const union san_command_params *params __unused){
  380. struct san_path *sanpath = sandev->active;
  381. int rc;
  382. /* Sanity check */
  383. assert ( sanpath != NULL );
  384. /* Initiate read capacity command */
  385. if ( ( rc = block_read_capacity ( &sanpath->block,
  386. &sandev->command ) ) != 0 ) {
  387. DBGC ( sandev, "SAN %#02x.%d could not initiate read capacity: "
  388. "%s\n", sandev->drive, sanpath->index, strerror ( rc ) );
  389. return rc;
  390. }
  391. return 0;
  392. }
  393. /**
  394. * Execute a single SAN device command and wait for completion
  395. *
  396. * @v sandev SAN device
  397. * @v command Command
  398. * @v params Command parameters (if required)
  399. * @ret rc Return status code
  400. */
  401. static int
  402. sandev_command ( struct san_device *sandev,
  403. int ( * command ) ( struct san_device *sandev,
  404. const union san_command_params *params ),
  405. const union san_command_params *params ) {
  406. unsigned int retries;
  407. int rc;
  408. /* Sanity check */
  409. assert ( ! timer_running ( &sandev->timer ) );
  410. /* (Re)try command */
  411. for ( retries = 0 ; retries < SAN_COMMAND_MAX_RETRIES ; retries++ ) {
  412. /* Reopen block device if applicable */
  413. if ( sandev_needs_reopen ( sandev ) &&
  414. ( ( rc = sandev_reopen ( sandev ) ) != 0 ) ) {
  415. continue;
  416. }
  417. /* Start expiry timer */
  418. start_timer_fixed ( &sandev->timer, SAN_COMMAND_TIMEOUT );
  419. /* Initiate command */
  420. if ( ( rc = command ( sandev, params ) ) != 0 ) {
  421. stop_timer ( &sandev->timer );
  422. continue;
  423. }
  424. /* Wait for command to complete */
  425. while ( timer_running ( &sandev->timer ) )
  426. step();
  427. /* Exit on success */
  428. if ( ( rc = sandev->command_rc ) == 0 )
  429. return 0;
  430. }
  431. /* Sanity check */
  432. assert ( ! timer_running ( &sandev->timer ) );
  433. return rc;
  434. }
  435. /**
  436. * Reset SAN device
  437. *
  438. * @v sandev SAN device
  439. * @ret rc Return status code
  440. */
  441. int sandev_reset ( struct san_device *sandev ) {
  442. int rc;
  443. DBGC ( sandev, "SAN %#02x reset\n", sandev->drive );
  444. /* Close and reopen underlying block device */
  445. if ( ( rc = sandev_reopen ( sandev ) ) != 0 )
  446. return rc;
  447. return 0;
  448. }
  449. /**
  450. * Read from or write to SAN device
  451. *
  452. * @v sandev SAN device
  453. * @v lba Starting logical block address
  454. * @v count Number of logical blocks
  455. * @v buffer Data buffer
  456. * @v block_rw Block read/write method
  457. * @ret rc Return status code
  458. */
  459. int sandev_rw ( struct san_device *sandev, uint64_t lba,
  460. unsigned int count, userptr_t buffer,
  461. int ( * block_rw ) ( struct interface *control,
  462. struct interface *data,
  463. uint64_t lba, unsigned int count,
  464. userptr_t buffer, size_t len ) ) {
  465. union san_command_params params;
  466. unsigned int remaining;
  467. size_t frag_len;
  468. int rc;
  469. /* Initialise command parameters */
  470. params.rw.block_rw = block_rw;
  471. params.rw.buffer = buffer;
  472. params.rw.lba = ( lba << sandev->blksize_shift );
  473. params.rw.count = sandev->capacity.max_count;
  474. remaining = ( count << sandev->blksize_shift );
  475. /* Read/write fragments */
  476. while ( remaining ) {
  477. /* Determine fragment length */
  478. if ( params.rw.count > remaining )
  479. params.rw.count = remaining;
  480. /* Execute command */
  481. if ( ( rc = sandev_command ( sandev, sandev_command_rw,
  482. &params ) ) != 0 )
  483. return rc;
  484. /* Move to next fragment */
  485. frag_len = ( sandev->capacity.blksize * params.rw.count );
  486. params.rw.buffer = userptr_add ( params.rw.buffer, frag_len );
  487. params.rw.lba += params.rw.count;
  488. remaining -= params.rw.count;
  489. }
  490. return 0;
  491. }
  492. /**
  493. * Configure SAN device as a CD-ROM, if applicable
  494. *
  495. * @v sandev SAN device
  496. * @ret rc Return status code
  497. *
  498. * Both BIOS and UEFI require SAN devices to be accessed with a block
  499. * size of 2048. While we could require the user to configure the
  500. * block size appropriately, this is non-trivial and would impose a
  501. * substantial learning effort on the user. Instead, we check for the
  502. * presence of the ISO9660 primary volume descriptor and, if found,
  503. * then we force a block size of 2048 and map read/write requests
  504. * appropriately.
  505. */
  506. static int sandev_parse_iso9660 ( struct san_device *sandev ) {
  507. static const struct iso9660_primary_descriptor_fixed primary_check = {
  508. .type = ISO9660_TYPE_PRIMARY,
  509. .id = ISO9660_ID,
  510. };
  511. union {
  512. struct iso9660_primary_descriptor primary;
  513. char bytes[ISO9660_BLKSIZE];
  514. } *scratch;
  515. unsigned int blksize;
  516. unsigned int blksize_shift;
  517. unsigned int lba;
  518. unsigned int count;
  519. int rc;
  520. /* Calculate required blocksize shift for potential CD-ROM access */
  521. blksize = sandev->capacity.blksize;
  522. blksize_shift = 0;
  523. while ( blksize < ISO9660_BLKSIZE ) {
  524. blksize <<= 1;
  525. blksize_shift++;
  526. }
  527. if ( blksize > ISO9660_BLKSIZE ) {
  528. /* Cannot be a CD-ROM. This is not an error. */
  529. rc = 0;
  530. goto invalid_blksize;
  531. }
  532. lba = ( ISO9660_PRIMARY_LBA << blksize_shift );
  533. count = ( 1 << blksize_shift );
  534. /* Allocate scratch area */
  535. scratch = malloc ( ISO9660_BLKSIZE );
  536. if ( ! scratch ) {
  537. rc = -ENOMEM;
  538. goto err_alloc;
  539. }
  540. /* Read primary volume descriptor */
  541. if ( ( rc = sandev_rw ( sandev, lba, count, virt_to_user ( scratch ),
  542. block_read ) ) != 0 ) {
  543. DBGC ( sandev, "SAN %#02x could not read ISO9660 primary"
  544. "volume descriptor: %s\n",
  545. sandev->drive, strerror ( rc ) );
  546. goto err_rw;
  547. }
  548. /* Configure as CD-ROM if applicable */
  549. if ( memcmp ( &scratch->primary.fixed, &primary_check,
  550. sizeof ( primary_check ) ) == 0 ) {
  551. DBGC ( sandev, "SAN %#02x contains an ISO9660 filesystem; "
  552. "treating as CD-ROM\n", sandev->drive );
  553. sandev->blksize_shift = blksize_shift;
  554. sandev->is_cdrom = 1;
  555. }
  556. err_rw:
  557. free ( scratch );
  558. err_alloc:
  559. invalid_blksize:
  560. return rc;
  561. }
  562. /**
  563. * Allocate SAN device
  564. *
  565. * @v uris List of URIs
  566. * @v count Number of URIs
  567. * @v priv_size Size of private data
  568. * @ret sandev SAN device, or NULL
  569. */
  570. struct san_device * alloc_sandev ( struct uri **uris, unsigned int count,
  571. size_t priv_size ) {
  572. struct san_device *sandev;
  573. struct san_path *sanpath;
  574. size_t size;
  575. unsigned int i;
  576. /* Allocate and initialise structure */
  577. size = ( sizeof ( *sandev ) + ( count * sizeof ( sandev->path[0] ) ) );
  578. sandev = zalloc ( size + priv_size );
  579. if ( ! sandev )
  580. return NULL;
  581. ref_init ( &sandev->refcnt, sandev_free );
  582. intf_init ( &sandev->command, &sandev_command_desc, &sandev->refcnt );
  583. timer_init ( &sandev->timer, sandev_command_expired, &sandev->refcnt );
  584. sandev->priv = ( ( ( void * ) sandev ) + size );
  585. INIT_LIST_HEAD ( &sandev->opened );
  586. INIT_LIST_HEAD ( &sandev->closed );
  587. for ( i = 0 ; i < count ; i++ ) {
  588. sanpath = &sandev->path[i];
  589. sanpath->sandev = sandev;
  590. sanpath->index = i;
  591. sanpath->uri = uri_get ( uris[i] );
  592. list_add_tail ( &sanpath->list, &sandev->closed );
  593. intf_init ( &sanpath->block, &sanpath_block_desc,
  594. &sandev->refcnt );
  595. process_init_stopped ( &sanpath->process, &sanpath_process_desc,
  596. &sandev->refcnt );
  597. sanpath->path_rc = -EINPROGRESS;
  598. }
  599. return sandev;
  600. }
  601. /**
  602. * Register SAN device
  603. *
  604. * @v sandev SAN device
  605. * @ret rc Return status code
  606. */
  607. int register_sandev ( struct san_device *sandev ) {
  608. int rc;
  609. /* Check that drive number is not in use */
  610. if ( sandev_find ( sandev->drive ) != NULL ) {
  611. DBGC ( sandev, "SAN %#02x is already in use\n", sandev->drive );
  612. return -EADDRINUSE;
  613. }
  614. /* Read device capacity */
  615. if ( ( rc = sandev_command ( sandev, sandev_command_read_capacity,
  616. NULL ) ) != 0 )
  617. return rc;
  618. /* Configure as a CD-ROM, if applicable */
  619. if ( ( rc = sandev_parse_iso9660 ( sandev ) ) != 0 )
  620. return rc;
  621. /* Add to list of SAN devices */
  622. list_add_tail ( &sandev->list, &san_devices );
  623. DBGC ( sandev, "SAN %#02x registered\n", sandev->drive );
  624. return 0;
  625. }
  626. /**
  627. * Unregister SAN device
  628. *
  629. * @v sandev SAN device
  630. */
  631. void unregister_sandev ( struct san_device *sandev ) {
  632. /* Sanity check */
  633. assert ( ! timer_running ( &sandev->timer ) );
  634. /* Shut down interfaces */
  635. sandev_restart ( sandev, 0 );
  636. /* Remove from list of SAN devices */
  637. list_del ( &sandev->list );
  638. DBGC ( sandev, "SAN %#02x unregistered\n", sandev->drive );
  639. }
  640. /** The "san-drive" setting */
  641. const struct setting san_drive_setting __setting ( SETTING_SANBOOT_EXTRA,
  642. san-drive ) = {
  643. .name = "san-drive",
  644. .description = "SAN drive number",
  645. .tag = DHCP_EB_SAN_DRIVE,
  646. .type = &setting_type_uint8,
  647. };
  648. /**
  649. * Get default SAN drive number
  650. *
  651. * @ret drive Default drive number
  652. */
  653. unsigned int san_default_drive ( void ) {
  654. unsigned long drive;
  655. /* Use "san-drive" setting, if specified */
  656. if ( fetch_uint_setting ( NULL, &san_drive_setting, &drive ) >= 0 )
  657. return drive;
  658. /* Otherwise, default to booting from first hard disk */
  659. return SAN_DEFAULT_DRIVE;
  660. }