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.

scsi.c 27KB

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