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

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