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 28KB

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