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.

aoe.c 26KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056
  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 <string.h>
  21. #include <stdio.h>
  22. #include <stdlib.h>
  23. #include <errno.h>
  24. #include <assert.h>
  25. #include <byteswap.h>
  26. #include <ipxe/list.h>
  27. #include <ipxe/if_ether.h>
  28. #include <ipxe/iobuf.h>
  29. #include <ipxe/uaccess.h>
  30. #include <ipxe/netdevice.h>
  31. #include <ipxe/features.h>
  32. #include <ipxe/interface.h>
  33. #include <ipxe/xfer.h>
  34. #include <ipxe/uri.h>
  35. #include <ipxe/open.h>
  36. #include <ipxe/ata.h>
  37. #include <ipxe/device.h>
  38. #include <ipxe/aoe.h>
  39. /** @file
  40. *
  41. * AoE protocol
  42. *
  43. */
  44. FEATURE ( FEATURE_PROTOCOL, "AoE", DHCP_EB_FEATURE_AOE, 1 );
  45. struct net_protocol aoe_protocol __net_protocol;
  46. /******************************************************************************
  47. *
  48. * AoE devices and commands
  49. *
  50. ******************************************************************************
  51. */
  52. /** List of all AoE devices */
  53. static LIST_HEAD ( aoe_devices );
  54. /** List of active AoE commands */
  55. static LIST_HEAD ( aoe_commands );
  56. /** An AoE device */
  57. struct aoe_device {
  58. /** Reference counter */
  59. struct refcnt refcnt;
  60. /** Network device */
  61. struct net_device *netdev;
  62. /** ATA command issuing interface */
  63. struct interface ata;
  64. /** Major number */
  65. uint16_t major;
  66. /** Minor number */
  67. uint8_t minor;
  68. /** Target MAC address */
  69. uint8_t target[MAX_LL_ADDR_LEN];
  70. /** Saved timeout value */
  71. unsigned long timeout;
  72. /** Configuration command interface */
  73. struct interface config;
  74. /** Device is configued */
  75. int configured;
  76. };
  77. /** An AoE command */
  78. struct aoe_command {
  79. /** Reference count */
  80. struct refcnt refcnt;
  81. /** AOE device */
  82. struct aoe_device *aoedev;
  83. /** List of active commands */
  84. struct list_head list;
  85. /** ATA command interface */
  86. struct interface ata;
  87. /** ATA command */
  88. struct ata_cmd command;
  89. /** Command type */
  90. struct aoe_command_type *type;
  91. /** Command tag */
  92. uint32_t tag;
  93. /** Retransmission timer */
  94. struct retry_timer timer;
  95. };
  96. /** An AoE command type */
  97. struct aoe_command_type {
  98. /**
  99. * Calculate length of AoE command IU
  100. *
  101. * @v aoecmd AoE command
  102. * @ret len Length of command IU
  103. */
  104. size_t ( * cmd_len ) ( struct aoe_command *aoecmd );
  105. /**
  106. * Build AoE command IU
  107. *
  108. * @v aoecmd AoE command
  109. * @v data Command IU
  110. * @v len Length of command IU
  111. */
  112. void ( * cmd ) ( struct aoe_command *aoecmd, void *data, size_t len );
  113. /**
  114. * Handle AoE response IU
  115. *
  116. * @v aoecmd AoE command
  117. * @v data Response IU
  118. * @v len Length of response IU
  119. * @v ll_source Link-layer source address
  120. * @ret rc Return status code
  121. */
  122. int ( * rsp ) ( struct aoe_command *aoecmd, const void *data,
  123. size_t len, const void *ll_source );
  124. };
  125. /**
  126. * Get reference to AoE device
  127. *
  128. * @v aoedev AoE device
  129. * @ret aoedev AoE device
  130. */
  131. static inline __attribute__ (( always_inline )) struct aoe_device *
  132. aoedev_get ( struct aoe_device *aoedev ) {
  133. ref_get ( &aoedev->refcnt );
  134. return aoedev;
  135. }
  136. /**
  137. * Drop reference to AoE device
  138. *
  139. * @v aoedev AoE device
  140. */
  141. static inline __attribute__ (( always_inline )) void
  142. aoedev_put ( struct aoe_device *aoedev ) {
  143. ref_put ( &aoedev->refcnt );
  144. }
  145. /**
  146. * Get reference to AoE command
  147. *
  148. * @v aoecmd AoE command
  149. * @ret aoecmd AoE command
  150. */
  151. static inline __attribute__ (( always_inline )) struct aoe_command *
  152. aoecmd_get ( struct aoe_command *aoecmd ) {
  153. ref_get ( &aoecmd->refcnt );
  154. return aoecmd;
  155. }
  156. /**
  157. * Drop reference to AoE command
  158. *
  159. * @v aoecmd AoE command
  160. */
  161. static inline __attribute__ (( always_inline )) void
  162. aoecmd_put ( struct aoe_command *aoecmd ) {
  163. ref_put ( &aoecmd->refcnt );
  164. }
  165. /**
  166. * Name AoE device
  167. *
  168. * @v aoedev AoE device
  169. * @ret name AoE device name
  170. */
  171. static const char * aoedev_name ( struct aoe_device *aoedev ) {
  172. static char buf[16];
  173. snprintf ( buf, sizeof ( buf ), "%s/e%d.%d", aoedev->netdev->name,
  174. aoedev->major, aoedev->minor );
  175. return buf;
  176. }
  177. /**
  178. * Free AoE command
  179. *
  180. * @v refcnt Reference counter
  181. */
  182. static void aoecmd_free ( struct refcnt *refcnt ) {
  183. struct aoe_command *aoecmd =
  184. container_of ( refcnt, struct aoe_command, refcnt );
  185. assert ( ! timer_running ( &aoecmd->timer ) );
  186. assert ( list_empty ( &aoecmd->list ) );
  187. aoedev_put ( aoecmd->aoedev );
  188. free ( aoecmd );
  189. }
  190. /**
  191. * Close AoE command
  192. *
  193. * @v aoecmd AoE command
  194. * @v rc Reason for close
  195. */
  196. static void aoecmd_close ( struct aoe_command *aoecmd, int rc ) {
  197. struct aoe_device *aoedev = aoecmd->aoedev;
  198. /* Stop timer */
  199. stop_timer ( &aoecmd->timer );
  200. /* Preserve the timeout value for subsequent commands */
  201. aoedev->timeout = aoecmd->timer.timeout;
  202. /* Remove from list of commands */
  203. if ( ! list_empty ( &aoecmd->list ) ) {
  204. list_del ( &aoecmd->list );
  205. INIT_LIST_HEAD ( &aoecmd->list );
  206. aoecmd_put ( aoecmd );
  207. }
  208. /* Shut down interfaces */
  209. intf_shutdown ( &aoecmd->ata, rc );
  210. }
  211. /**
  212. * Transmit AoE command request
  213. *
  214. * @v aoecmd AoE command
  215. * @ret rc Return status code
  216. */
  217. static int aoecmd_tx ( struct aoe_command *aoecmd ) {
  218. struct aoe_device *aoedev = aoecmd->aoedev;
  219. struct net_device *netdev = aoedev->netdev;
  220. struct io_buffer *iobuf;
  221. struct aoehdr *aoehdr;
  222. size_t cmd_len;
  223. int rc;
  224. /* Sanity check */
  225. assert ( netdev != NULL );
  226. /* If we are transmitting anything that requires a response,
  227. * start the retransmission timer. Do this before attempting
  228. * to allocate the I/O buffer, in case allocation itself
  229. * fails.
  230. */
  231. start_timer ( &aoecmd->timer );
  232. /* Create outgoing I/O buffer */
  233. cmd_len = aoecmd->type->cmd_len ( aoecmd );
  234. iobuf = alloc_iob ( MAX_LL_HEADER_LEN + cmd_len );
  235. if ( ! iobuf )
  236. return -ENOMEM;
  237. iob_reserve ( iobuf, MAX_LL_HEADER_LEN );
  238. aoehdr = iob_put ( iobuf, cmd_len );
  239. /* Fill AoE header */
  240. memset ( aoehdr, 0, sizeof ( *aoehdr ) );
  241. aoehdr->ver_flags = AOE_VERSION;
  242. aoehdr->major = htons ( aoedev->major );
  243. aoehdr->minor = aoedev->minor;
  244. aoehdr->tag = htonl ( aoecmd->tag );
  245. aoecmd->type->cmd ( aoecmd, iobuf->data, iob_len ( iobuf ) );
  246. /* Send packet */
  247. if ( ( rc = net_tx ( iobuf, netdev, &aoe_protocol, aoedev->target,
  248. netdev->ll_addr ) ) != 0 ) {
  249. DBGC ( aoedev, "AoE %s/%08x could not transmit: %s\n",
  250. aoedev_name ( aoedev ), aoecmd->tag,
  251. strerror ( rc ) );
  252. return rc;
  253. }
  254. return 0;
  255. }
  256. /**
  257. * Receive AoE command response
  258. *
  259. * @v aoecmd AoE command
  260. * @v iobuf I/O buffer
  261. * @v ll_source Link-layer source address
  262. * @ret rc Return status code
  263. */
  264. static int aoecmd_rx ( struct aoe_command *aoecmd, struct io_buffer *iobuf,
  265. const void *ll_source ) {
  266. struct aoe_device *aoedev = aoecmd->aoedev;
  267. struct aoehdr *aoehdr = iobuf->data;
  268. int rc;
  269. /* Sanity check */
  270. if ( iob_len ( iobuf ) < sizeof ( *aoehdr ) ) {
  271. DBGC ( aoedev, "AoE %s/%08x received underlength response "
  272. "(%zd bytes)\n", aoedev_name ( aoedev ),
  273. aoecmd->tag, iob_len ( iobuf ) );
  274. rc = -EINVAL;
  275. goto done;
  276. }
  277. if ( ( ntohs ( aoehdr->major ) != aoedev->major ) ||
  278. ( aoehdr->minor != aoedev->minor ) ) {
  279. DBGC ( aoedev, "AoE %s/%08x received response for incorrect "
  280. "device e%d.%d\n", aoedev_name ( aoedev ), aoecmd->tag,
  281. ntohs ( aoehdr->major ), aoehdr->minor );
  282. rc = -EINVAL;
  283. goto done;
  284. }
  285. /* Catch command failures */
  286. if ( aoehdr->ver_flags & AOE_FL_ERROR ) {
  287. DBGC ( aoedev, "AoE %s/%08x terminated in error\n",
  288. aoedev_name ( aoedev ), aoecmd->tag );
  289. aoecmd_close ( aoecmd, -EIO );
  290. rc = -EIO;
  291. goto done;
  292. }
  293. /* Hand off to command completion handler */
  294. if ( ( rc = aoecmd->type->rsp ( aoecmd, iobuf->data, iob_len ( iobuf ),
  295. ll_source ) ) != 0 )
  296. goto done;
  297. done:
  298. /* Free I/O buffer */
  299. free_iob ( iobuf );
  300. /* Terminate command */
  301. aoecmd_close ( aoecmd, rc );
  302. return rc;
  303. }
  304. /**
  305. * Handle AoE retry timer expiry
  306. *
  307. * @v timer AoE retry timer
  308. * @v fail Failure indicator
  309. */
  310. static void aoecmd_expired ( struct retry_timer *timer, int fail ) {
  311. struct aoe_command *aoecmd =
  312. container_of ( timer, struct aoe_command, timer );
  313. if ( fail ) {
  314. aoecmd_close ( aoecmd, -ETIMEDOUT );
  315. } else {
  316. aoecmd_tx ( aoecmd );
  317. }
  318. }
  319. /**
  320. * Calculate length of AoE ATA command IU
  321. *
  322. * @v aoecmd AoE command
  323. * @ret len Length of command IU
  324. */
  325. static size_t aoecmd_ata_cmd_len ( struct aoe_command *aoecmd ) {
  326. struct ata_cmd *command = &aoecmd->command;
  327. return ( sizeof ( struct aoehdr ) + sizeof ( struct aoeata ) +
  328. command->data_out_len );
  329. }
  330. /**
  331. * Build AoE ATA command IU
  332. *
  333. * @v aoecmd AoE command
  334. * @v data Command IU
  335. * @v len Length of command IU
  336. */
  337. static void aoecmd_ata_cmd ( struct aoe_command *aoecmd,
  338. void *data, size_t len ) {
  339. struct aoe_device *aoedev = aoecmd->aoedev;
  340. struct ata_cmd *command = &aoecmd->command;
  341. struct aoehdr *aoehdr = data;
  342. struct aoeata *aoeata = &aoehdr->payload[0].ata;
  343. /* Sanity check */
  344. linker_assert ( AOE_FL_DEV_HEAD == ATA_DEV_SLAVE, __fix_ata_h__ );
  345. assert ( len == ( sizeof ( *aoehdr ) + sizeof ( *aoeata ) +
  346. command->data_out_len ) );
  347. /* Build IU */
  348. aoehdr->command = AOE_CMD_ATA;
  349. memset ( aoeata, 0, sizeof ( *aoeata ) );
  350. aoeata->aflags = ( ( command->cb.lba48 ? AOE_FL_EXTENDED : 0 ) |
  351. ( command->cb.device & ATA_DEV_SLAVE ) |
  352. ( command->data_out_len ? AOE_FL_WRITE : 0 ) );
  353. aoeata->err_feat = command->cb.err_feat.bytes.cur;
  354. aoeata->count = command->cb.count.native;
  355. aoeata->cmd_stat = command->cb.cmd_stat;
  356. aoeata->lba.u64 = cpu_to_le64 ( command->cb.lba.native );
  357. if ( ! command->cb.lba48 )
  358. aoeata->lba.bytes[3] |=
  359. ( command->cb.device & ATA_DEV_MASK );
  360. copy_from_user ( aoeata->data, command->data_out, 0,
  361. command->data_out_len );
  362. DBGC2 ( aoedev, "AoE %s/%08x ATA cmd %02x:%02x:%02x:%02x:%08llx",
  363. aoedev_name ( aoedev ), aoecmd->tag, aoeata->aflags,
  364. aoeata->err_feat, aoeata->count, aoeata->cmd_stat,
  365. aoeata->lba.u64 );
  366. if ( command->data_out_len )
  367. DBGC2 ( aoedev, " out %04zx", command->data_out_len );
  368. if ( command->data_in_len )
  369. DBGC2 ( aoedev, " in %04zx", command->data_in_len );
  370. DBGC2 ( aoedev, "\n" );
  371. }
  372. /**
  373. * Handle AoE ATA response IU
  374. *
  375. * @v aoecmd AoE command
  376. * @v data Response IU
  377. * @v len Length of response IU
  378. * @v ll_source Link-layer source address
  379. * @ret rc Return status code
  380. */
  381. static int aoecmd_ata_rsp ( struct aoe_command *aoecmd, const void *data,
  382. size_t len, const void *ll_source __unused ) {
  383. struct aoe_device *aoedev = aoecmd->aoedev;
  384. struct ata_cmd *command = &aoecmd->command;
  385. const struct aoehdr *aoehdr = data;
  386. const struct aoeata *aoeata = &aoehdr->payload[0].ata;
  387. size_t data_len;
  388. /* Sanity check */
  389. if ( len < ( sizeof ( *aoehdr ) + sizeof ( *aoeata ) ) ) {
  390. DBGC ( aoedev, "AoE %s/%08x received underlength ATA response "
  391. "(%zd bytes)\n", aoedev_name ( aoedev ),
  392. aoecmd->tag, len );
  393. return -EINVAL;
  394. }
  395. data_len = ( len - ( sizeof ( *aoehdr ) + sizeof ( *aoeata ) ) );
  396. DBGC2 ( aoedev, "AoE %s/%08x ATA rsp %02x in %04zx\n",
  397. aoedev_name ( aoedev ), aoecmd->tag, aoeata->cmd_stat,
  398. data_len );
  399. /* Check for command failure */
  400. if ( aoeata->cmd_stat & ATA_STAT_ERR ) {
  401. DBGC ( aoedev, "AoE %s/%08x status %02x\n",
  402. aoedev_name ( aoedev ), aoecmd->tag, aoeata->cmd_stat );
  403. return -EIO;
  404. }
  405. /* Check data-in length is sufficient. (There may be trailing
  406. * garbage due to Ethernet minimum-frame-size padding.)
  407. */
  408. if ( data_len < command->data_in_len ) {
  409. DBGC ( aoedev, "AoE %s/%08x data-in underrun (received %zd, "
  410. "expected %zd)\n", aoedev_name ( aoedev ), aoecmd->tag,
  411. data_len, command->data_in_len );
  412. return -ERANGE;
  413. }
  414. /* Copy out data payload */
  415. copy_to_user ( command->data_in, 0, aoeata->data,
  416. command->data_in_len );
  417. return 0;
  418. }
  419. /** AoE ATA command */
  420. static struct aoe_command_type aoecmd_ata = {
  421. .cmd_len = aoecmd_ata_cmd_len,
  422. .cmd = aoecmd_ata_cmd,
  423. .rsp = aoecmd_ata_rsp,
  424. };
  425. /**
  426. * Calculate length of AoE configuration command IU
  427. *
  428. * @v aoecmd AoE command
  429. * @ret len Length of command IU
  430. */
  431. static size_t aoecmd_cfg_cmd_len ( struct aoe_command *aoecmd __unused ) {
  432. return ( sizeof ( struct aoehdr ) + sizeof ( struct aoecfg ) );
  433. }
  434. /**
  435. * Build AoE configuration command IU
  436. *
  437. * @v aoecmd AoE command
  438. * @v data Command IU
  439. * @v len Length of command IU
  440. */
  441. static void aoecmd_cfg_cmd ( struct aoe_command *aoecmd,
  442. void *data, size_t len ) {
  443. struct aoe_device *aoedev = aoecmd->aoedev;
  444. struct aoehdr *aoehdr = data;
  445. struct aoecfg *aoecfg = &aoehdr->payload[0].cfg;
  446. /* Sanity check */
  447. assert ( len == ( sizeof ( *aoehdr ) + sizeof ( *aoecfg ) ) );
  448. /* Build IU */
  449. aoehdr->command = AOE_CMD_CONFIG;
  450. memset ( aoecfg, 0, sizeof ( *aoecfg ) );
  451. DBGC ( aoedev, "AoE %s/%08x CONFIG cmd\n",
  452. aoedev_name ( aoedev ), aoecmd->tag );
  453. }
  454. /**
  455. * Handle AoE configuration response IU
  456. *
  457. * @v aoecmd AoE command
  458. * @v data Response IU
  459. * @v len Length of response IU
  460. * @v ll_source Link-layer source address
  461. * @ret rc Return status code
  462. */
  463. static int aoecmd_cfg_rsp ( struct aoe_command *aoecmd, const void *data,
  464. size_t len, const void *ll_source ) {
  465. struct aoe_device *aoedev = aoecmd->aoedev;
  466. struct ll_protocol *ll_protocol = aoedev->netdev->ll_protocol;
  467. const struct aoehdr *aoehdr = data;
  468. const struct aoecfg *aoecfg = &aoehdr->payload[0].cfg;
  469. /* Sanity check */
  470. if ( len < ( sizeof ( *aoehdr ) + sizeof ( *aoecfg ) ) ) {
  471. DBGC ( aoedev, "AoE %s/%08x received underlength "
  472. "configuration response (%zd bytes)\n",
  473. aoedev_name ( aoedev ), aoecmd->tag, len );
  474. return -EINVAL;
  475. }
  476. DBGC ( aoedev, "AoE %s/%08x CONFIG rsp buf %04x fw %04x scnt %02x\n",
  477. aoedev_name ( aoedev ), aoecmd->tag, ntohs ( aoecfg->bufcnt ),
  478. aoecfg->fwver, aoecfg->scnt );
  479. /* Record target MAC address */
  480. memcpy ( aoedev->target, ll_source, ll_protocol->ll_addr_len );
  481. DBGC ( aoedev, "AoE %s has MAC address %s\n",
  482. aoedev_name ( aoedev ), ll_protocol->ntoa ( aoedev->target ) );
  483. return 0;
  484. }
  485. /** AoE configuration command */
  486. static struct aoe_command_type aoecmd_cfg = {
  487. .cmd_len = aoecmd_cfg_cmd_len,
  488. .cmd = aoecmd_cfg_cmd,
  489. .rsp = aoecmd_cfg_rsp,
  490. };
  491. /** AoE command ATA interface operations */
  492. static struct interface_operation aoecmd_ata_op[] = {
  493. INTF_OP ( intf_close, struct aoe_command *, aoecmd_close ),
  494. };
  495. /** AoE command ATA interface descriptor */
  496. static struct interface_descriptor aoecmd_ata_desc =
  497. INTF_DESC ( struct aoe_command, ata, aoecmd_ata_op );
  498. /**
  499. * Identify AoE command by tag
  500. *
  501. * @v tag Command tag
  502. * @ret aoecmd AoE command, or NULL
  503. */
  504. static struct aoe_command * aoecmd_find_tag ( uint32_t tag ) {
  505. struct aoe_command *aoecmd;
  506. list_for_each_entry ( aoecmd, &aoe_commands, list ) {
  507. if ( aoecmd->tag == tag )
  508. return aoecmd;
  509. }
  510. return NULL;
  511. }
  512. /**
  513. * Choose an AoE command tag
  514. *
  515. * @ret tag New tag, or negative error
  516. */
  517. static int aoecmd_new_tag ( void ) {
  518. static uint16_t tag_idx;
  519. unsigned int i;
  520. for ( i = 0 ; i < 65536 ; i++ ) {
  521. tag_idx++;
  522. if ( aoecmd_find_tag ( tag_idx ) == NULL )
  523. return ( AOE_TAG_MAGIC | tag_idx );
  524. }
  525. return -EADDRINUSE;
  526. }
  527. /**
  528. * Create AoE command
  529. *
  530. * @v aoedev AoE device
  531. * @v type AoE command type
  532. * @ret aoecmd AoE command
  533. */
  534. static struct aoe_command * aoecmd_create ( struct aoe_device *aoedev,
  535. struct aoe_command_type *type ) {
  536. struct aoe_command *aoecmd;
  537. int tag;
  538. /* Allocate command tag */
  539. tag = aoecmd_new_tag();
  540. if ( tag < 0 )
  541. return NULL;
  542. /* Allocate and initialise structure */
  543. aoecmd = zalloc ( sizeof ( *aoecmd ) );
  544. if ( ! aoecmd )
  545. return NULL;
  546. ref_init ( &aoecmd->refcnt, aoecmd_free );
  547. list_add ( &aoecmd->list, &aoe_commands );
  548. intf_init ( &aoecmd->ata, &aoecmd_ata_desc, &aoecmd->refcnt );
  549. timer_init ( &aoecmd->timer, aoecmd_expired, &aoecmd->refcnt );
  550. aoecmd->aoedev = aoedev_get ( aoedev );
  551. aoecmd->type = type;
  552. aoecmd->tag = tag;
  553. /* Preserve timeout from last completed command */
  554. aoecmd->timer.timeout = aoedev->timeout;
  555. /* Return already mortalised. (Reference is held by command list.) */
  556. return aoecmd;
  557. }
  558. /**
  559. * Issue AoE ATA command
  560. *
  561. * @v aoedev AoE device
  562. * @v parent Parent interface
  563. * @v command ATA command
  564. * @ret tag Command tag, or negative error
  565. */
  566. static int aoedev_ata_command ( struct aoe_device *aoedev,
  567. struct interface *parent,
  568. struct ata_cmd *command ) {
  569. struct net_device *netdev = aoedev->netdev;
  570. struct aoe_command *aoecmd;
  571. /* Fail immediately if net device is closed */
  572. if ( ! netdev_is_open ( netdev ) ) {
  573. DBGC ( aoedev, "AoE %s cannot issue command while net device "
  574. "is closed\n", aoedev_name ( aoedev ) );
  575. return -EWOULDBLOCK;
  576. }
  577. /* Create command */
  578. aoecmd = aoecmd_create ( aoedev, &aoecmd_ata );
  579. if ( ! aoecmd )
  580. return -ENOMEM;
  581. memcpy ( &aoecmd->command, command, sizeof ( aoecmd->command ) );
  582. /* Attempt to send command. Allow failures to be handled by
  583. * the retry timer.
  584. */
  585. aoecmd_tx ( aoecmd );
  586. /* Attach to parent interface, leave reference with command
  587. * list, and return.
  588. */
  589. intf_plug_plug ( &aoecmd->ata, parent );
  590. return aoecmd->tag;
  591. }
  592. /**
  593. * Issue AoE configuration command
  594. *
  595. * @v aoedev AoE device
  596. * @v parent Parent interface
  597. * @ret tag Command tag, or negative error
  598. */
  599. static int aoedev_cfg_command ( struct aoe_device *aoedev,
  600. struct interface *parent ) {
  601. struct aoe_command *aoecmd;
  602. /* Create command */
  603. aoecmd = aoecmd_create ( aoedev, &aoecmd_cfg );
  604. if ( ! aoecmd )
  605. return -ENOMEM;
  606. /* Attempt to send command. Allow failures to be handled by
  607. * the retry timer.
  608. */
  609. aoecmd_tx ( aoecmd );
  610. /* Attach to parent interface, leave reference with command
  611. * list, and return.
  612. */
  613. intf_plug_plug ( &aoecmd->ata, parent );
  614. return aoecmd->tag;
  615. }
  616. /**
  617. * Free AoE device
  618. *
  619. * @v refcnt Reference count
  620. */
  621. static void aoedev_free ( struct refcnt *refcnt ) {
  622. struct aoe_device *aoedev =
  623. container_of ( refcnt, struct aoe_device, refcnt );
  624. netdev_put ( aoedev->netdev );
  625. free ( aoedev );
  626. }
  627. /**
  628. * Close AoE device
  629. *
  630. * @v aoedev AoE device
  631. * @v rc Reason for close
  632. */
  633. static void aoedev_close ( struct aoe_device *aoedev, int rc ) {
  634. struct aoe_command *aoecmd;
  635. struct aoe_command *tmp;
  636. /* Shut down interfaces */
  637. intf_shutdown ( &aoedev->ata, rc );
  638. intf_shutdown ( &aoedev->config, rc );
  639. /* Shut down any active commands */
  640. list_for_each_entry_safe ( aoecmd, tmp, &aoe_commands, list ) {
  641. if ( aoecmd->aoedev != aoedev )
  642. continue;
  643. aoecmd_get ( aoecmd );
  644. aoecmd_close ( aoecmd, rc );
  645. aoecmd_put ( aoecmd );
  646. }
  647. }
  648. /**
  649. * Check AoE device flow-control window
  650. *
  651. * @v aoedev AoE device
  652. * @ret len Length of window
  653. */
  654. static size_t aoedev_window ( struct aoe_device *aoedev ) {
  655. return ( aoedev->configured ? ~( ( size_t ) 0 ) : 0 );
  656. }
  657. /**
  658. * Handle AoE device configuration completion
  659. *
  660. * @v aoedev AoE device
  661. * @v rc Reason for completion
  662. */
  663. static void aoedev_config_done ( struct aoe_device *aoedev, int rc ) {
  664. /* Shut down interface */
  665. intf_shutdown ( &aoedev->config, rc );
  666. /* Close device on failure */
  667. if ( rc != 0 ) {
  668. aoedev_close ( aoedev, rc );
  669. return;
  670. }
  671. /* Mark device as configured */
  672. aoedev->configured = 1;
  673. xfer_window_changed ( &aoedev->ata );
  674. }
  675. /**
  676. * Identify device underlying AoE device
  677. *
  678. * @v aoedev AoE device
  679. * @ret device Underlying device
  680. */
  681. static struct device * aoedev_identify_device ( struct aoe_device *aoedev ) {
  682. return aoedev->netdev->dev;
  683. }
  684. /**
  685. * Describe AoE device in an ACPI table
  686. *
  687. * @v aoedev AoE device
  688. * @v acpi ACPI table
  689. * @v len Length of ACPI table
  690. * @ret rc Return status code
  691. */
  692. static int aoedev_describe ( struct aoe_device *aoedev,
  693. struct acpi_description_header *acpi,
  694. size_t len ) {
  695. struct abft_table *abft =
  696. container_of ( acpi, struct abft_table, acpi );
  697. /* Sanity check */
  698. if ( len < sizeof ( *abft ) )
  699. return -ENOBUFS;
  700. /* Populate table */
  701. abft->acpi.signature = cpu_to_le32 ( ABFT_SIG );
  702. abft->acpi.length = cpu_to_le32 ( sizeof ( *abft ) );
  703. abft->acpi.revision = 1;
  704. abft->shelf = cpu_to_le16 ( aoedev->major );
  705. abft->slot = aoedev->minor;
  706. memcpy ( abft->mac, aoedev->netdev->ll_addr, sizeof ( abft->mac ) );
  707. return 0;
  708. }
  709. /** AoE device ATA interface operations */
  710. static struct interface_operation aoedev_ata_op[] = {
  711. INTF_OP ( ata_command, struct aoe_device *, aoedev_ata_command ),
  712. INTF_OP ( xfer_window, struct aoe_device *, aoedev_window ),
  713. INTF_OP ( intf_close, struct aoe_device *, aoedev_close ),
  714. INTF_OP ( acpi_describe, struct aoe_device *, aoedev_describe ),
  715. INTF_OP ( identify_device, struct aoe_device *,
  716. aoedev_identify_device ),
  717. };
  718. /** AoE device ATA interface descriptor */
  719. static struct interface_descriptor aoedev_ata_desc =
  720. INTF_DESC ( struct aoe_device, ata, aoedev_ata_op );
  721. /** AoE device configuration interface operations */
  722. static struct interface_operation aoedev_config_op[] = {
  723. INTF_OP ( intf_close, struct aoe_device *, aoedev_config_done ),
  724. };
  725. /** AoE device configuration interface descriptor */
  726. static struct interface_descriptor aoedev_config_desc =
  727. INTF_DESC ( struct aoe_device, config, aoedev_config_op );
  728. /**
  729. * Open AoE device
  730. *
  731. * @v parent Parent interface
  732. * @v netdev Network device
  733. * @v major Device major number
  734. * @v minor Device minor number
  735. * @ret rc Return status code
  736. */
  737. static int aoedev_open ( struct interface *parent, struct net_device *netdev,
  738. unsigned int major, unsigned int minor ) {
  739. struct aoe_device *aoedev;
  740. int rc;
  741. /* Allocate and initialise structure */
  742. aoedev = zalloc ( sizeof ( *aoedev ) );
  743. if ( ! aoedev ) {
  744. rc = -ENOMEM;
  745. goto err_zalloc;
  746. }
  747. ref_init ( &aoedev->refcnt, aoedev_free );
  748. intf_init ( &aoedev->ata, &aoedev_ata_desc, &aoedev->refcnt );
  749. intf_init ( &aoedev->config, &aoedev_config_desc, &aoedev->refcnt );
  750. aoedev->netdev = netdev_get ( netdev );
  751. aoedev->major = major;
  752. aoedev->minor = minor;
  753. memcpy ( aoedev->target, netdev->ll_broadcast,
  754. netdev->ll_protocol->ll_addr_len );
  755. /* Initiate configuration */
  756. if ( ( rc = aoedev_cfg_command ( aoedev, &aoedev->config ) ) < 0 ) {
  757. DBGC ( aoedev, "AoE %s could not initiate configuration: %s\n",
  758. aoedev_name ( aoedev ), strerror ( rc ) );
  759. goto err_config;
  760. }
  761. /* Attach ATA device to parent interface */
  762. if ( ( rc = ata_open ( parent, &aoedev->ata, ATA_DEV_MASTER,
  763. AOE_MAX_COUNT ) ) != 0 ) {
  764. DBGC ( aoedev, "AoE %s could not create ATA device: %s\n",
  765. aoedev_name ( aoedev ), strerror ( rc ) );
  766. goto err_ata_open;
  767. }
  768. /* Mortalise self and return */
  769. ref_put ( &aoedev->refcnt );
  770. return 0;
  771. err_ata_open:
  772. err_config:
  773. aoedev_close ( aoedev, rc );
  774. ref_put ( &aoedev->refcnt );
  775. err_zalloc:
  776. return rc;
  777. }
  778. /******************************************************************************
  779. *
  780. * AoE network protocol
  781. *
  782. ******************************************************************************
  783. */
  784. /**
  785. * Process incoming AoE packets
  786. *
  787. * @v iobuf I/O buffer
  788. * @v netdev Network device
  789. * @v ll_dest Link-layer destination address
  790. * @v ll_source Link-layer source address
  791. * @v flags Packet flags
  792. * @ret rc Return status code
  793. */
  794. static int aoe_rx ( struct io_buffer *iobuf,
  795. struct net_device *netdev __unused,
  796. const void *ll_dest __unused,
  797. const void *ll_source,
  798. unsigned int flags __unused ) {
  799. struct aoehdr *aoehdr = iobuf->data;
  800. struct aoe_command *aoecmd;
  801. int rc;
  802. /* Sanity check */
  803. if ( iob_len ( iobuf ) < sizeof ( *aoehdr ) ) {
  804. DBG ( "AoE received underlength packet (%zd bytes)\n",
  805. iob_len ( iobuf ) );
  806. rc = -EINVAL;
  807. goto err_sanity;
  808. }
  809. if ( ( aoehdr->ver_flags & AOE_VERSION_MASK ) != AOE_VERSION ) {
  810. DBG ( "AoE received packet for unsupported protocol version "
  811. "%02x\n", ( aoehdr->ver_flags & AOE_VERSION_MASK ) );
  812. rc = -EPROTONOSUPPORT;
  813. goto err_sanity;
  814. }
  815. if ( ! ( aoehdr->ver_flags & AOE_FL_RESPONSE ) ) {
  816. DBG ( "AoE received request packet\n" );
  817. rc = -EOPNOTSUPP;
  818. goto err_sanity;
  819. }
  820. /* Demultiplex amongst active AoE commands */
  821. aoecmd = aoecmd_find_tag ( ntohl ( aoehdr->tag ) );
  822. if ( ! aoecmd ) {
  823. DBG ( "AoE received packet for unused tag %08x\n",
  824. ntohl ( aoehdr->tag ) );
  825. rc = -ENOENT;
  826. goto err_demux;
  827. }
  828. /* Pass received frame to command */
  829. aoecmd_get ( aoecmd );
  830. if ( ( rc = aoecmd_rx ( aoecmd, iob_disown ( iobuf ),
  831. ll_source ) ) != 0 )
  832. goto err_rx;
  833. err_rx:
  834. aoecmd_put ( aoecmd );
  835. err_demux:
  836. err_sanity:
  837. free_iob ( iobuf );
  838. return rc;
  839. }
  840. /** AoE protocol */
  841. struct net_protocol aoe_protocol __net_protocol = {
  842. .name = "AoE",
  843. .net_proto = htons ( ETH_P_AOE ),
  844. .rx = aoe_rx,
  845. };
  846. /******************************************************************************
  847. *
  848. * AoE URIs
  849. *
  850. ******************************************************************************
  851. */
  852. /**
  853. * Parse AoE URI
  854. *
  855. * @v uri URI
  856. * @ret major Major device number
  857. * @ret minor Minor device number
  858. * @ret rc Return status code
  859. *
  860. * An AoE URI has the form "aoe:e<major>.<minor>".
  861. */
  862. static int aoe_parse_uri ( struct uri *uri, unsigned int *major,
  863. unsigned int *minor ) {
  864. const char *ptr;
  865. char *end;
  866. /* Check for URI with opaque portion */
  867. if ( ! uri->opaque )
  868. return -EINVAL;
  869. ptr = uri->opaque;
  870. /* Check for initial 'e' */
  871. if ( *ptr != 'e' )
  872. return -EINVAL;
  873. ptr++;
  874. /* Parse major device number */
  875. *major = strtoul ( ptr, &end, 10 );
  876. if ( *end != '.' )
  877. return -EINVAL;
  878. ptr = ( end + 1 );
  879. /* Parse minor device number */
  880. *minor = strtoul ( ptr, &end, 10 );
  881. if ( *end )
  882. return -EINVAL;
  883. return 0;
  884. }
  885. /**
  886. * Open AoE URI
  887. *
  888. * @v parent Parent interface
  889. * @v uri URI
  890. * @ret rc Return status code
  891. */
  892. static int aoe_open ( struct interface *parent, struct uri *uri ) {
  893. struct net_device *netdev;
  894. unsigned int major;
  895. unsigned int minor;
  896. int rc;
  897. /* Identify network device. This is something of a hack, but
  898. * the AoE URI scheme that has been in use for some time now
  899. * provides no way to specify a particular device.
  900. */
  901. netdev = last_opened_netdev();
  902. if ( ! netdev ) {
  903. DBG ( "AoE cannot identify network device\n" );
  904. return -ENODEV;
  905. }
  906. /* Parse URI */
  907. if ( ( rc = aoe_parse_uri ( uri, &major, &minor ) ) != 0 ) {
  908. DBG ( "AoE cannot parse URI\n" );
  909. return rc;
  910. }
  911. /* Open AoE device */
  912. if ( ( rc = aoedev_open ( parent, netdev, major, minor ) ) != 0 )
  913. return rc;
  914. return 0;
  915. }
  916. /** AoE URI opener */
  917. struct uri_opener aoe_uri_opener __uri_opener = {
  918. .scheme = "aoe",
  919. .open = aoe_open,
  920. };