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

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