From 4de0e273a78f22dbc62e79906c79fc4579aeac54 Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Fri, 19 Dec 2014 18:09:04 +0000 Subject: [PATCH] [rndis] Send RNDIS_HALT_MSG The RNDIS specification requires that we send RNDIS_HALT_MSG. Signed-off-by: Michael Brown --- src/include/ipxe/rndis.h | 2 +- src/net/rndis.c | 58 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 1 deletion(-) diff --git a/src/include/ipxe/rndis.h b/src/include/ipxe/rndis.h index 4e4ab7f8f..bd6793e46 100644 --- a/src/include/ipxe/rndis.h +++ b/src/include/ipxe/rndis.h @@ -88,7 +88,7 @@ struct rndis_initialise_completion { } __attribute__ (( packed )); /** RNDIS halt message */ -#define RNIS_HALT_MSG 0x00000003UL +#define RNDIS_HALT_MSG 0x00000003UL /** RNDIS halt message */ struct rndis_halt_message { diff --git a/src/net/rndis.c b/src/net/rndis.c index 0de3d3a66..62a26ad58 100644 --- a/src/net/rndis.c +++ b/src/net/rndis.c @@ -367,6 +367,56 @@ static int rndis_initialise ( struct rndis_device *rndis ) { return 0; } +/** + * Transmit halt message + * + * @v rndis RNDIS device + * @ret rc Return status code + */ +static int rndis_tx_halt ( struct rndis_device *rndis ) { + struct io_buffer *iobuf; + struct rndis_halt_message *msg; + int rc; + + /* Allocate I/O buffer */ + iobuf = rndis_alloc_iob ( sizeof ( *msg ) ); + if ( ! iobuf ) { + rc = -ENOMEM; + goto err_alloc; + } + + /* Construct message */ + msg = iob_put ( iobuf, sizeof ( *msg ) ); + memset ( msg, 0, sizeof ( *msg ) ); + + /* Transmit message */ + if ( ( rc = rndis_tx_message ( rndis, iobuf, RNDIS_HALT_MSG ) ) != 0 ) + goto err_tx; + + return 0; + + err_tx: + free_iob ( iobuf ); + err_alloc: + return rc; +} + +/** + * Halt RNDIS + * + * @v rndis RNDIS device + * @ret rc Return status code + */ +static int rndis_halt ( struct rndis_device *rndis ) { + int rc; + + /* Transmit halt message */ + if ( ( rc = rndis_tx_halt ( rndis ) ) != 0 ) + return rc; + + return 0; +} + /** * Transmit OID message * @@ -822,6 +872,7 @@ static int rndis_open ( struct net_device *netdev ) { err_query_link: err_set_filter: + rndis_halt ( rndis ); err_initialise: rndis->op->close ( rndis ); err_open: @@ -836,6 +887,9 @@ static int rndis_open ( struct net_device *netdev ) { static void rndis_close ( struct net_device *netdev ) { struct rndis_device *rndis = netdev->priv; + /* Halt RNDIS device */ + rndis_halt ( rndis ); + /* Close RNDIS device */ rndis->op->close ( rndis ); } @@ -947,6 +1001,9 @@ int register_rndis ( struct rndis_device *rndis ) { NULL, 0 ) ) != 0 ) goto err_query_link; + /* Halt RNDIS device */ + rndis_halt ( rndis ); + /* Close RNDIS device */ rndis->op->close ( rndis ); @@ -955,6 +1012,7 @@ int register_rndis ( struct rndis_device *rndis ) { err_query_link: err_query_current: err_query_permanent: + rndis_halt ( rndis ); err_initialise: rndis->op->close ( rndis ); err_open: