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.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831
  1. /*
  2. * Copyright (C) 2006 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., 675 Mass Ave, Cambridge, MA 02139, USA.
  17. */
  18. FILE_LICENCE ( GPL2_OR_LATER );
  19. #include <stddef.h>
  20. #include <stdlib.h>
  21. #include <string.h>
  22. #include <byteswap.h>
  23. #include <errno.h>
  24. #include <ipxe/list.h>
  25. #include <ipxe/blockdev.h>
  26. #include <ipxe/scsi.h>
  27. /** @file
  28. *
  29. * SCSI block device
  30. *
  31. */
  32. /** Maximum number of command retries */
  33. #define SCSICMD_MAX_RETRIES 10
  34. /* Error numbers generated by SCSI sense data */
  35. #define EIO_NO_SENSE __einfo_error ( EINFO_EIO_NO_SENSE )
  36. #define EINFO_EIO_NO_SENSE \
  37. __einfo_uniqify ( EINFO_EIO, 0x00, "No sense" )
  38. #define EIO_RECOVERED_ERROR __einfo_error ( EINFO_EIO_RECOVERED_ERROR )
  39. #define EINFO_EIO_RECOVERED_ERROR \
  40. __einfo_uniqify ( EINFO_EIO, 0x01, "Recovered error" )
  41. #define EIO_NOT_READY __einfo_error ( EINFO_EIO_NOT_READY )
  42. #define EINFO_EIO_NOT_READY \
  43. __einfo_uniqify ( EINFO_EIO, 0x02, "Not ready" )
  44. #define EIO_MEDIUM_ERROR __einfo_error ( EINFO_EIO_MEDIUM_ERROR )
  45. #define EINFO_EIO_MEDIUM_ERROR \
  46. __einfo_uniqify ( EINFO_EIO, 0x03, "Medium error" )
  47. #define EIO_HARDWARE_ERROR __einfo_error ( EINFO_EIO_HARDWARE_ERROR )
  48. #define EINFO_EIO_HARDWARE_ERROR \
  49. __einfo_uniqify ( EINFO_EIO, 0x04, "Hardware error" )
  50. #define EIO_ILLEGAL_REQUEST __einfo_error ( EINFO_EIO_ILLEGAL_REQUEST )
  51. #define EINFO_EIO_ILLEGAL_REQUEST \
  52. __einfo_uniqify ( EINFO_EIO, 0x05, "Illegal request" )
  53. #define EIO_UNIT_ATTENTION __einfo_error ( EINFO_EIO_UNIT_ATTENTION )
  54. #define EINFO_EIO_UNIT_ATTENTION \
  55. __einfo_uniqify ( EINFO_EIO, 0x06, "Unit attention" )
  56. #define EIO_DATA_PROTECT __einfo_error ( EINFO_EIO_DATA_PROTECT )
  57. #define EINFO_EIO_DATA_PROTECT \
  58. __einfo_uniqify ( EINFO_EIO, 0x07, "Data protect" )
  59. #define EIO_BLANK_CHECK __einfo_error ( EINFO_EIO_BLANK_CHECK )
  60. #define EINFO_EIO_BLANK_CHECK \
  61. __einfo_uniqify ( EINFO_EIO, 0x08, "Blank check" )
  62. #define EIO_VENDOR_SPECIFIC __einfo_error ( EINFO_EIO_VENDOR_SPECIFIC )
  63. #define EINFO_EIO_VENDOR_SPECIFIC \
  64. __einfo_uniqify ( EINFO_EIO, 0x09, "Vendor specific" )
  65. #define EIO_COPY_ABORTED __einfo_error ( EINFO_EIO_COPY_ABORTED )
  66. #define EINFO_EIO_COPY_ABORTED \
  67. __einfo_uniqify ( EINFO_EIO, 0x0a, "Copy aborted" )
  68. #define EIO_ABORTED_COMMAND __einfo_error ( EINFO_EIO_ABORTED_COMMAND )
  69. #define EINFO_EIO_ABORTED_COMMAND \
  70. __einfo_uniqify ( EINFO_EIO, 0x0b, "Aborted command" )
  71. #define EIO_RESERVED __einfo_error ( EINFO_EIO_RESERVED )
  72. #define EINFO_EIO_RESERVED \
  73. __einfo_uniqify ( EINFO_EIO, 0x0c, "Reserved" )
  74. #define EIO_VOLUME_OVERFLOW __einfo_error ( EINFO_EIO_VOLUME_OVERFLOW )
  75. #define EINFO_EIO_VOLUME_OVERFLOW \
  76. __einfo_uniqify ( EINFO_EIO, 0x0d, "Volume overflow" )
  77. #define EIO_MISCOMPARE __einfo_error ( EINFO_EIO_MISCOMPARE )
  78. #define EINFO_EIO_MISCOMPARE \
  79. __einfo_uniqify ( EINFO_EIO, 0x0e, "Miscompare" )
  80. #define EIO_COMPLETED __einfo_error ( EINFO_EIO_COMPLETED )
  81. #define EINFO_EIO_COMPLETED \
  82. __einfo_uniqify ( EINFO_EIO, 0x0f, "Completed" )
  83. #define EIO_SENSE( key ) \
  84. EUNIQ ( EIO, (key), EIO_NO_SENSE, EIO_RECOVERED_ERROR, \
  85. EIO_NOT_READY, EIO_MEDIUM_ERROR, EIO_HARDWARE_ERROR, \
  86. EIO_ILLEGAL_REQUEST, EIO_UNIT_ATTENTION, \
  87. EIO_DATA_PROTECT, EIO_BLANK_CHECK, EIO_VENDOR_SPECIFIC, \
  88. EIO_COPY_ABORTED, EIO_ABORTED_COMMAND, EIO_RESERVED, \
  89. EIO_VOLUME_OVERFLOW, EIO_MISCOMPARE, EIO_COMPLETED )
  90. /******************************************************************************
  91. *
  92. * Utility functions
  93. *
  94. ******************************************************************************
  95. */
  96. /**
  97. * Parse SCSI LUN
  98. *
  99. * @v lun_string LUN string representation
  100. * @v lun LUN to fill in
  101. * @ret rc Return status code
  102. */
  103. int scsi_parse_lun ( const char *lun_string, struct scsi_lun *lun ) {
  104. char *p;
  105. int i;
  106. memset ( lun, 0, sizeof ( *lun ) );
  107. if ( lun_string ) {
  108. p = ( char * ) lun_string;
  109. for ( i = 0 ; i < 4 ; i++ ) {
  110. lun->u16[i] = htons ( strtoul ( p, &p, 16 ) );
  111. if ( *p == '\0' )
  112. break;
  113. if ( *p != '-' )
  114. return -EINVAL;
  115. p++;
  116. }
  117. if ( *p )
  118. return -EINVAL;
  119. }
  120. return 0;
  121. }
  122. /******************************************************************************
  123. *
  124. * Interface methods
  125. *
  126. ******************************************************************************
  127. */
  128. /**
  129. * Issue SCSI command
  130. *
  131. * @v control SCSI control interface
  132. * @v data SCSI data interface
  133. * @v command SCSI command
  134. * @ret tag Command tag, or negative error
  135. */
  136. int scsi_command ( struct interface *control, struct interface *data,
  137. struct scsi_cmd *command ) {
  138. struct interface *dest;
  139. scsi_command_TYPE ( void * ) *op =
  140. intf_get_dest_op ( control, scsi_command, &dest );
  141. void *object = intf_object ( dest );
  142. int tap;
  143. if ( op ) {
  144. tap = op ( object, data, command );
  145. } else {
  146. /* Default is to fail to issue the command */
  147. tap = -EOPNOTSUPP;
  148. }
  149. intf_put ( dest );
  150. return tap;
  151. }
  152. /**
  153. * Report SCSI response
  154. *
  155. * @v interface SCSI command interface
  156. * @v response SCSI response
  157. */
  158. void scsi_response ( struct interface *intf, struct scsi_rsp *response ) {
  159. struct interface *dest;
  160. scsi_response_TYPE ( void * ) *op =
  161. intf_get_dest_op ( intf, scsi_response, &dest );
  162. void *object = intf_object ( dest );
  163. if ( op ) {
  164. op ( object, response );
  165. } else {
  166. /* Default is to ignore the response */
  167. }
  168. intf_put ( dest );
  169. }
  170. /******************************************************************************
  171. *
  172. * SCSI devices and commands
  173. *
  174. ******************************************************************************
  175. */
  176. /** A SCSI device */
  177. struct scsi_device {
  178. /** Reference count */
  179. struct refcnt refcnt;
  180. /** Block control interface */
  181. struct interface block;
  182. /** SCSI control interface */
  183. struct interface scsi;
  184. /** SCSI LUN */
  185. struct scsi_lun lun;
  186. /** List of commands */
  187. struct list_head cmds;
  188. };
  189. /** A SCSI command */
  190. struct scsi_command {
  191. /** Reference count */
  192. struct refcnt refcnt;
  193. /** SCSI device */
  194. struct scsi_device *scsidev;
  195. /** List of SCSI commands */
  196. struct list_head list;
  197. /** Block data interface */
  198. struct interface block;
  199. /** SCSI data interface */
  200. struct interface scsi;
  201. /** Command type */
  202. struct scsi_command_type *type;
  203. /** Starting logical block address */
  204. uint64_t lba;
  205. /** Number of blocks */
  206. unsigned int count;
  207. /** Data buffer */
  208. userptr_t buffer;
  209. /** Length of data buffer */
  210. size_t len;
  211. /** Command tag */
  212. uint32_t tag;
  213. /** Retry count */
  214. unsigned int retries;
  215. /** Private data */
  216. uint8_t priv[0];
  217. };
  218. /** A SCSI command type */
  219. struct scsi_command_type {
  220. /** Name */
  221. const char *name;
  222. /** Additional working space */
  223. size_t priv_len;
  224. /**
  225. * Construct SCSI command IU
  226. *
  227. * @v scsicmd SCSI command
  228. * @v command SCSI command IU
  229. */
  230. void ( * cmd ) ( struct scsi_command *scsicmd,
  231. struct scsi_cmd *command );
  232. /**
  233. * Handle SCSI command completion
  234. *
  235. * @v scsicmd SCSI command
  236. * @v rc Reason for completion
  237. */
  238. void ( * done ) ( struct scsi_command *scsicmd, int rc );
  239. };
  240. /**
  241. * Get reference to SCSI device
  242. *
  243. * @v scsidev SCSI device
  244. * @ret scsidev SCSI device
  245. */
  246. static inline __attribute__ (( always_inline )) struct scsi_device *
  247. scsidev_get ( struct scsi_device *scsidev ) {
  248. ref_get ( &scsidev->refcnt );
  249. return scsidev;
  250. }
  251. /**
  252. * Drop reference to SCSI device
  253. *
  254. * @v scsidev SCSI device
  255. */
  256. static inline __attribute__ (( always_inline )) void
  257. scsidev_put ( struct scsi_device *scsidev ) {
  258. ref_put ( &scsidev->refcnt );
  259. }
  260. /**
  261. * Get reference to SCSI command
  262. *
  263. * @v scsicmd SCSI command
  264. * @ret scsicmd SCSI command
  265. */
  266. static inline __attribute__ (( always_inline )) struct scsi_command *
  267. scsicmd_get ( struct scsi_command *scsicmd ) {
  268. ref_get ( &scsicmd->refcnt );
  269. return scsicmd;
  270. }
  271. /**
  272. * Drop reference to SCSI command
  273. *
  274. * @v scsicmd SCSI command
  275. */
  276. static inline __attribute__ (( always_inline )) void
  277. scsicmd_put ( struct scsi_command *scsicmd ) {
  278. ref_put ( &scsicmd->refcnt );
  279. }
  280. /**
  281. * Get SCSI command private data
  282. *
  283. * @v scsicmd SCSI command
  284. * @ret priv Private data
  285. */
  286. static inline __attribute__ (( always_inline )) void *
  287. scsicmd_priv ( struct scsi_command *scsicmd ) {
  288. return scsicmd->priv;
  289. }
  290. /**
  291. * Free SCSI command
  292. *
  293. * @v refcnt Reference count
  294. */
  295. static void scsicmd_free ( struct refcnt *refcnt ) {
  296. struct scsi_command *scsicmd =
  297. container_of ( refcnt, struct scsi_command, refcnt );
  298. /* Remove from list of commands */
  299. list_del ( &scsicmd->list );
  300. scsidev_put ( scsicmd->scsidev );
  301. /* Free command */
  302. free ( scsicmd );
  303. }
  304. /**
  305. * Close SCSI command
  306. *
  307. * @v scsicmd SCSI command
  308. * @v rc Reason for close
  309. */
  310. static void scsicmd_close ( struct scsi_command *scsicmd, int rc ) {
  311. struct scsi_device *scsidev = scsicmd->scsidev;
  312. if ( rc != 0 ) {
  313. DBGC ( scsidev, "SCSI %p tag %08x closed: %s\n",
  314. scsidev, scsicmd->tag, strerror ( rc ) );
  315. }
  316. /* Shut down interfaces */
  317. intf_shutdown ( &scsicmd->scsi, rc );
  318. intf_shutdown ( &scsicmd->block, rc );
  319. }
  320. /**
  321. * Construct and issue SCSI command
  322. *
  323. * @ret rc Return status code
  324. */
  325. static int scsicmd_command ( struct scsi_command *scsicmd ) {
  326. struct scsi_device *scsidev = scsicmd->scsidev;
  327. struct scsi_cmd command;
  328. int tag;
  329. int rc;
  330. /* Construct command */
  331. memset ( &command, 0, sizeof ( command ) );
  332. memcpy ( &command.lun, &scsidev->lun, sizeof ( command.lun ) );
  333. scsicmd->type->cmd ( scsicmd, &command );
  334. /* Issue command */
  335. if ( ( tag = scsi_command ( &scsidev->scsi, &scsicmd->scsi,
  336. &command ) ) < 0 ) {
  337. rc = tag;
  338. DBGC ( scsidev, "SCSI %p could not issue command: %s\n",
  339. scsidev, strerror ( rc ) );
  340. return rc;
  341. }
  342. /* Record tag */
  343. if ( scsicmd->tag ) {
  344. DBGC ( scsidev, "SCSI %p tag %08x is now tag %08x\n",
  345. scsidev, scsicmd->tag, tag );
  346. }
  347. scsicmd->tag = tag;
  348. DBGC2 ( scsidev, "SCSI %p tag %08x %s " SCSI_CDB_FORMAT "\n",
  349. scsidev, scsicmd->tag, scsicmd->type->name,
  350. SCSI_CDB_DATA ( command.cdb ) );
  351. return 0;
  352. }
  353. /**
  354. * Handle SCSI command completion
  355. *
  356. * @v scsicmd SCSI command
  357. * @v rc Reason for close
  358. */
  359. static void scsicmd_done ( struct scsi_command *scsicmd, int rc ) {
  360. struct scsi_device *scsidev = scsicmd->scsidev;
  361. /* Restart SCSI interface */
  362. intf_restart ( &scsicmd->scsi, rc );
  363. /* SCSI targets have an annoying habit of returning occasional
  364. * pointless "error" messages such as "power-on occurred", so
  365. * we have to be prepared to retry commands.
  366. */
  367. if ( ( rc != 0 ) && ( scsicmd->retries++ < SCSICMD_MAX_RETRIES ) ) {
  368. /* Retry command */
  369. DBGC ( scsidev, "SCSI %p tag %08x failed: %s\n",
  370. scsidev, scsicmd->tag, strerror ( rc ) );
  371. DBGC ( scsidev, "SCSI %p tag %08x retrying (retry %d)\n",
  372. scsidev, scsicmd->tag, scsicmd->retries );
  373. if ( ( rc = scsicmd_command ( scsicmd ) ) == 0 )
  374. return;
  375. }
  376. /* If we didn't (successfully) reissue the command, hand over
  377. * to the command completion handler.
  378. */
  379. scsicmd->type->done ( scsicmd, rc );
  380. }
  381. /**
  382. * Handle SCSI response
  383. *
  384. * @v scsicmd SCSI command
  385. * @v response SCSI response
  386. */
  387. static void scsicmd_response ( struct scsi_command *scsicmd,
  388. struct scsi_rsp *response ) {
  389. struct scsi_device *scsidev = scsicmd->scsidev;
  390. size_t overrun;
  391. size_t underrun;
  392. int rc;
  393. if ( response->status == 0 ) {
  394. scsicmd_done ( scsicmd, 0 );
  395. } else {
  396. DBGC ( scsidev, "SCSI %p tag %08x status %02x",
  397. scsidev, scsicmd->tag, response->status );
  398. if ( response->overrun > 0 ) {
  399. overrun = response->overrun;
  400. DBGC ( scsidev, " overrun +%zd", overrun );
  401. } else if ( response->overrun < 0 ) {
  402. underrun = -(response->overrun);
  403. DBGC ( scsidev, " underrun -%zd", underrun );
  404. }
  405. DBGC ( scsidev, " sense %02x:%02x:%08x\n",
  406. response->sense.code, response->sense.key,
  407. ntohl ( response->sense.info ) );
  408. /* Construct error number from sense data */
  409. rc = -EIO_SENSE ( response->sense.key & SCSI_SENSE_KEY_MASK );
  410. scsicmd_done ( scsicmd, rc );
  411. }
  412. }
  413. /**
  414. * Construct SCSI READ command
  415. *
  416. * @v scsicmd SCSI command
  417. * @v command SCSI command IU
  418. */
  419. static void scsicmd_read_cmd ( struct scsi_command *scsicmd,
  420. struct scsi_cmd *command ) {
  421. if ( ( scsicmd->lba + scsicmd->count ) > SCSI_MAX_BLOCK_10 ) {
  422. /* Use READ (16) */
  423. command->cdb.read16.opcode = SCSI_OPCODE_READ_16;
  424. command->cdb.read16.lba = cpu_to_be64 ( scsicmd->lba );
  425. command->cdb.read16.len = cpu_to_be32 ( scsicmd->count );
  426. } else {
  427. /* Use READ (10) */
  428. command->cdb.read10.opcode = SCSI_OPCODE_READ_10;
  429. command->cdb.read10.lba = cpu_to_be32 ( scsicmd->lba );
  430. command->cdb.read10.len = cpu_to_be16 ( scsicmd->count );
  431. }
  432. command->data_in = scsicmd->buffer;
  433. command->data_in_len = scsicmd->len;
  434. }
  435. /** SCSI READ command type */
  436. static struct scsi_command_type scsicmd_read = {
  437. .name = "READ",
  438. .cmd = scsicmd_read_cmd,
  439. .done = scsicmd_close,
  440. };
  441. /**
  442. * Construct SCSI WRITE command
  443. *
  444. * @v scsicmd SCSI command
  445. * @v command SCSI command IU
  446. */
  447. static void scsicmd_write_cmd ( struct scsi_command *scsicmd,
  448. struct scsi_cmd *command ) {
  449. if ( ( scsicmd->lba + scsicmd->count ) > SCSI_MAX_BLOCK_10 ) {
  450. /* Use WRITE (16) */
  451. command->cdb.write16.opcode = SCSI_OPCODE_WRITE_16;
  452. command->cdb.write16.lba = cpu_to_be64 ( scsicmd->lba );
  453. command->cdb.write16.len = cpu_to_be32 ( scsicmd->count );
  454. } else {
  455. /* Use WRITE (10) */
  456. command->cdb.write10.opcode = SCSI_OPCODE_WRITE_10;
  457. command->cdb.write10.lba = cpu_to_be32 ( scsicmd->lba );
  458. command->cdb.write10.len = cpu_to_be16 ( scsicmd->count );
  459. }
  460. command->data_out = scsicmd->buffer;
  461. command->data_out_len = scsicmd->len;
  462. }
  463. /** SCSI WRITE command type */
  464. static struct scsi_command_type scsicmd_write = {
  465. .name = "WRITE",
  466. .cmd = scsicmd_write_cmd,
  467. .done = scsicmd_close,
  468. };
  469. /** SCSI READ CAPACITY private data */
  470. struct scsi_read_capacity_private {
  471. /** Use READ CAPACITY (16) */
  472. int use16;
  473. /** Data buffer for READ CAPACITY commands */
  474. union {
  475. /** Data buffer for READ CAPACITY (10) */
  476. struct scsi_capacity_10 capacity10;
  477. /** Data buffer for READ CAPACITY (16) */
  478. struct scsi_capacity_16 capacity16;
  479. } capacity;
  480. };
  481. /**
  482. * Construct SCSI READ CAPACITY command
  483. *
  484. * @v scsicmd SCSI command
  485. * @v command SCSI command IU
  486. */
  487. static void scsicmd_read_capacity_cmd ( struct scsi_command *scsicmd,
  488. struct scsi_cmd *command ) {
  489. struct scsi_read_capacity_private *priv = scsicmd_priv ( scsicmd );
  490. struct scsi_cdb_read_capacity_16 *readcap16 = &command->cdb.readcap16;
  491. struct scsi_cdb_read_capacity_10 *readcap10 = &command->cdb.readcap10;
  492. struct scsi_capacity_16 *capacity16 = &priv->capacity.capacity16;
  493. struct scsi_capacity_10 *capacity10 = &priv->capacity.capacity10;
  494. if ( priv->use16 ) {
  495. /* Use READ CAPACITY (16) */
  496. readcap16->opcode = SCSI_OPCODE_SERVICE_ACTION_IN;
  497. readcap16->service_action =
  498. SCSI_SERVICE_ACTION_READ_CAPACITY_16;
  499. readcap16->len = cpu_to_be32 ( sizeof ( *capacity16 ) );
  500. command->data_in = virt_to_user ( capacity16 );
  501. command->data_in_len = sizeof ( *capacity16 );
  502. } else {
  503. /* Use READ CAPACITY (10) */
  504. readcap10->opcode = SCSI_OPCODE_READ_CAPACITY_10;
  505. command->data_in = virt_to_user ( capacity10 );
  506. command->data_in_len = sizeof ( *capacity10 );
  507. }
  508. }
  509. /**
  510. * Handle SCSI READ CAPACITY command completion
  511. *
  512. * @v scsicmd SCSI command
  513. * @v rc Reason for completion
  514. */
  515. static void scsicmd_read_capacity_done ( struct scsi_command *scsicmd,
  516. int rc ) {
  517. struct scsi_read_capacity_private *priv = scsicmd_priv ( scsicmd );
  518. struct scsi_capacity_16 *capacity16 = &priv->capacity.capacity16;
  519. struct scsi_capacity_10 *capacity10 = &priv->capacity.capacity10;
  520. struct block_device_capacity capacity;
  521. /* Close if command failed */
  522. if ( rc != 0 ) {
  523. scsicmd_close ( scsicmd, rc );
  524. return;
  525. }
  526. /* Extract capacity */
  527. if ( priv->use16 ) {
  528. capacity.blocks = ( be64_to_cpu ( capacity16->lba ) + 1 );
  529. capacity.blksize = be32_to_cpu ( capacity16->blksize );
  530. } else {
  531. capacity.blocks = ( be32_to_cpu ( capacity10->lba ) + 1 );
  532. capacity.blksize = be32_to_cpu ( capacity10->blksize );
  533. /* If capacity range was exceeded (i.e. capacity.lba
  534. * was 0xffffffff, meaning that blockdev->blocks is
  535. * now zero), use READ CAPACITY (16) instead. READ
  536. * CAPACITY (16) is not mandatory, so we can't just
  537. * use it straight off.
  538. */
  539. if ( capacity.blocks == 0 ) {
  540. priv->use16 = 1;
  541. if ( ( rc = scsicmd_command ( scsicmd ) ) != 0 ) {
  542. scsicmd_close ( scsicmd, rc );
  543. return;
  544. }
  545. return;
  546. }
  547. }
  548. capacity.max_count = -1U;
  549. /* Return capacity to caller */
  550. block_capacity ( &scsicmd->block, &capacity );
  551. /* Close command */
  552. scsicmd_close ( scsicmd, 0 );
  553. }
  554. /** SCSI READ CAPACITY command type */
  555. static struct scsi_command_type scsicmd_read_capacity = {
  556. .name = "READ CAPACITY",
  557. .priv_len = sizeof ( struct scsi_read_capacity_private ),
  558. .cmd = scsicmd_read_capacity_cmd,
  559. .done = scsicmd_read_capacity_done,
  560. };
  561. /** SCSI command block interface operations */
  562. static struct interface_operation scsicmd_block_op[] = {
  563. INTF_OP ( intf_close, struct scsi_command *, scsicmd_close ),
  564. };
  565. /** SCSI command block interface descriptor */
  566. static struct interface_descriptor scsicmd_block_desc =
  567. INTF_DESC_PASSTHRU ( struct scsi_command, block,
  568. scsicmd_block_op, scsi );
  569. /** SCSI command SCSI interface operations */
  570. static struct interface_operation scsicmd_scsi_op[] = {
  571. INTF_OP ( intf_close, struct scsi_command *, scsicmd_done ),
  572. INTF_OP ( scsi_response, struct scsi_command *, scsicmd_response ),
  573. };
  574. /** SCSI command SCSI interface descriptor */
  575. static struct interface_descriptor scsicmd_scsi_desc =
  576. INTF_DESC_PASSTHRU ( struct scsi_command, scsi,
  577. scsicmd_scsi_op, block );
  578. /**
  579. * Create SCSI command
  580. *
  581. * @v scsidev SCSI device
  582. * @v block Block data interface
  583. * @v type SCSI command type
  584. * @v lba Starting logical block address
  585. * @v count Number of blocks to transfer
  586. * @v buffer Data buffer
  587. * @v len Length of data buffer
  588. * @ret rc Return status code
  589. */
  590. static int scsidev_command ( struct scsi_device *scsidev,
  591. struct interface *block,
  592. struct scsi_command_type *type,
  593. uint64_t lba, unsigned int count,
  594. userptr_t buffer, size_t len ) {
  595. struct scsi_command *scsicmd;
  596. int rc;
  597. /* Allocate and initialise structure */
  598. scsicmd = zalloc ( sizeof ( *scsicmd ) + type->priv_len );
  599. if ( ! scsicmd ) {
  600. rc = -ENOMEM;
  601. goto err_zalloc;
  602. }
  603. ref_init ( &scsicmd->refcnt, scsicmd_free );
  604. intf_init ( &scsicmd->block, &scsicmd_block_desc, &scsicmd->refcnt );
  605. intf_init ( &scsicmd->scsi, &scsicmd_scsi_desc,
  606. &scsicmd->refcnt );
  607. scsicmd->scsidev = scsidev_get ( scsidev );
  608. list_add ( &scsicmd->list, &scsidev->cmds );
  609. scsicmd->type = type;
  610. scsicmd->lba = lba;
  611. scsicmd->count = count;
  612. scsicmd->buffer = buffer;
  613. scsicmd->len = len;
  614. /* Issue SCSI command */
  615. if ( ( rc = scsicmd_command ( scsicmd ) ) != 0 )
  616. goto err_command;
  617. /* Attach to parent interface, mortalise self, and return */
  618. intf_plug_plug ( &scsicmd->block, block );
  619. ref_put ( &scsicmd->refcnt );
  620. return 0;
  621. err_command:
  622. scsicmd_close ( scsicmd, rc );
  623. ref_put ( &scsicmd->refcnt );
  624. err_zalloc:
  625. return rc;
  626. }
  627. /**
  628. * Issue SCSI block read
  629. *
  630. * @v scsidev SCSI device
  631. * @v block Block data interface
  632. * @v lba Starting logical block address
  633. * @v count Number of blocks to transfer
  634. * @v buffer Data buffer
  635. * @v len Length of data buffer
  636. * @ret rc Return status code
  637. */
  638. static int scsidev_read ( struct scsi_device *scsidev,
  639. struct interface *block,
  640. uint64_t lba, unsigned int count,
  641. userptr_t buffer, size_t len ) {
  642. return scsidev_command ( scsidev, block, &scsicmd_read,
  643. lba, count, buffer, len );
  644. }
  645. /**
  646. * Issue SCSI block write
  647. *
  648. * @v scsidev SCSI device
  649. * @v block Block data interface
  650. * @v lba Starting logical block address
  651. * @v count Number of blocks to transfer
  652. * @v buffer Data buffer
  653. * @v len Length of data buffer
  654. * @ret rc Return status code
  655. */
  656. static int scsidev_write ( struct scsi_device *scsidev,
  657. struct interface *block,
  658. uint64_t lba, unsigned int count,
  659. userptr_t buffer, size_t len ) {
  660. return scsidev_command ( scsidev, block, &scsicmd_write,
  661. lba, count, buffer, len );
  662. }
  663. /**
  664. * Read SCSI device capacity
  665. *
  666. * @v scsidev SCSI device
  667. * @v block Block data interface
  668. * @ret rc Return status code
  669. */
  670. static int scsidev_read_capacity ( struct scsi_device *scsidev,
  671. struct interface *block ) {
  672. return scsidev_command ( scsidev, block, &scsicmd_read_capacity,
  673. 0, 0, UNULL, 0 );
  674. }
  675. /**
  676. * Close SCSI device
  677. *
  678. * @v scsidev SCSI device
  679. * @v rc Reason for close
  680. */
  681. static void scsidev_close ( struct scsi_device *scsidev, int rc ) {
  682. struct scsi_command *scsicmd;
  683. struct scsi_command *tmp;
  684. /* Shut down interfaces */
  685. intf_shutdown ( &scsidev->block, rc );
  686. intf_shutdown ( &scsidev->scsi, rc );
  687. /* Shut down any remaining commands */
  688. list_for_each_entry_safe ( scsicmd, tmp, &scsidev->cmds, list ) {
  689. scsicmd_get ( scsicmd );
  690. scsicmd_close ( scsicmd, rc );
  691. scsicmd_put ( scsicmd );
  692. }
  693. }
  694. /** SCSI device block interface operations */
  695. static struct interface_operation scsidev_block_op[] = {
  696. INTF_OP ( block_read, struct scsi_device *, scsidev_read ),
  697. INTF_OP ( block_write, struct scsi_device *, scsidev_write ),
  698. INTF_OP ( block_read_capacity, struct scsi_device *,
  699. scsidev_read_capacity ),
  700. INTF_OP ( intf_close, struct scsi_device *, scsidev_close ),
  701. };
  702. /** SCSI device block interface descriptor */
  703. static struct interface_descriptor scsidev_block_desc =
  704. INTF_DESC_PASSTHRU ( struct scsi_device, block,
  705. scsidev_block_op, scsi );
  706. /** SCSI device SCSI interface operations */
  707. static struct interface_operation scsidev_scsi_op[] = {
  708. INTF_OP ( intf_close, struct scsi_device *, scsidev_close ),
  709. };
  710. /** SCSI device SCSI interface descriptor */
  711. static struct interface_descriptor scsidev_scsi_desc =
  712. INTF_DESC_PASSTHRU ( struct scsi_device, scsi,
  713. scsidev_scsi_op, block );
  714. /**
  715. * Open SCSI device
  716. *
  717. * @v block Block control interface
  718. * @v scsi SCSI control interface
  719. * @v lun SCSI LUN
  720. * @ret rc Return status code
  721. */
  722. int scsi_open ( struct interface *block, struct interface *scsi,
  723. struct scsi_lun *lun ) {
  724. struct scsi_device *scsidev;
  725. /* Allocate and initialise structure */
  726. scsidev = zalloc ( sizeof ( *scsidev ) );
  727. if ( ! scsidev )
  728. return -ENOMEM;
  729. ref_init ( &scsidev->refcnt, NULL );
  730. intf_init ( &scsidev->block, &scsidev_block_desc, &scsidev->refcnt );
  731. intf_init ( &scsidev->scsi, &scsidev_scsi_desc, &scsidev->refcnt );
  732. INIT_LIST_HEAD ( &scsidev->cmds );
  733. memcpy ( &scsidev->lun, lun, sizeof ( scsidev->lun ) );
  734. DBGC ( scsidev, "SCSI %p created for LUN " SCSI_LUN_FORMAT "\n",
  735. scsidev, SCSI_LUN_DATA ( scsidev->lun ) );
  736. /* Attach to SCSI and parent and interfaces, mortalise self,
  737. * and return
  738. */
  739. intf_plug_plug ( &scsidev->scsi, scsi );
  740. intf_plug_plug ( &scsidev->block, block );
  741. ref_put ( &scsidev->refcnt );
  742. return 0;
  743. }