Blame view
drivers/net/rionet.c
13.7 KB
f89efd523 [PATCH] Add rapid... |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
/* * rionet - Ethernet driver over RapidIO messaging services * * Copyright 2005 MontaVista Software, Inc. * Matt Porter <mporter@kernel.crashing.org> * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. */ #include <linux/module.h> #include <linux/kernel.h> #include <linux/dma-mapping.h> #include <linux/delay.h> #include <linux/rio.h> #include <linux/rio_drv.h> |
5a0e3ad6a include cleanup: ... |
19 |
#include <linux/slab.h> |
f89efd523 [PATCH] Add rapid... |
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
#include <linux/rio_ids.h> #include <linux/netdevice.h> #include <linux/etherdevice.h> #include <linux/skbuff.h> #include <linux/crc32.h> #include <linux/ethtool.h> #define DRV_NAME "rionet" #define DRV_VERSION "0.2" #define DRV_AUTHOR "Matt Porter <mporter@kernel.crashing.org>" #define DRV_DESC "Ethernet over RapidIO" MODULE_AUTHOR(DRV_AUTHOR); MODULE_DESCRIPTION(DRV_DESC); MODULE_LICENSE("GPL"); #define RIONET_DEFAULT_MSGLEVEL \ (NETIF_MSG_DRV | \ NETIF_MSG_LINK | \ NETIF_MSG_RX_ERR | \ NETIF_MSG_TX_ERR) #define RIONET_DOORBELL_JOIN 0x1000 #define RIONET_DOORBELL_LEAVE 0x1001 #define RIONET_MAILBOX 0 #define RIONET_TX_RING_SIZE CONFIG_RIONET_TX_SIZE #define RIONET_RX_RING_SIZE CONFIG_RIONET_RX_SIZE static LIST_HEAD(rionet_peers); struct rionet_private { struct rio_mport *mport; struct sk_buff *rx_skb[RIONET_RX_RING_SIZE]; struct sk_buff *tx_skb[RIONET_TX_RING_SIZE]; |
f89efd523 [PATCH] Add rapid... |
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
int rx_slot; int tx_slot; int tx_cnt; int ack_slot; spinlock_t lock; spinlock_t tx_lock; u32 msg_enable; }; struct rionet_peer { struct list_head node; struct rio_dev *rdev; struct resource *res; }; static int rionet_check = 0; static int rionet_capable = 1; /* |
411c94038 trivial: fix typo... |
76 |
* This is a fast lookup table for translating TX |
f89efd523 [PATCH] Add rapid... |
77 78 79 80 |
* Ethernet packets into a destination RIO device. It * could be made into a hash table to save memory depending * on system trade-offs. */ |
e04232360 [RAPIDIO] Auto-pr... |
81 |
static struct rio_dev **rionet_active; |
f89efd523 [PATCH] Add rapid... |
82 |
|
284fb68d0 rapidio: fix use ... |
83 84 85 |
#define is_rionet_capable(src_ops, dst_ops) \ ((src_ops & RIO_SRC_OPS_DATA_MSG) && \ (dst_ops & RIO_DST_OPS_DATA_MSG) && \ |
f89efd523 [PATCH] Add rapid... |
86 87 88 |
(src_ops & RIO_SRC_OPS_DOORBELL) && \ (dst_ops & RIO_DST_OPS_DOORBELL)) #define dev_rionet_capable(dev) \ |
284fb68d0 rapidio: fix use ... |
89 |
is_rionet_capable(dev->src_ops, dev->dst_ops) |
f89efd523 [PATCH] Add rapid... |
90 |
|
e0c87bd95 drivers/net/rione... |
91 92 |
#define RIONET_MAC_MATCH(x) (!memcmp((x), "\00\01\00\01", 4)) #define RIONET_GET_DESTID(x) ((*((u8 *)x + 4) << 8) | *((u8 *)x + 5)) |
f89efd523 [PATCH] Add rapid... |
93 |
|
f89efd523 [PATCH] Add rapid... |
94 95 96 97 |
static int rionet_rx_clean(struct net_device *ndev) { int i; int error = 0; |
4cf1653aa netdevice: safe c... |
98 |
struct rionet_private *rnet = netdev_priv(ndev); |
f89efd523 [PATCH] Add rapid... |
99 100 101 102 103 104 105 106 107 108 109 110 111 |
void *data; i = rnet->rx_slot; do { if (!rnet->rx_skb[i]) continue; if (!(data = rio_get_inb_message(rnet->mport, RIONET_MAILBOX))) break; rnet->rx_skb[i]->data = data; skb_put(rnet->rx_skb[i], RIO_MAX_MSG_SIZE); |
f89efd523 [PATCH] Add rapid... |
112 113 114 115 116 |
rnet->rx_skb[i]->protocol = eth_type_trans(rnet->rx_skb[i], ndev); error = netif_rx(rnet->rx_skb[i]); if (error == NET_RX_DROP) { |
09f75cd7b [NET] drivers/net... |
117 |
ndev->stats.rx_dropped++; |
f89efd523 [PATCH] Add rapid... |
118 |
} else { |
09f75cd7b [NET] drivers/net... |
119 120 |
ndev->stats.rx_packets++; ndev->stats.rx_bytes += RIO_MAX_MSG_SIZE; |
f89efd523 [PATCH] Add rapid... |
121 122 123 124 125 126 127 128 129 130 |
} } while ((i = (i + 1) % RIONET_RX_RING_SIZE) != rnet->rx_slot); return i; } static void rionet_rx_fill(struct net_device *ndev, int end) { int i; |
4cf1653aa netdevice: safe c... |
131 |
struct rionet_private *rnet = netdev_priv(ndev); |
f89efd523 [PATCH] Add rapid... |
132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 |
i = rnet->rx_slot; do { rnet->rx_skb[i] = dev_alloc_skb(RIO_MAX_MSG_SIZE); if (!rnet->rx_skb[i]) break; rio_add_inb_buffer(rnet->mport, RIONET_MAILBOX, rnet->rx_skb[i]->data); } while ((i = (i + 1) % RIONET_RX_RING_SIZE) != end); rnet->rx_slot = i; } static int rionet_queue_tx_msg(struct sk_buff *skb, struct net_device *ndev, struct rio_dev *rdev) { |
4cf1653aa netdevice: safe c... |
150 |
struct rionet_private *rnet = netdev_priv(ndev); |
f89efd523 [PATCH] Add rapid... |
151 152 153 |
rio_add_outb_message(rnet->mport, rdev, 0, skb->data, skb->len); rnet->tx_skb[rnet->tx_slot] = skb; |
09f75cd7b [NET] drivers/net... |
154 155 |
ndev->stats.tx_packets++; ndev->stats.tx_bytes += skb->len; |
f89efd523 [PATCH] Add rapid... |
156 157 158 159 160 161 162 163 |
if (++rnet->tx_cnt == RIONET_TX_RING_SIZE) netif_stop_queue(ndev); ++rnet->tx_slot; rnet->tx_slot &= (RIONET_TX_RING_SIZE - 1); if (netif_msg_tx_queued(rnet)) |
8df8a4753 rionet: Remove po... |
164 165 166 |
printk(KERN_INFO "%s: queued skb len %8.8x ", DRV_NAME, skb->len); |
f89efd523 [PATCH] Add rapid... |
167 168 169 170 171 172 173 |
return 0; } static int rionet_start_xmit(struct sk_buff *skb, struct net_device *ndev) { int i; |
4cf1653aa netdevice: safe c... |
174 |
struct rionet_private *rnet = netdev_priv(ndev); |
f89efd523 [PATCH] Add rapid... |
175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 |
struct ethhdr *eth = (struct ethhdr *)skb->data; u16 destid; unsigned long flags; local_irq_save(flags); if (!spin_trylock(&rnet->tx_lock)) { local_irq_restore(flags); return NETDEV_TX_LOCKED; } if ((rnet->tx_cnt + 1) > RIONET_TX_RING_SIZE) { netif_stop_queue(ndev); spin_unlock_irqrestore(&rnet->tx_lock, flags); printk(KERN_ERR "%s: BUG! Tx Ring full when queue awake! ", ndev->name); return NETDEV_TX_BUSY; } |
abfc89c7b net: rionet: Use ... |
193 |
if (is_multicast_ether_addr(eth->h_dest)) { |
e04232360 [RAPIDIO] Auto-pr... |
194 195 |
for (i = 0; i < RIO_MAX_ROUTE_ENTRIES(rnet->mport->sys_size); i++) |
f89efd523 [PATCH] Add rapid... |
196 197 198 199 200 201 202 203 204 205 |
if (rionet_active[i]) rionet_queue_tx_msg(skb, ndev, rionet_active[i]); } else if (RIONET_MAC_MATCH(eth->h_dest)) { destid = RIONET_GET_DESTID(eth->h_dest); if (rionet_active[destid]) rionet_queue_tx_msg(skb, ndev, rionet_active[destid]); } spin_unlock_irqrestore(&rnet->tx_lock, flags); |
6ed106549 net: use NETDEV_T... |
206 |
return NETDEV_TX_OK; |
f89efd523 [PATCH] Add rapid... |
207 208 209 210 211 212 |
} static void rionet_dbell_event(struct rio_mport *mport, void *dev_id, u16 sid, u16 tid, u16 info) { struct net_device *ndev = dev_id; |
4cf1653aa netdevice: safe c... |
213 |
struct rionet_private *rnet = netdev_priv(ndev); |
f89efd523 [PATCH] Add rapid... |
214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 |
struct rionet_peer *peer; if (netif_msg_intr(rnet)) printk(KERN_INFO "%s: doorbell sid %4.4x tid %4.4x info %4.4x", DRV_NAME, sid, tid, info); if (info == RIONET_DOORBELL_JOIN) { if (!rionet_active[sid]) { list_for_each_entry(peer, &rionet_peers, node) { if (peer->rdev->destid == sid) rionet_active[sid] = peer->rdev; } rio_mport_send_doorbell(mport, sid, RIONET_DOORBELL_JOIN); } } else if (info == RIONET_DOORBELL_LEAVE) { rionet_active[sid] = NULL; } else { if (netif_msg_intr(rnet)) printk(KERN_WARNING "%s: unhandled doorbell ", DRV_NAME); } } static void rionet_inb_msg_event(struct rio_mport *mport, void *dev_id, int mbox, int slot) { int n; struct net_device *ndev = dev_id; |
4cf1653aa netdevice: safe c... |
242 |
struct rionet_private *rnet = netdev_priv(ndev); |
f89efd523 [PATCH] Add rapid... |
243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 |
if (netif_msg_intr(rnet)) printk(KERN_INFO "%s: inbound message event, mbox %d slot %d ", DRV_NAME, mbox, slot); spin_lock(&rnet->lock); if ((n = rionet_rx_clean(ndev)) != rnet->rx_slot) rionet_rx_fill(ndev, n); spin_unlock(&rnet->lock); } static void rionet_outb_msg_event(struct rio_mport *mport, void *dev_id, int mbox, int slot) { struct net_device *ndev = dev_id; |
4cf1653aa netdevice: safe c... |
258 |
struct rionet_private *rnet = netdev_priv(ndev); |
f89efd523 [PATCH] Add rapid... |
259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 |
spin_lock(&rnet->lock); if (netif_msg_intr(rnet)) printk(KERN_INFO "%s: outbound message event, mbox %d slot %d ", DRV_NAME, mbox, slot); while (rnet->tx_cnt && (rnet->ack_slot != slot)) { /* dma unmap single */ dev_kfree_skb_irq(rnet->tx_skb[rnet->ack_slot]); rnet->tx_skb[rnet->ack_slot] = NULL; ++rnet->ack_slot; rnet->ack_slot &= (RIONET_TX_RING_SIZE - 1); rnet->tx_cnt--; } if (rnet->tx_cnt < RIONET_TX_RING_SIZE) netif_wake_queue(ndev); spin_unlock(&rnet->lock); } static int rionet_open(struct net_device *ndev) { int i, rc = 0; struct rionet_peer *peer, *tmp; |
4cf1653aa netdevice: safe c... |
287 |
struct rionet_private *rnet = netdev_priv(ndev); |
f89efd523 [PATCH] Add rapid... |
288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 |
if (netif_msg_ifup(rnet)) printk(KERN_INFO "%s: open ", DRV_NAME); if ((rc = rio_request_inb_dbell(rnet->mport, (void *)ndev, RIONET_DOORBELL_JOIN, RIONET_DOORBELL_LEAVE, rionet_dbell_event)) < 0) goto out; if ((rc = rio_request_inb_mbox(rnet->mport, (void *)ndev, RIONET_MAILBOX, RIONET_RX_RING_SIZE, rionet_inb_msg_event)) < 0) goto out; if ((rc = rio_request_outb_mbox(rnet->mport, (void *)ndev, RIONET_MAILBOX, RIONET_TX_RING_SIZE, rionet_outb_msg_event)) < 0) goto out; /* Initialize inbound message ring */ for (i = 0; i < RIONET_RX_RING_SIZE; i++) rnet->rx_skb[i] = NULL; rnet->rx_slot = 0; rionet_rx_fill(ndev, 0); rnet->tx_slot = 0; rnet->tx_cnt = 0; rnet->ack_slot = 0; netif_carrier_on(ndev); netif_start_queue(ndev); list_for_each_entry_safe(peer, tmp, &rionet_peers, node) { if (!(peer->res = rio_request_outb_dbell(peer->rdev, RIONET_DOORBELL_JOIN, RIONET_DOORBELL_LEAVE))) { printk(KERN_ERR "%s: error requesting doorbells ", DRV_NAME); continue; } |
284fb68d0 rapidio: fix use ... |
337 338 |
/* Send a join message */ rio_send_doorbell(peer->rdev, RIONET_DOORBELL_JOIN); |
f89efd523 [PATCH] Add rapid... |
339 340 341 342 343 344 345 346 |
} out: return rc; } static int rionet_close(struct net_device *ndev) { |
4cf1653aa netdevice: safe c... |
347 |
struct rionet_private *rnet = netdev_priv(ndev); |
f89efd523 [PATCH] Add rapid... |
348 349 350 351 352 353 354 355 356 357 358 |
struct rionet_peer *peer, *tmp; int i; if (netif_msg_ifup(rnet)) printk(KERN_INFO "%s: close ", DRV_NAME); netif_stop_queue(ndev); netif_carrier_off(ndev); for (i = 0; i < RIONET_RX_RING_SIZE; i++) |
aaff1e190 drivers/net/rione... |
359 |
kfree_skb(rnet->rx_skb[i]); |
f89efd523 [PATCH] Add rapid... |
360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 |
list_for_each_entry_safe(peer, tmp, &rionet_peers, node) { if (rionet_active[peer->rdev->destid]) { rio_send_doorbell(peer->rdev, RIONET_DOORBELL_LEAVE); rionet_active[peer->rdev->destid] = NULL; } rio_release_outb_dbell(peer->rdev, peer->res); } rio_release_inb_dbell(rnet->mport, RIONET_DOORBELL_JOIN, RIONET_DOORBELL_LEAVE); rio_release_inb_mbox(rnet->mport, RIONET_MAILBOX); rio_release_outb_mbox(rnet->mport, RIONET_MAILBOX); return 0; } static void rionet_remove(struct rio_dev *rdev) { |
55caa9241 rionet: fix NULL ... |
379 |
struct net_device *ndev = rio_get_drvdata(rdev); |
f89efd523 [PATCH] Add rapid... |
380 |
struct rionet_peer *peer, *tmp; |
e04232360 [RAPIDIO] Auto-pr... |
381 |
free_pages((unsigned long)rionet_active, rdev->net->hport->sys_size ? |
388b78adc rapidio: modify c... |
382 |
__fls(sizeof(void *)) + 4 : 0); |
f89efd523 [PATCH] Add rapid... |
383 |
unregister_netdev(ndev); |
22138d307 rionet: use free_... |
384 |
free_netdev(ndev); |
f89efd523 [PATCH] Add rapid... |
385 386 387 388 389 390 391 392 393 394 |
list_for_each_entry_safe(peer, tmp, &rionet_peers, node) { list_del(&peer->node); kfree(peer); } } static void rionet_get_drvinfo(struct net_device *ndev, struct ethtool_drvinfo *info) { |
4cf1653aa netdevice: safe c... |
395 |
struct rionet_private *rnet = netdev_priv(ndev); |
f89efd523 [PATCH] Add rapid... |
396 397 398 399 400 401 402 403 404 |
strcpy(info->driver, DRV_NAME); strcpy(info->version, DRV_VERSION); strcpy(info->fw_version, "n/a"); strcpy(info->bus_info, rnet->mport->name); } static u32 rionet_get_msglevel(struct net_device *ndev) { |
4cf1653aa netdevice: safe c... |
405 |
struct rionet_private *rnet = netdev_priv(ndev); |
f89efd523 [PATCH] Add rapid... |
406 407 408 409 410 411 |
return rnet->msg_enable; } static void rionet_set_msglevel(struct net_device *ndev, u32 value) { |
4cf1653aa netdevice: safe c... |
412 |
struct rionet_private *rnet = netdev_priv(ndev); |
f89efd523 [PATCH] Add rapid... |
413 414 415 |
rnet->msg_enable = value; } |
7282d491e drivers/net: cons... |
416 |
static const struct ethtool_ops rionet_ethtool_ops = { |
f89efd523 [PATCH] Add rapid... |
417 418 419 420 421 |
.get_drvinfo = rionet_get_drvinfo, .get_msglevel = rionet_get_msglevel, .set_msglevel = rionet_set_msglevel, .get_link = ethtool_op_get_link, }; |
a33a2bb3c rionet: convert t... |
422 423 424 425 426 427 428 429 |
static const struct net_device_ops rionet_netdev_ops = { .ndo_open = rionet_open, .ndo_stop = rionet_close, .ndo_start_xmit = rionet_start_xmit, .ndo_change_mtu = eth_change_mtu, .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = eth_mac_addr, }; |
55caa9241 rionet: fix NULL ... |
430 |
static int rionet_setup_netdev(struct rio_mport *mport, struct net_device *ndev) |
f89efd523 [PATCH] Add rapid... |
431 432 |
{ int rc = 0; |
f89efd523 [PATCH] Add rapid... |
433 434 |
struct rionet_private *rnet; u16 device_id; |
e04232360 [RAPIDIO] Auto-pr... |
435 |
rionet_active = (struct rio_dev **)__get_free_pages(GFP_KERNEL, |
388b78adc rapidio: modify c... |
436 |
mport->sys_size ? __fls(sizeof(void *)) + 4 : 0); |
e04232360 [RAPIDIO] Auto-pr... |
437 438 439 440 441 442 |
if (!rionet_active) { rc = -ENOMEM; goto out; } memset((void *)rionet_active, 0, sizeof(void *) * RIO_MAX_ROUTE_ENTRIES(mport->sys_size)); |
f89efd523 [PATCH] Add rapid... |
443 |
/* Set up private area */ |
4cf1653aa netdevice: safe c... |
444 |
rnet = netdev_priv(ndev); |
f89efd523 [PATCH] Add rapid... |
445 446 447 448 449 450 451 452 453 454 |
rnet->mport = mport; /* Set the default MAC address */ device_id = rio_local_get_device_id(mport); ndev->dev_addr[0] = 0x00; ndev->dev_addr[1] = 0x01; ndev->dev_addr[2] = 0x00; ndev->dev_addr[3] = 0x01; ndev->dev_addr[4] = device_id >> 8; ndev->dev_addr[5] = device_id & 0xff; |
a33a2bb3c rionet: convert t... |
455 |
ndev->netdev_ops = &rionet_netdev_ops; |
f89efd523 [PATCH] Add rapid... |
456 457 458 |
ndev->mtu = RIO_MAX_MSG_SIZE - 14; ndev->features = NETIF_F_LLTX; SET_ETHTOOL_OPS(ndev, &rionet_ethtool_ops); |
f89efd523 [PATCH] Add rapid... |
459 460 461 462 463 464 465 466 |
spin_lock_init(&rnet->lock); spin_lock_init(&rnet->tx_lock); rnet->msg_enable = RIONET_DEFAULT_MSGLEVEL; rc = register_netdev(ndev); if (rc != 0) goto out; |
e174961ca net: convert prin... |
467 468 |
printk("%s: %s %s Version %s, MAC %pM ", |
f89efd523 [PATCH] Add rapid... |
469 470 471 472 |
ndev->name, DRV_NAME, DRV_DESC, DRV_VERSION, |
e174961ca net: convert prin... |
473 |
ndev->dev_addr); |
f89efd523 [PATCH] Add rapid... |
474 475 476 477 478 479 480 481 482 483 484 |
out: return rc; } /* * XXX Make multi-net safe */ static int rionet_probe(struct rio_dev *rdev, const struct rio_device_id *id) { int rc = -ENODEV; |
284fb68d0 rapidio: fix use ... |
485 |
u32 lsrc_ops, ldst_ops; |
f89efd523 [PATCH] Add rapid... |
486 |
struct rionet_peer *peer; |
55caa9241 rionet: fix NULL ... |
487 |
struct net_device *ndev = NULL; |
f89efd523 [PATCH] Add rapid... |
488 489 490 491 |
/* If local device is not rionet capable, give up quickly */ if (!rionet_capable) goto out; |
55caa9241 rionet: fix NULL ... |
492 493 494 495 496 497 498 499 500 |
/* Allocate our net_device structure */ ndev = alloc_etherdev(sizeof(struct rionet_private)); if (ndev == NULL) { printk(KERN_INFO "%s: could not allocate ethernet device. ", DRV_NAME); rc = -ENOMEM; goto out; } |
f89efd523 [PATCH] Add rapid... |
501 502 503 504 505 506 |
/* * First time through, make sure local device is rionet * capable, setup netdev, and set flags so this is skipped * on later probes */ if (!rionet_check) { |
f89efd523 [PATCH] Add rapid... |
507 508 509 510 |
rio_local_read_config_32(rdev->net->hport, RIO_SRC_OPS_CAR, &lsrc_ops); rio_local_read_config_32(rdev->net->hport, RIO_DST_OPS_CAR, &ldst_ops); |
284fb68d0 rapidio: fix use ... |
511 |
if (!is_rionet_capable(lsrc_ops, ldst_ops)) { |
f89efd523 [PATCH] Add rapid... |
512 513 514 515 516 517 518 519 |
printk(KERN_ERR "%s: local device is not network capable ", DRV_NAME); rionet_check = 1; rionet_capable = 0; goto out; } |
55caa9241 rionet: fix NULL ... |
520 |
rc = rionet_setup_netdev(rdev->net->hport, ndev); |
f89efd523 [PATCH] Add rapid... |
521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 |
rionet_check = 1; } /* * If the remote device has mailbox/doorbell capabilities, * add it to the peer list. */ if (dev_rionet_capable(rdev)) { if (!(peer = kmalloc(sizeof(struct rionet_peer), GFP_KERNEL))) { rc = -ENOMEM; goto out; } peer->rdev = rdev; list_add_tail(&peer->node, &rionet_peers); } |
55caa9241 rionet: fix NULL ... |
536 |
rio_set_drvdata(rdev, ndev); |
f89efd523 [PATCH] Add rapid... |
537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 |
out: return rc; } static struct rio_device_id rionet_id_table[] = { {RIO_DEVICE(RIO_ANY_ID, RIO_ANY_ID)} }; static struct rio_driver rionet_driver = { .name = "rionet", .id_table = rionet_id_table, .probe = rionet_probe, .remove = rionet_remove, }; static int __init rionet_init(void) { return rio_register_driver(&rionet_driver); } static void __exit rionet_exit(void) { rio_unregister_driver(&rionet_driver); } |
2f809985d rapidio: modify s... |
561 |
late_initcall(rionet_init); |
f89efd523 [PATCH] Add rapid... |
562 |
module_exit(rionet_exit); |