Loading drivers/scsi/cxgbi/libcxgbi.c +218 −19 Original line number Diff line number Diff line Loading @@ -24,6 +24,10 @@ #include <linux/inet.h> #include <net/dst.h> #include <net/route.h> #include <net/ipv6.h> #include <net/ip6_route.h> #include <net/addrconf.h> #include <linux/inetdevice.h> /* ip_dev_find */ #include <linux/module.h> #include <net/tcp.h> Loading Loading @@ -193,7 +197,7 @@ struct cxgbi_device *cxgbi_device_find_by_lldev(void *lldev) } EXPORT_SYMBOL_GPL(cxgbi_device_find_by_lldev); static struct cxgbi_device *cxgbi_device_find_by_netdev(struct net_device *ndev, struct cxgbi_device *cxgbi_device_find_by_netdev(struct net_device *ndev, int *port) { struct net_device *vdev = NULL; Loading Loading @@ -224,6 +228,40 @@ static struct cxgbi_device *cxgbi_device_find_by_netdev(struct net_device *ndev, "ndev 0x%p, %s, NO match found.\n", ndev, ndev->name); return NULL; } EXPORT_SYMBOL_GPL(cxgbi_device_find_by_netdev); static struct cxgbi_device *cxgbi_device_find_by_mac(struct net_device *ndev, int *port) { struct net_device *vdev = NULL; struct cxgbi_device *cdev, *tmp; int i; if (ndev->priv_flags & IFF_802_1Q_VLAN) { vdev = ndev; ndev = vlan_dev_real_dev(ndev); pr_info("vlan dev %s -> %s.\n", vdev->name, ndev->name); } mutex_lock(&cdev_mutex); list_for_each_entry_safe(cdev, tmp, &cdev_list, list_head) { for (i = 0; i < cdev->nports; i++) { if (!memcmp(ndev->dev_addr, cdev->ports[i]->dev_addr, MAX_ADDR_LEN)) { cdev->hbas[i]->vdev = vdev; mutex_unlock(&cdev_mutex); if (port) *port = i; return cdev; } } } mutex_unlock(&cdev_mutex); log_debug(1 << CXGBI_DBG_DEV, "ndev 0x%p, %s, NO match mac found.\n", ndev, ndev->name); return NULL; } void cxgbi_hbas_remove(struct cxgbi_device *cdev) { Loading Loading @@ -320,6 +358,7 @@ static int sock_get_port(struct cxgbi_sock *csk) struct cxgbi_ports_map *pmap = &cdev->pmap; unsigned int start; int idx; __be16 *port; if (!pmap->max_connect) { pr_err("cdev 0x%p, p#%u %s, NO port map.\n", Loading @@ -327,9 +366,14 @@ static int sock_get_port(struct cxgbi_sock *csk) return -EADDRNOTAVAIL; } if (csk->saddr.sin_port) { if (csk->csk_family == AF_INET) port = &csk->saddr.sin_port; else /* ipv6 */ port = &csk->saddr6.sin6_port; if (*port) { pr_err("source port NON-ZERO %u.\n", ntohs(csk->saddr.sin_port)); ntohs(*port)); return -EADDRINUSE; } Loading @@ -347,8 +391,7 @@ static int sock_get_port(struct cxgbi_sock *csk) idx = 0; if (!pmap->port_csk[idx]) { pmap->used++; csk->saddr.sin_port = htons(pmap->sport_base + idx); *port = htons(pmap->sport_base + idx); pmap->next = idx; pmap->port_csk[idx] = csk; spin_unlock_bh(&pmap->lock); Loading @@ -374,16 +417,22 @@ static void sock_put_port(struct cxgbi_sock *csk) { struct cxgbi_device *cdev = csk->cdev; struct cxgbi_ports_map *pmap = &cdev->pmap; __be16 *port; if (csk->saddr.sin_port) { int idx = ntohs(csk->saddr.sin_port) - pmap->sport_base; if (csk->csk_family == AF_INET) port = &csk->saddr.sin_port; else /* ipv6 */ port = &csk->saddr6.sin6_port; csk->saddr.sin_port = 0; if (*port) { int idx = ntohs(*port) - pmap->sport_base; *port = 0; if (idx < 0 || idx >= pmap->max_connect) { pr_err("cdev 0x%p, p#%u %s, port %u OOR.\n", cdev, csk->port_id, cdev->ports[csk->port_id]->name, ntohs(csk->saddr.sin_port)); ntohs(*port)); return; } Loading Loading @@ -479,17 +528,11 @@ static struct cxgbi_sock *cxgbi_check_route(struct sockaddr *dst_addr) int port = 0xFFFF; int err = 0; if (daddr->sin_family != AF_INET) { pr_info("address family 0x%x NOT supported.\n", daddr->sin_family); err = -EAFNOSUPPORT; goto err_out; } rt = find_route_ipv4(&fl4, 0, daddr->sin_addr.s_addr, 0, daddr->sin_port, 0); if (!rt) { pr_info("no route to ipv4 0x%x, port %u.\n", daddr->sin_addr.s_addr, daddr->sin_port); be32_to_cpu(daddr->sin_addr.s_addr), be16_to_cpu(daddr->sin_port)); err = -ENETUNREACH; goto err_out; } Loading Loading @@ -537,9 +580,12 @@ static struct cxgbi_sock *cxgbi_check_route(struct sockaddr *dst_addr) csk->port_id = port; csk->mtu = mtu; csk->dst = dst; csk->csk_family = AF_INET; csk->daddr.sin_addr.s_addr = daddr->sin_addr.s_addr; csk->daddr.sin_port = daddr->sin_port; csk->daddr.sin_family = daddr->sin_family; csk->saddr.sin_family = daddr->sin_family; csk->saddr.sin_addr.s_addr = fl4.saddr; neigh_release(n); Loading @@ -556,6 +602,121 @@ static struct cxgbi_sock *cxgbi_check_route(struct sockaddr *dst_addr) return ERR_PTR(err); } static struct rt6_info *find_route_ipv6(const struct in6_addr *saddr, const struct in6_addr *daddr) { struct flowi6 fl; if (saddr) memcpy(&fl.saddr, saddr, sizeof(struct in6_addr)); if (daddr) memcpy(&fl.daddr, daddr, sizeof(struct in6_addr)); return (struct rt6_info *)ip6_route_output(&init_net, NULL, &fl); } static struct cxgbi_sock *cxgbi_check_route6(struct sockaddr *dst_addr) { struct sockaddr_in6 *daddr6 = (struct sockaddr_in6 *)dst_addr; struct dst_entry *dst; struct net_device *ndev; struct cxgbi_device *cdev; struct rt6_info *rt = NULL; struct neighbour *n; struct in6_addr pref_saddr; struct cxgbi_sock *csk = NULL; unsigned int mtu = 0; int port = 0xFFFF; int err = 0; rt = find_route_ipv6(NULL, &daddr6->sin6_addr); if (!rt) { pr_info("no route to ipv6 %pI6 port %u\n", daddr6->sin6_addr.s6_addr, be16_to_cpu(daddr6->sin6_port)); err = -ENETUNREACH; goto err_out; } dst = &rt->dst; n = dst_neigh_lookup(dst, &daddr6->sin6_addr); if (!n) { pr_info("%pI6, port %u, dst no neighbour.\n", daddr6->sin6_addr.s6_addr, be16_to_cpu(daddr6->sin6_port)); err = -ENETUNREACH; goto rel_rt; } ndev = n->dev; if (ipv6_addr_is_multicast(&rt->rt6i_dst.addr)) { pr_info("multi-cast route %pI6 port %u, dev %s.\n", daddr6->sin6_addr.s6_addr, ntohs(daddr6->sin6_port), ndev->name); err = -ENETUNREACH; goto rel_rt; } cdev = cxgbi_device_find_by_netdev(ndev, &port); if (!cdev) cdev = cxgbi_device_find_by_mac(ndev, &port); if (!cdev) { pr_info("dst %pI6 %s, NOT cxgbi device.\n", daddr6->sin6_addr.s6_addr, ndev->name); err = -ENETUNREACH; goto rel_rt; } log_debug(1 << CXGBI_DBG_SOCK, "route to %pI6 :%u, ndev p#%d,%s, cdev 0x%p.\n", daddr6->sin6_addr.s6_addr, ntohs(daddr6->sin6_port), port, ndev->name, cdev); csk = cxgbi_sock_create(cdev); if (!csk) { err = -ENOMEM; goto rel_rt; } csk->cdev = cdev; csk->port_id = port; csk->mtu = mtu; csk->dst = dst; if (ipv6_addr_any(&rt->rt6i_prefsrc.addr)) { struct inet6_dev *idev = ip6_dst_idev((struct dst_entry *)rt); err = ipv6_dev_get_saddr(&init_net, idev ? idev->dev : NULL, &daddr6->sin6_addr, 0, &pref_saddr); if (err) { pr_info("failed to get source address to reach %pI6\n", &daddr6->sin6_addr); goto rel_rt; } } else { pref_saddr = rt->rt6i_prefsrc.addr; } csk->csk_family = AF_INET6; csk->daddr6.sin6_addr = daddr6->sin6_addr; csk->daddr6.sin6_port = daddr6->sin6_port; csk->daddr6.sin6_family = daddr6->sin6_family; csk->saddr6.sin6_addr = pref_saddr; neigh_release(n); return csk; rel_rt: if (n) neigh_release(n); ip6_rt_put(rt); if (csk) cxgbi_sock_closed(csk); err_out: return ERR_PTR(err); } void cxgbi_sock_established(struct cxgbi_sock *csk, unsigned int snd_isn, unsigned int opt) { Loading Loading @@ -2194,6 +2355,34 @@ int cxgbi_set_conn_param(struct iscsi_cls_conn *cls_conn, } EXPORT_SYMBOL_GPL(cxgbi_set_conn_param); static inline int csk_print_port(struct cxgbi_sock *csk, char *buf) { int len; cxgbi_sock_get(csk); len = sprintf(buf, "%hu\n", ntohs(csk->daddr.sin_port)); cxgbi_sock_put(csk); return len; } static inline int csk_print_ip(struct cxgbi_sock *csk, char *buf) { int len; cxgbi_sock_get(csk); if (csk->csk_family == AF_INET) len = sprintf(buf, "%pI4", &csk->daddr.sin_addr.s_addr); else len = sprintf(buf, "%pI6", &csk->daddr6.sin6_addr); cxgbi_sock_put(csk); return len; } int cxgbi_get_ep_param(struct iscsi_endpoint *ep, enum iscsi_param param, char *buf) { Loading Loading @@ -2447,7 +2636,17 @@ struct iscsi_endpoint *cxgbi_ep_connect(struct Scsi_Host *shost, } } if (dst_addr->sa_family == AF_INET) { csk = cxgbi_check_route(dst_addr); } else if (dst_addr->sa_family == AF_INET6) { csk = cxgbi_check_route6(dst_addr); } else { pr_info("address family 0x%x NOT supported.\n", dst_addr->sa_family); err = -EAFNOSUPPORT; return (struct iscsi_endpoint *)ERR_PTR(err); } if (IS_ERR(csk)) return (struct iscsi_endpoint *)csk; cxgbi_sock_get(csk); Loading drivers/scsi/cxgbi/libcxgbi.h +19 −2 Original line number Diff line number Diff line Loading @@ -44,6 +44,15 @@ enum cxgbi_dbg_flag { pr_info(fmt, ##__VA_ARGS__); \ } while (0) #define pr_info_ipaddr(fmt_trail, \ addr1, addr2, args_trail...) \ do { \ if (!((1 << CXGBI_DBG_SOCK) & dbg_level)) \ break; \ pr_info("%pISpc - %pISpc, " fmt_trail, \ addr1, addr2, args_trail); \ } while (0) /* max. connections per adapter */ #define CXGBI_MAX_CONN 16384 Loading Loading @@ -202,8 +211,15 @@ struct cxgbi_sock { spinlock_t lock; struct kref refcnt; unsigned int state; unsigned int csk_family; union { struct sockaddr_in saddr; struct sockaddr_in6 saddr6; }; union { struct sockaddr_in daddr; struct sockaddr_in6 daddr6; }; struct dst_entry *dst; struct sk_buff_head receive_queue; struct sk_buff_head write_queue; Loading Loading @@ -692,6 +708,7 @@ struct cxgbi_device *cxgbi_device_register(unsigned int, unsigned int); void cxgbi_device_unregister(struct cxgbi_device *); void cxgbi_device_unregister_all(unsigned int flag); struct cxgbi_device *cxgbi_device_find_by_lldev(void *); struct cxgbi_device *cxgbi_device_find_by_netdev(struct net_device *, int *); int cxgbi_hbas_add(struct cxgbi_device *, unsigned int, unsigned int, struct scsi_host_template *, struct scsi_transport_template *); Loading Loading
drivers/scsi/cxgbi/libcxgbi.c +218 −19 Original line number Diff line number Diff line Loading @@ -24,6 +24,10 @@ #include <linux/inet.h> #include <net/dst.h> #include <net/route.h> #include <net/ipv6.h> #include <net/ip6_route.h> #include <net/addrconf.h> #include <linux/inetdevice.h> /* ip_dev_find */ #include <linux/module.h> #include <net/tcp.h> Loading Loading @@ -193,7 +197,7 @@ struct cxgbi_device *cxgbi_device_find_by_lldev(void *lldev) } EXPORT_SYMBOL_GPL(cxgbi_device_find_by_lldev); static struct cxgbi_device *cxgbi_device_find_by_netdev(struct net_device *ndev, struct cxgbi_device *cxgbi_device_find_by_netdev(struct net_device *ndev, int *port) { struct net_device *vdev = NULL; Loading Loading @@ -224,6 +228,40 @@ static struct cxgbi_device *cxgbi_device_find_by_netdev(struct net_device *ndev, "ndev 0x%p, %s, NO match found.\n", ndev, ndev->name); return NULL; } EXPORT_SYMBOL_GPL(cxgbi_device_find_by_netdev); static struct cxgbi_device *cxgbi_device_find_by_mac(struct net_device *ndev, int *port) { struct net_device *vdev = NULL; struct cxgbi_device *cdev, *tmp; int i; if (ndev->priv_flags & IFF_802_1Q_VLAN) { vdev = ndev; ndev = vlan_dev_real_dev(ndev); pr_info("vlan dev %s -> %s.\n", vdev->name, ndev->name); } mutex_lock(&cdev_mutex); list_for_each_entry_safe(cdev, tmp, &cdev_list, list_head) { for (i = 0; i < cdev->nports; i++) { if (!memcmp(ndev->dev_addr, cdev->ports[i]->dev_addr, MAX_ADDR_LEN)) { cdev->hbas[i]->vdev = vdev; mutex_unlock(&cdev_mutex); if (port) *port = i; return cdev; } } } mutex_unlock(&cdev_mutex); log_debug(1 << CXGBI_DBG_DEV, "ndev 0x%p, %s, NO match mac found.\n", ndev, ndev->name); return NULL; } void cxgbi_hbas_remove(struct cxgbi_device *cdev) { Loading Loading @@ -320,6 +358,7 @@ static int sock_get_port(struct cxgbi_sock *csk) struct cxgbi_ports_map *pmap = &cdev->pmap; unsigned int start; int idx; __be16 *port; if (!pmap->max_connect) { pr_err("cdev 0x%p, p#%u %s, NO port map.\n", Loading @@ -327,9 +366,14 @@ static int sock_get_port(struct cxgbi_sock *csk) return -EADDRNOTAVAIL; } if (csk->saddr.sin_port) { if (csk->csk_family == AF_INET) port = &csk->saddr.sin_port; else /* ipv6 */ port = &csk->saddr6.sin6_port; if (*port) { pr_err("source port NON-ZERO %u.\n", ntohs(csk->saddr.sin_port)); ntohs(*port)); return -EADDRINUSE; } Loading @@ -347,8 +391,7 @@ static int sock_get_port(struct cxgbi_sock *csk) idx = 0; if (!pmap->port_csk[idx]) { pmap->used++; csk->saddr.sin_port = htons(pmap->sport_base + idx); *port = htons(pmap->sport_base + idx); pmap->next = idx; pmap->port_csk[idx] = csk; spin_unlock_bh(&pmap->lock); Loading @@ -374,16 +417,22 @@ static void sock_put_port(struct cxgbi_sock *csk) { struct cxgbi_device *cdev = csk->cdev; struct cxgbi_ports_map *pmap = &cdev->pmap; __be16 *port; if (csk->saddr.sin_port) { int idx = ntohs(csk->saddr.sin_port) - pmap->sport_base; if (csk->csk_family == AF_INET) port = &csk->saddr.sin_port; else /* ipv6 */ port = &csk->saddr6.sin6_port; csk->saddr.sin_port = 0; if (*port) { int idx = ntohs(*port) - pmap->sport_base; *port = 0; if (idx < 0 || idx >= pmap->max_connect) { pr_err("cdev 0x%p, p#%u %s, port %u OOR.\n", cdev, csk->port_id, cdev->ports[csk->port_id]->name, ntohs(csk->saddr.sin_port)); ntohs(*port)); return; } Loading Loading @@ -479,17 +528,11 @@ static struct cxgbi_sock *cxgbi_check_route(struct sockaddr *dst_addr) int port = 0xFFFF; int err = 0; if (daddr->sin_family != AF_INET) { pr_info("address family 0x%x NOT supported.\n", daddr->sin_family); err = -EAFNOSUPPORT; goto err_out; } rt = find_route_ipv4(&fl4, 0, daddr->sin_addr.s_addr, 0, daddr->sin_port, 0); if (!rt) { pr_info("no route to ipv4 0x%x, port %u.\n", daddr->sin_addr.s_addr, daddr->sin_port); be32_to_cpu(daddr->sin_addr.s_addr), be16_to_cpu(daddr->sin_port)); err = -ENETUNREACH; goto err_out; } Loading Loading @@ -537,9 +580,12 @@ static struct cxgbi_sock *cxgbi_check_route(struct sockaddr *dst_addr) csk->port_id = port; csk->mtu = mtu; csk->dst = dst; csk->csk_family = AF_INET; csk->daddr.sin_addr.s_addr = daddr->sin_addr.s_addr; csk->daddr.sin_port = daddr->sin_port; csk->daddr.sin_family = daddr->sin_family; csk->saddr.sin_family = daddr->sin_family; csk->saddr.sin_addr.s_addr = fl4.saddr; neigh_release(n); Loading @@ -556,6 +602,121 @@ static struct cxgbi_sock *cxgbi_check_route(struct sockaddr *dst_addr) return ERR_PTR(err); } static struct rt6_info *find_route_ipv6(const struct in6_addr *saddr, const struct in6_addr *daddr) { struct flowi6 fl; if (saddr) memcpy(&fl.saddr, saddr, sizeof(struct in6_addr)); if (daddr) memcpy(&fl.daddr, daddr, sizeof(struct in6_addr)); return (struct rt6_info *)ip6_route_output(&init_net, NULL, &fl); } static struct cxgbi_sock *cxgbi_check_route6(struct sockaddr *dst_addr) { struct sockaddr_in6 *daddr6 = (struct sockaddr_in6 *)dst_addr; struct dst_entry *dst; struct net_device *ndev; struct cxgbi_device *cdev; struct rt6_info *rt = NULL; struct neighbour *n; struct in6_addr pref_saddr; struct cxgbi_sock *csk = NULL; unsigned int mtu = 0; int port = 0xFFFF; int err = 0; rt = find_route_ipv6(NULL, &daddr6->sin6_addr); if (!rt) { pr_info("no route to ipv6 %pI6 port %u\n", daddr6->sin6_addr.s6_addr, be16_to_cpu(daddr6->sin6_port)); err = -ENETUNREACH; goto err_out; } dst = &rt->dst; n = dst_neigh_lookup(dst, &daddr6->sin6_addr); if (!n) { pr_info("%pI6, port %u, dst no neighbour.\n", daddr6->sin6_addr.s6_addr, be16_to_cpu(daddr6->sin6_port)); err = -ENETUNREACH; goto rel_rt; } ndev = n->dev; if (ipv6_addr_is_multicast(&rt->rt6i_dst.addr)) { pr_info("multi-cast route %pI6 port %u, dev %s.\n", daddr6->sin6_addr.s6_addr, ntohs(daddr6->sin6_port), ndev->name); err = -ENETUNREACH; goto rel_rt; } cdev = cxgbi_device_find_by_netdev(ndev, &port); if (!cdev) cdev = cxgbi_device_find_by_mac(ndev, &port); if (!cdev) { pr_info("dst %pI6 %s, NOT cxgbi device.\n", daddr6->sin6_addr.s6_addr, ndev->name); err = -ENETUNREACH; goto rel_rt; } log_debug(1 << CXGBI_DBG_SOCK, "route to %pI6 :%u, ndev p#%d,%s, cdev 0x%p.\n", daddr6->sin6_addr.s6_addr, ntohs(daddr6->sin6_port), port, ndev->name, cdev); csk = cxgbi_sock_create(cdev); if (!csk) { err = -ENOMEM; goto rel_rt; } csk->cdev = cdev; csk->port_id = port; csk->mtu = mtu; csk->dst = dst; if (ipv6_addr_any(&rt->rt6i_prefsrc.addr)) { struct inet6_dev *idev = ip6_dst_idev((struct dst_entry *)rt); err = ipv6_dev_get_saddr(&init_net, idev ? idev->dev : NULL, &daddr6->sin6_addr, 0, &pref_saddr); if (err) { pr_info("failed to get source address to reach %pI6\n", &daddr6->sin6_addr); goto rel_rt; } } else { pref_saddr = rt->rt6i_prefsrc.addr; } csk->csk_family = AF_INET6; csk->daddr6.sin6_addr = daddr6->sin6_addr; csk->daddr6.sin6_port = daddr6->sin6_port; csk->daddr6.sin6_family = daddr6->sin6_family; csk->saddr6.sin6_addr = pref_saddr; neigh_release(n); return csk; rel_rt: if (n) neigh_release(n); ip6_rt_put(rt); if (csk) cxgbi_sock_closed(csk); err_out: return ERR_PTR(err); } void cxgbi_sock_established(struct cxgbi_sock *csk, unsigned int snd_isn, unsigned int opt) { Loading Loading @@ -2194,6 +2355,34 @@ int cxgbi_set_conn_param(struct iscsi_cls_conn *cls_conn, } EXPORT_SYMBOL_GPL(cxgbi_set_conn_param); static inline int csk_print_port(struct cxgbi_sock *csk, char *buf) { int len; cxgbi_sock_get(csk); len = sprintf(buf, "%hu\n", ntohs(csk->daddr.sin_port)); cxgbi_sock_put(csk); return len; } static inline int csk_print_ip(struct cxgbi_sock *csk, char *buf) { int len; cxgbi_sock_get(csk); if (csk->csk_family == AF_INET) len = sprintf(buf, "%pI4", &csk->daddr.sin_addr.s_addr); else len = sprintf(buf, "%pI6", &csk->daddr6.sin6_addr); cxgbi_sock_put(csk); return len; } int cxgbi_get_ep_param(struct iscsi_endpoint *ep, enum iscsi_param param, char *buf) { Loading Loading @@ -2447,7 +2636,17 @@ struct iscsi_endpoint *cxgbi_ep_connect(struct Scsi_Host *shost, } } if (dst_addr->sa_family == AF_INET) { csk = cxgbi_check_route(dst_addr); } else if (dst_addr->sa_family == AF_INET6) { csk = cxgbi_check_route6(dst_addr); } else { pr_info("address family 0x%x NOT supported.\n", dst_addr->sa_family); err = -EAFNOSUPPORT; return (struct iscsi_endpoint *)ERR_PTR(err); } if (IS_ERR(csk)) return (struct iscsi_endpoint *)csk; cxgbi_sock_get(csk); Loading
drivers/scsi/cxgbi/libcxgbi.h +19 −2 Original line number Diff line number Diff line Loading @@ -44,6 +44,15 @@ enum cxgbi_dbg_flag { pr_info(fmt, ##__VA_ARGS__); \ } while (0) #define pr_info_ipaddr(fmt_trail, \ addr1, addr2, args_trail...) \ do { \ if (!((1 << CXGBI_DBG_SOCK) & dbg_level)) \ break; \ pr_info("%pISpc - %pISpc, " fmt_trail, \ addr1, addr2, args_trail); \ } while (0) /* max. connections per adapter */ #define CXGBI_MAX_CONN 16384 Loading Loading @@ -202,8 +211,15 @@ struct cxgbi_sock { spinlock_t lock; struct kref refcnt; unsigned int state; unsigned int csk_family; union { struct sockaddr_in saddr; struct sockaddr_in6 saddr6; }; union { struct sockaddr_in daddr; struct sockaddr_in6 daddr6; }; struct dst_entry *dst; struct sk_buff_head receive_queue; struct sk_buff_head write_queue; Loading Loading @@ -692,6 +708,7 @@ struct cxgbi_device *cxgbi_device_register(unsigned int, unsigned int); void cxgbi_device_unregister(struct cxgbi_device *); void cxgbi_device_unregister_all(unsigned int flag); struct cxgbi_device *cxgbi_device_find_by_lldev(void *); struct cxgbi_device *cxgbi_device_find_by_netdev(struct net_device *, int *); int cxgbi_hbas_add(struct cxgbi_device *, unsigned int, unsigned int, struct scsi_host_template *, struct scsi_transport_template *); Loading