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

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