您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

sanboot.c 21KB

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