You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

sanboot.c 20KB

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