diff options
author | Michael Brown <mcb30@ipxe.org> | 2014-12-19 18:09:04 +0000 |
---|---|---|
committer | Michael Brown <mcb30@ipxe.org> | 2014-12-19 18:09:04 +0000 |
commit | 4de0e273a78f22dbc62e79906c79fc4579aeac54 (patch) | |
tree | 342f768d3eacc254251d3ab6c024be3844107dfc /src/net | |
parent | 1d0ade42dba3c30375694fb59eb2d06085271a71 (diff) | |
download | ipxe-4de0e273a78f22dbc62e79906c79fc4579aeac54.tar.gz |
[rndis] Send RNDIS_HALT_MSG
The RNDIS specification requires that we send RNDIS_HALT_MSG.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/net')
-rw-r--r-- | src/net/rndis.c | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/src/net/rndis.c b/src/net/rndis.c index 0de3d3a6..62a26ad5 100644 --- a/src/net/rndis.c +++ b/src/net/rndis.c @@ -368,6 +368,56 @@ static int rndis_initialise ( struct rndis_device *rndis ) { } /** + * 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 * * @v rndis RNDIS device @@ -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: |