diff options
Diffstat (limited to 'drivers/s390/net')
-rw-r--r-- | drivers/s390/net/cu3088.c | 20 | ||||
-rw-r--r-- | drivers/s390/net/lcs.c | 3 | ||||
-rw-r--r-- | drivers/s390/net/netiucv.c | 3 | ||||
-rw-r--r-- | drivers/s390/net/qeth_core.h | 50 | ||||
-rw-r--r-- | drivers/s390/net/qeth_core_main.c | 200 | ||||
-rw-r--r-- | drivers/s390/net/qeth_l2_main.c | 30 | ||||
-rw-r--r-- | drivers/s390/net/qeth_l3.h | 3 | ||||
-rw-r--r-- | drivers/s390/net/qeth_l3_main.c | 30 |
8 files changed, 164 insertions, 175 deletions
diff --git a/drivers/s390/net/cu3088.c b/drivers/s390/net/cu3088.c index 76728ae4b843..8e7697305a4c 100644 --- a/drivers/s390/net/cu3088.c +++ b/drivers/s390/net/cu3088.c | |||
@@ -62,30 +62,14 @@ static struct device *cu3088_root_dev; | |||
62 | static ssize_t | 62 | static ssize_t |
63 | group_write(struct device_driver *drv, const char *buf, size_t count) | 63 | group_write(struct device_driver *drv, const char *buf, size_t count) |
64 | { | 64 | { |
65 | const char *start, *end; | ||
66 | char bus_ids[2][BUS_ID_SIZE], *argv[2]; | ||
67 | int i; | ||
68 | int ret; | 65 | int ret; |
69 | struct ccwgroup_driver *cdrv; | 66 | struct ccwgroup_driver *cdrv; |
70 | 67 | ||
71 | cdrv = to_ccwgroupdrv(drv); | 68 | cdrv = to_ccwgroupdrv(drv); |
72 | if (!cdrv) | 69 | if (!cdrv) |
73 | return -EINVAL; | 70 | return -EINVAL; |
74 | start = buf; | 71 | ret = ccwgroup_create_from_string(cu3088_root_dev, cdrv->driver_id, |
75 | for (i=0; i<2; i++) { | 72 | &cu3088_driver, 2, buf); |
76 | static const char delim[] = {',', '\n'}; | ||
77 | int len; | ||
78 | |||
79 | if (!(end = strchr(start, delim[i]))) | ||
80 | return -EINVAL; | ||
81 | len = min_t(ptrdiff_t, BUS_ID_SIZE, end - start + 1); | ||
82 | strlcpy (bus_ids[i], start, len); | ||
83 | argv[i] = bus_ids[i]; | ||
84 | start = end + 1; | ||
85 | } | ||
86 | |||
87 | ret = ccwgroup_create(cu3088_root_dev, cdrv->driver_id, | ||
88 | &cu3088_driver, 2, argv); | ||
89 | 73 | ||
90 | return (ret == 0) ? count : ret; | 74 | return (ret == 0) ? count : ret; |
91 | } | 75 | } |
diff --git a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c index f51ed9972587..dd22f4b37037 100644 --- a/drivers/s390/net/lcs.c +++ b/drivers/s390/net/lcs.c | |||
@@ -1793,7 +1793,8 @@ lcs_get_skb(struct lcs_card *card, char *skb_data, unsigned int skb_len) | |||
1793 | skb->protocol = card->lan_type_trans(skb, card->dev); | 1793 | skb->protocol = card->lan_type_trans(skb, card->dev); |
1794 | card->stats.rx_bytes += skb_len; | 1794 | card->stats.rx_bytes += skb_len; |
1795 | card->stats.rx_packets++; | 1795 | card->stats.rx_packets++; |
1796 | *((__u32 *)skb->cb) = ++card->pkt_seq; | 1796 | if (skb->protocol == htons(ETH_P_802_2)) |
1797 | *((__u32 *)skb->cb) = ++card->pkt_seq; | ||
1797 | netif_rx(skb); | 1798 | netif_rx(skb); |
1798 | } | 1799 | } |
1799 | 1800 | ||
diff --git a/drivers/s390/net/netiucv.c b/drivers/s390/net/netiucv.c index 8f876f6ab367..e4ba6a0372ac 100644 --- a/drivers/s390/net/netiucv.c +++ b/drivers/s390/net/netiucv.c | |||
@@ -1313,8 +1313,6 @@ static int netiucv_tx(struct sk_buff *skb, struct net_device *dev) | |||
1313 | * and throw away packet. | 1313 | * and throw away packet. |
1314 | */ | 1314 | */ |
1315 | if (fsm_getstate(privptr->fsm) != DEV_STATE_RUNNING) { | 1315 | if (fsm_getstate(privptr->fsm) != DEV_STATE_RUNNING) { |
1316 | if (!in_atomic()) | ||
1317 | fsm_event(privptr->fsm, DEV_EVENT_START, dev); | ||
1318 | dev_kfree_skb(skb); | 1316 | dev_kfree_skb(skb); |
1319 | privptr->stats.tx_dropped++; | 1317 | privptr->stats.tx_dropped++; |
1320 | privptr->stats.tx_errors++; | 1318 | privptr->stats.tx_errors++; |
@@ -2147,6 +2145,7 @@ static int __init netiucv_init(void) | |||
2147 | if (rc) | 2145 | if (rc) |
2148 | goto out_dbf; | 2146 | goto out_dbf; |
2149 | IUCV_DBF_TEXT(trace, 3, __func__); | 2147 | IUCV_DBF_TEXT(trace, 3, __func__); |
2148 | netiucv_driver.groups = netiucv_drv_attr_groups; | ||
2150 | rc = driver_register(&netiucv_driver); | 2149 | rc = driver_register(&netiucv_driver); |
2151 | if (rc) { | 2150 | if (rc) { |
2152 | PRINT_ERR("NETIUCV: failed to register driver.\n"); | 2151 | PRINT_ERR("NETIUCV: failed to register driver.\n"); |
diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h index 66f4f12503c9..699ac11debd8 100644 --- a/drivers/s390/net/qeth_core.h +++ b/drivers/s390/net/qeth_core.h | |||
@@ -72,22 +72,7 @@ struct qeth_dbf_info { | |||
72 | debug_sprintf_event(qeth_dbf[QETH_DBF_MSG].id, level, text) | 72 | debug_sprintf_event(qeth_dbf[QETH_DBF_MSG].id, level, text) |
73 | 73 | ||
74 | #define QETH_DBF_TEXT_(name, level, text...) \ | 74 | #define QETH_DBF_TEXT_(name, level, text...) \ |
75 | do { \ | 75 | qeth_dbf_longtext(QETH_DBF_##name, level, text) |
76 | if (qeth_dbf_passes(qeth_dbf[QETH_DBF_##name].id, level)) { \ | ||
77 | char *dbf_txt_buf = \ | ||
78 | get_cpu_var(QETH_DBF_TXT_BUF); \ | ||
79 | sprintf(dbf_txt_buf, text); \ | ||
80 | debug_text_event(qeth_dbf[QETH_DBF_##name].id, \ | ||
81 | level, dbf_txt_buf); \ | ||
82 | put_cpu_var(QETH_DBF_TXT_BUF); \ | ||
83 | } \ | ||
84 | } while (0) | ||
85 | |||
86 | /* Allow to sort out low debug levels early to avoid wasted sprints */ | ||
87 | static inline int qeth_dbf_passes(debug_info_t *dbf_grp, int level) | ||
88 | { | ||
89 | return (level <= dbf_grp->level); | ||
90 | } | ||
91 | 76 | ||
92 | /** | 77 | /** |
93 | * some more debug stuff | 78 | * some more debug stuff |
@@ -773,27 +758,6 @@ static inline int qeth_get_micros(void) | |||
773 | return (int) (get_clock() >> 12); | 758 | return (int) (get_clock() >> 12); |
774 | } | 759 | } |
775 | 760 | ||
776 | static inline void *qeth_push_skb(struct qeth_card *card, struct sk_buff *skb, | ||
777 | int size) | ||
778 | { | ||
779 | void *hdr; | ||
780 | |||
781 | hdr = (void *) skb_push(skb, size); | ||
782 | /* | ||
783 | * sanity check, the Linux memory allocation scheme should | ||
784 | * never present us cases like this one (the qdio header size plus | ||
785 | * the first 40 bytes of the paket cross a 4k boundary) | ||
786 | */ | ||
787 | if ((((unsigned long) hdr) & (~(PAGE_SIZE - 1))) != | ||
788 | (((unsigned long) hdr + size + | ||
789 | QETH_IP_HEADER_SIZE) & (~(PAGE_SIZE - 1)))) { | ||
790 | PRINT_ERR("Misaligned packet on interface %s. Discarded.", | ||
791 | QETH_CARD_IFNAME(card)); | ||
792 | return NULL; | ||
793 | } | ||
794 | return hdr; | ||
795 | } | ||
796 | |||
797 | static inline int qeth_get_ip_version(struct sk_buff *skb) | 761 | static inline int qeth_get_ip_version(struct sk_buff *skb) |
798 | { | 762 | { |
799 | switch (skb->protocol) { | 763 | switch (skb->protocol) { |
@@ -806,6 +770,12 @@ static inline int qeth_get_ip_version(struct sk_buff *skb) | |||
806 | } | 770 | } |
807 | } | 771 | } |
808 | 772 | ||
773 | static inline void qeth_put_buffer_pool_entry(struct qeth_card *card, | ||
774 | struct qeth_buffer_pool_entry *entry) | ||
775 | { | ||
776 | list_add_tail(&entry->list, &card->qdio.in_buf_pool.entry_list); | ||
777 | } | ||
778 | |||
809 | struct qeth_eddp_context; | 779 | struct qeth_eddp_context; |
810 | extern struct ccwgroup_driver qeth_l2_ccwgroup_driver; | 780 | extern struct ccwgroup_driver qeth_l2_ccwgroup_driver; |
811 | extern struct ccwgroup_driver qeth_l3_ccwgroup_driver; | 781 | extern struct ccwgroup_driver qeth_l3_ccwgroup_driver; |
@@ -843,8 +813,6 @@ struct qeth_cmd_buffer *qeth_get_ipacmd_buffer(struct qeth_card *, | |||
843 | int qeth_query_setadapterparms(struct qeth_card *); | 813 | int qeth_query_setadapterparms(struct qeth_card *); |
844 | int qeth_check_qdio_errors(struct qdio_buffer *, unsigned int, | 814 | int qeth_check_qdio_errors(struct qdio_buffer *, unsigned int, |
845 | unsigned int, const char *); | 815 | unsigned int, const char *); |
846 | void qeth_put_buffer_pool_entry(struct qeth_card *, | ||
847 | struct qeth_buffer_pool_entry *); | ||
848 | void qeth_queue_input_buffer(struct qeth_card *, int); | 816 | void qeth_queue_input_buffer(struct qeth_card *, int); |
849 | struct sk_buff *qeth_core_get_next_skb(struct qeth_card *, | 817 | struct sk_buff *qeth_core_get_next_skb(struct qeth_card *, |
850 | struct qdio_buffer *, struct qdio_buffer_element **, int *, | 818 | struct qdio_buffer *, struct qdio_buffer_element **, int *, |
@@ -880,8 +848,6 @@ int qeth_send_control_data(struct qeth_card *, int, struct qeth_cmd_buffer *, | |||
880 | void *reply_param); | 848 | void *reply_param); |
881 | int qeth_get_cast_type(struct qeth_card *, struct sk_buff *); | 849 | int qeth_get_cast_type(struct qeth_card *, struct sk_buff *); |
882 | int qeth_get_priority_queue(struct qeth_card *, struct sk_buff *, int, int); | 850 | int qeth_get_priority_queue(struct qeth_card *, struct sk_buff *, int, int); |
883 | struct sk_buff *qeth_prepare_skb(struct qeth_card *, struct sk_buff *, | ||
884 | struct qeth_hdr **); | ||
885 | int qeth_get_elements_no(struct qeth_card *, void *, struct sk_buff *, int); | 851 | int qeth_get_elements_no(struct qeth_card *, void *, struct sk_buff *, int); |
886 | int qeth_do_send_packet_fast(struct qeth_card *, struct qeth_qdio_out_q *, | 852 | int qeth_do_send_packet_fast(struct qeth_card *, struct qeth_qdio_out_q *, |
887 | struct sk_buff *, struct qeth_hdr *, int, | 853 | struct sk_buff *, struct qeth_hdr *, int, |
@@ -894,6 +860,8 @@ void qeth_core_get_ethtool_stats(struct net_device *, | |||
894 | struct ethtool_stats *, u64 *); | 860 | struct ethtool_stats *, u64 *); |
895 | void qeth_core_get_strings(struct net_device *, u32, u8 *); | 861 | void qeth_core_get_strings(struct net_device *, u32, u8 *); |
896 | void qeth_core_get_drvinfo(struct net_device *, struct ethtool_drvinfo *); | 862 | void qeth_core_get_drvinfo(struct net_device *, struct ethtool_drvinfo *); |
863 | void qeth_dbf_longtext(enum qeth_dbf_names dbf_nix, int level, char *text, ...); | ||
864 | int qeth_core_ethtool_get_settings(struct net_device *, struct ethtool_cmd *); | ||
897 | 865 | ||
898 | /* exports for OSN */ | 866 | /* exports for OSN */ |
899 | int qeth_osn_assist(struct net_device *, void *, int); | 867 | int qeth_osn_assist(struct net_device *, void *, int); |
diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index 055f5c3e7b56..436bf1f6d4a6 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c | |||
@@ -26,9 +26,6 @@ | |||
26 | #include "qeth_core.h" | 26 | #include "qeth_core.h" |
27 | #include "qeth_core_offl.h" | 27 | #include "qeth_core_offl.h" |
28 | 28 | ||
29 | static DEFINE_PER_CPU(char[256], qeth_core_dbf_txt_buf); | ||
30 | #define QETH_DBF_TXT_BUF qeth_core_dbf_txt_buf | ||
31 | |||
32 | struct qeth_dbf_info qeth_dbf[QETH_DBF_INFOS] = { | 29 | struct qeth_dbf_info qeth_dbf[QETH_DBF_INFOS] = { |
33 | /* define dbf - Name, Pages, Areas, Maxlen, Level, View, Handle */ | 30 | /* define dbf - Name, Pages, Areas, Maxlen, Level, View, Handle */ |
34 | /* N P A M L V H */ | 31 | /* N P A M L V H */ |
@@ -2255,14 +2252,6 @@ void qeth_print_status_message(struct qeth_card *card) | |||
2255 | } | 2252 | } |
2256 | EXPORT_SYMBOL_GPL(qeth_print_status_message); | 2253 | EXPORT_SYMBOL_GPL(qeth_print_status_message); |
2257 | 2254 | ||
2258 | void qeth_put_buffer_pool_entry(struct qeth_card *card, | ||
2259 | struct qeth_buffer_pool_entry *entry) | ||
2260 | { | ||
2261 | QETH_DBF_TEXT(TRACE, 6, "ptbfplen"); | ||
2262 | list_add_tail(&entry->list, &card->qdio.in_buf_pool.entry_list); | ||
2263 | } | ||
2264 | EXPORT_SYMBOL_GPL(qeth_put_buffer_pool_entry); | ||
2265 | |||
2266 | static void qeth_initialize_working_pool_list(struct qeth_card *card) | 2255 | static void qeth_initialize_working_pool_list(struct qeth_card *card) |
2267 | { | 2256 | { |
2268 | struct qeth_buffer_pool_entry *entry; | 2257 | struct qeth_buffer_pool_entry *entry; |
@@ -2603,7 +2592,6 @@ void qeth_queue_input_buffer(struct qeth_card *card, int index) | |||
2603 | int rc; | 2592 | int rc; |
2604 | int newcount = 0; | 2593 | int newcount = 0; |
2605 | 2594 | ||
2606 | QETH_DBF_TEXT(TRACE, 6, "queinbuf"); | ||
2607 | count = (index < queue->next_buf_to_init)? | 2595 | count = (index < queue->next_buf_to_init)? |
2608 | card->qdio.in_buf_pool.buf_count - | 2596 | card->qdio.in_buf_pool.buf_count - |
2609 | (queue->next_buf_to_init - index) : | 2597 | (queue->next_buf_to_init - index) : |
@@ -2792,8 +2780,6 @@ static void qeth_flush_buffers(struct qeth_qdio_out_q *queue, int under_int, | |||
2792 | int i; | 2780 | int i; |
2793 | unsigned int qdio_flags; | 2781 | unsigned int qdio_flags; |
2794 | 2782 | ||
2795 | QETH_DBF_TEXT(TRACE, 6, "flushbuf"); | ||
2796 | |||
2797 | for (i = index; i < index + count; ++i) { | 2783 | for (i = index; i < index + count; ++i) { |
2798 | buf = &queue->bufs[i % QDIO_MAX_BUFFERS_PER_Q]; | 2784 | buf = &queue->bufs[i % QDIO_MAX_BUFFERS_PER_Q]; |
2799 | buf->buffer->element[buf->next_element_to_fill - 1].flags |= | 2785 | buf->buffer->element[buf->next_element_to_fill - 1].flags |= |
@@ -3037,49 +3023,6 @@ int qeth_get_priority_queue(struct qeth_card *card, struct sk_buff *skb, | |||
3037 | } | 3023 | } |
3038 | EXPORT_SYMBOL_GPL(qeth_get_priority_queue); | 3024 | EXPORT_SYMBOL_GPL(qeth_get_priority_queue); |
3039 | 3025 | ||
3040 | static void __qeth_free_new_skb(struct sk_buff *orig_skb, | ||
3041 | struct sk_buff *new_skb) | ||
3042 | { | ||
3043 | if (orig_skb != new_skb) | ||
3044 | dev_kfree_skb_any(new_skb); | ||
3045 | } | ||
3046 | |||
3047 | static inline struct sk_buff *qeth_realloc_headroom(struct qeth_card *card, | ||
3048 | struct sk_buff *skb, int size) | ||
3049 | { | ||
3050 | struct sk_buff *new_skb = skb; | ||
3051 | |||
3052 | if (skb_headroom(skb) >= size) | ||
3053 | return skb; | ||
3054 | new_skb = skb_realloc_headroom(skb, size); | ||
3055 | if (!new_skb) | ||
3056 | PRINT_ERR("Could not realloc headroom for qeth_hdr " | ||
3057 | "on interface %s", QETH_CARD_IFNAME(card)); | ||
3058 | return new_skb; | ||
3059 | } | ||
3060 | |||
3061 | struct sk_buff *qeth_prepare_skb(struct qeth_card *card, struct sk_buff *skb, | ||
3062 | struct qeth_hdr **hdr) | ||
3063 | { | ||
3064 | struct sk_buff *new_skb; | ||
3065 | |||
3066 | QETH_DBF_TEXT(TRACE, 6, "prepskb"); | ||
3067 | |||
3068 | new_skb = qeth_realloc_headroom(card, skb, | ||
3069 | sizeof(struct qeth_hdr)); | ||
3070 | if (!new_skb) | ||
3071 | return NULL; | ||
3072 | |||
3073 | *hdr = ((struct qeth_hdr *)qeth_push_skb(card, new_skb, | ||
3074 | sizeof(struct qeth_hdr))); | ||
3075 | if (*hdr == NULL) { | ||
3076 | __qeth_free_new_skb(skb, new_skb); | ||
3077 | return NULL; | ||
3078 | } | ||
3079 | return new_skb; | ||
3080 | } | ||
3081 | EXPORT_SYMBOL_GPL(qeth_prepare_skb); | ||
3082 | |||
3083 | int qeth_get_elements_no(struct qeth_card *card, void *hdr, | 3026 | int qeth_get_elements_no(struct qeth_card *card, void *hdr, |
3084 | struct sk_buff *skb, int elems) | 3027 | struct sk_buff *skb, int elems) |
3085 | { | 3028 | { |
@@ -3100,8 +3043,8 @@ int qeth_get_elements_no(struct qeth_card *card, void *hdr, | |||
3100 | } | 3043 | } |
3101 | EXPORT_SYMBOL_GPL(qeth_get_elements_no); | 3044 | EXPORT_SYMBOL_GPL(qeth_get_elements_no); |
3102 | 3045 | ||
3103 | static void __qeth_fill_buffer(struct sk_buff *skb, struct qdio_buffer *buffer, | 3046 | static inline void __qeth_fill_buffer(struct sk_buff *skb, |
3104 | int is_tso, int *next_element_to_fill) | 3047 | struct qdio_buffer *buffer, int is_tso, int *next_element_to_fill) |
3105 | { | 3048 | { |
3106 | int length = skb->len; | 3049 | int length = skb->len; |
3107 | int length_here; | 3050 | int length_here; |
@@ -3143,15 +3086,13 @@ static void __qeth_fill_buffer(struct sk_buff *skb, struct qdio_buffer *buffer, | |||
3143 | *next_element_to_fill = element; | 3086 | *next_element_to_fill = element; |
3144 | } | 3087 | } |
3145 | 3088 | ||
3146 | static int qeth_fill_buffer(struct qeth_qdio_out_q *queue, | 3089 | static inline int qeth_fill_buffer(struct qeth_qdio_out_q *queue, |
3147 | struct qeth_qdio_out_buffer *buf, struct sk_buff *skb) | 3090 | struct qeth_qdio_out_buffer *buf, struct sk_buff *skb) |
3148 | { | 3091 | { |
3149 | struct qdio_buffer *buffer; | 3092 | struct qdio_buffer *buffer; |
3150 | struct qeth_hdr_tso *hdr; | 3093 | struct qeth_hdr_tso *hdr; |
3151 | int flush_cnt = 0, hdr_len, large_send = 0; | 3094 | int flush_cnt = 0, hdr_len, large_send = 0; |
3152 | 3095 | ||
3153 | QETH_DBF_TEXT(TRACE, 6, "qdfillbf"); | ||
3154 | |||
3155 | buffer = buf->buffer; | 3096 | buffer = buf->buffer; |
3156 | atomic_inc(&skb->users); | 3097 | atomic_inc(&skb->users); |
3157 | skb_queue_tail(&buf->skb_list, skb); | 3098 | skb_queue_tail(&buf->skb_list, skb); |
@@ -3210,8 +3151,6 @@ int qeth_do_send_packet_fast(struct qeth_card *card, | |||
3210 | int flush_cnt = 0; | 3151 | int flush_cnt = 0; |
3211 | int index; | 3152 | int index; |
3212 | 3153 | ||
3213 | QETH_DBF_TEXT(TRACE, 6, "dosndpfa"); | ||
3214 | |||
3215 | /* spin until we get the queue ... */ | 3154 | /* spin until we get the queue ... */ |
3216 | while (atomic_cmpxchg(&queue->state, QETH_OUT_Q_UNLOCKED, | 3155 | while (atomic_cmpxchg(&queue->state, QETH_OUT_Q_UNLOCKED, |
3217 | QETH_OUT_Q_LOCKED) != QETH_OUT_Q_UNLOCKED); | 3156 | QETH_OUT_Q_LOCKED) != QETH_OUT_Q_UNLOCKED); |
@@ -3263,8 +3202,6 @@ int qeth_do_send_packet(struct qeth_card *card, struct qeth_qdio_out_q *queue, | |||
3263 | int tmp; | 3202 | int tmp; |
3264 | int rc = 0; | 3203 | int rc = 0; |
3265 | 3204 | ||
3266 | QETH_DBF_TEXT(TRACE, 6, "dosndpkt"); | ||
3267 | |||
3268 | /* spin until we get the queue ... */ | 3205 | /* spin until we get the queue ... */ |
3269 | while (atomic_cmpxchg(&queue->state, QETH_OUT_Q_UNLOCKED, | 3206 | while (atomic_cmpxchg(&queue->state, QETH_OUT_Q_UNLOCKED, |
3270 | QETH_OUT_Q_LOCKED) != QETH_OUT_Q_UNLOCKED); | 3207 | QETH_OUT_Q_LOCKED) != QETH_OUT_Q_UNLOCKED); |
@@ -3827,27 +3764,8 @@ static struct ccw_driver qeth_ccw_driver = { | |||
3827 | static int qeth_core_driver_group(const char *buf, struct device *root_dev, | 3764 | static int qeth_core_driver_group(const char *buf, struct device *root_dev, |
3828 | unsigned long driver_id) | 3765 | unsigned long driver_id) |
3829 | { | 3766 | { |
3830 | const char *start, *end; | 3767 | return ccwgroup_create_from_string(root_dev, driver_id, |
3831 | char bus_ids[3][BUS_ID_SIZE], *argv[3]; | 3768 | &qeth_ccw_driver, 3, buf); |
3832 | int i; | ||
3833 | |||
3834 | start = buf; | ||
3835 | for (i = 0; i < 3; i++) { | ||
3836 | static const char delim[] = { ',', ',', '\n' }; | ||
3837 | int len; | ||
3838 | |||
3839 | end = strchr(start, delim[i]); | ||
3840 | if (!end) | ||
3841 | return -EINVAL; | ||
3842 | len = min_t(ptrdiff_t, BUS_ID_SIZE, end - start); | ||
3843 | strncpy(bus_ids[i], start, len); | ||
3844 | bus_ids[i][len] = '\0'; | ||
3845 | start = end + 1; | ||
3846 | argv[i] = bus_ids[i]; | ||
3847 | } | ||
3848 | |||
3849 | return (ccwgroup_create(root_dev, driver_id, | ||
3850 | &qeth_ccw_driver, 3, argv)); | ||
3851 | } | 3769 | } |
3852 | 3770 | ||
3853 | int qeth_core_hardsetup_card(struct qeth_card *card) | 3771 | int qeth_core_hardsetup_card(struct qeth_card *card) |
@@ -3885,8 +3803,9 @@ retry: | |||
3885 | QETH_DBF_TEXT_(SETUP, 2, "2err%d", rc); | 3803 | QETH_DBF_TEXT_(SETUP, 2, "2err%d", rc); |
3886 | return rc; | 3804 | return rc; |
3887 | } | 3805 | } |
3888 | 3806 | mpno = qdio_get_ssqd_pct(CARD_DDEV(card)); | |
3889 | mpno = QETH_MAX_PORTNO; | 3807 | if (mpno) |
3808 | mpno = min(mpno - 1, QETH_MAX_PORTNO); | ||
3890 | if (card->info.portno > mpno) { | 3809 | if (card->info.portno > mpno) { |
3891 | PRINT_ERR("Device %s does not offer port number %d \n.", | 3810 | PRINT_ERR("Device %s does not offer port number %d \n.", |
3892 | CARD_BUS_ID(card), card->info.portno); | 3811 | CARD_BUS_ID(card), card->info.portno); |
@@ -3980,7 +3899,6 @@ struct sk_buff *qeth_core_get_next_skb(struct qeth_card *card, | |||
3980 | int use_rx_sg = 0; | 3899 | int use_rx_sg = 0; |
3981 | int frag = 0; | 3900 | int frag = 0; |
3982 | 3901 | ||
3983 | QETH_DBF_TEXT(TRACE, 6, "nextskb"); | ||
3984 | /* qeth_hdr must not cross element boundaries */ | 3902 | /* qeth_hdr must not cross element boundaries */ |
3985 | if (element->length < offset + sizeof(struct qeth_hdr)) { | 3903 | if (element->length < offset + sizeof(struct qeth_hdr)) { |
3986 | if (qeth_is_last_sbale(element)) | 3904 | if (qeth_is_last_sbale(element)) |
@@ -4086,6 +4004,18 @@ static void qeth_unregister_dbf_views(void) | |||
4086 | } | 4004 | } |
4087 | } | 4005 | } |
4088 | 4006 | ||
4007 | void qeth_dbf_longtext(enum qeth_dbf_names dbf_nix, int level, char *text, ...) | ||
4008 | { | ||
4009 | char dbf_txt_buf[32]; | ||
4010 | |||
4011 | if (level > (qeth_dbf[dbf_nix].id)->level) | ||
4012 | return; | ||
4013 | snprintf(dbf_txt_buf, sizeof(dbf_txt_buf), text); | ||
4014 | debug_text_event(qeth_dbf[dbf_nix].id, level, dbf_txt_buf); | ||
4015 | |||
4016 | } | ||
4017 | EXPORT_SYMBOL_GPL(qeth_dbf_longtext); | ||
4018 | |||
4089 | static int qeth_register_dbf_views(void) | 4019 | static int qeth_register_dbf_views(void) |
4090 | { | 4020 | { |
4091 | int ret; | 4021 | int ret; |
@@ -4433,6 +4363,96 @@ void qeth_core_get_drvinfo(struct net_device *dev, | |||
4433 | } | 4363 | } |
4434 | EXPORT_SYMBOL_GPL(qeth_core_get_drvinfo); | 4364 | EXPORT_SYMBOL_GPL(qeth_core_get_drvinfo); |
4435 | 4365 | ||
4366 | int qeth_core_ethtool_get_settings(struct net_device *netdev, | ||
4367 | struct ethtool_cmd *ecmd) | ||
4368 | { | ||
4369 | struct qeth_card *card = netdev_priv(netdev); | ||
4370 | enum qeth_link_types link_type; | ||
4371 | |||
4372 | if ((card->info.type == QETH_CARD_TYPE_IQD) || (card->info.guestlan)) | ||
4373 | link_type = QETH_LINK_TYPE_10GBIT_ETH; | ||
4374 | else | ||
4375 | link_type = card->info.link_type; | ||
4376 | |||
4377 | ecmd->transceiver = XCVR_INTERNAL; | ||
4378 | ecmd->supported = SUPPORTED_Autoneg; | ||
4379 | ecmd->advertising = ADVERTISED_Autoneg; | ||
4380 | ecmd->duplex = DUPLEX_FULL; | ||
4381 | ecmd->autoneg = AUTONEG_ENABLE; | ||
4382 | |||
4383 | switch (link_type) { | ||
4384 | case QETH_LINK_TYPE_FAST_ETH: | ||
4385 | case QETH_LINK_TYPE_LANE_ETH100: | ||
4386 | ecmd->supported |= SUPPORTED_10baseT_Half | | ||
4387 | SUPPORTED_10baseT_Full | | ||
4388 | SUPPORTED_100baseT_Half | | ||
4389 | SUPPORTED_100baseT_Full | | ||
4390 | SUPPORTED_TP; | ||
4391 | ecmd->advertising |= ADVERTISED_10baseT_Half | | ||
4392 | ADVERTISED_10baseT_Full | | ||
4393 | ADVERTISED_100baseT_Half | | ||
4394 | ADVERTISED_100baseT_Full | | ||
4395 | ADVERTISED_TP; | ||
4396 | ecmd->speed = SPEED_100; | ||
4397 | ecmd->port = PORT_TP; | ||
4398 | break; | ||
4399 | |||
4400 | case QETH_LINK_TYPE_GBIT_ETH: | ||
4401 | case QETH_LINK_TYPE_LANE_ETH1000: | ||
4402 | ecmd->supported |= SUPPORTED_10baseT_Half | | ||
4403 | SUPPORTED_10baseT_Full | | ||
4404 | SUPPORTED_100baseT_Half | | ||
4405 | SUPPORTED_100baseT_Full | | ||
4406 | SUPPORTED_1000baseT_Half | | ||
4407 | SUPPORTED_1000baseT_Full | | ||
4408 | SUPPORTED_FIBRE; | ||
4409 | ecmd->advertising |= ADVERTISED_10baseT_Half | | ||
4410 | ADVERTISED_10baseT_Full | | ||
4411 | ADVERTISED_100baseT_Half | | ||
4412 | ADVERTISED_100baseT_Full | | ||
4413 | ADVERTISED_1000baseT_Half | | ||
4414 | ADVERTISED_1000baseT_Full | | ||
4415 | ADVERTISED_FIBRE; | ||
4416 | ecmd->speed = SPEED_1000; | ||
4417 | ecmd->port = PORT_FIBRE; | ||
4418 | break; | ||
4419 | |||
4420 | case QETH_LINK_TYPE_10GBIT_ETH: | ||
4421 | ecmd->supported |= SUPPORTED_10baseT_Half | | ||
4422 | SUPPORTED_10baseT_Full | | ||
4423 | SUPPORTED_100baseT_Half | | ||
4424 | SUPPORTED_100baseT_Full | | ||
4425 | SUPPORTED_1000baseT_Half | | ||
4426 | SUPPORTED_1000baseT_Full | | ||
4427 | SUPPORTED_10000baseT_Full | | ||
4428 | SUPPORTED_FIBRE; | ||
4429 | ecmd->advertising |= ADVERTISED_10baseT_Half | | ||
4430 | ADVERTISED_10baseT_Full | | ||
4431 | ADVERTISED_100baseT_Half | | ||
4432 | ADVERTISED_100baseT_Full | | ||
4433 | ADVERTISED_1000baseT_Half | | ||
4434 | ADVERTISED_1000baseT_Full | | ||
4435 | ADVERTISED_10000baseT_Full | | ||
4436 | ADVERTISED_FIBRE; | ||
4437 | ecmd->speed = SPEED_10000; | ||
4438 | ecmd->port = PORT_FIBRE; | ||
4439 | break; | ||
4440 | |||
4441 | default: | ||
4442 | ecmd->supported |= SUPPORTED_10baseT_Half | | ||
4443 | SUPPORTED_10baseT_Full | | ||
4444 | SUPPORTED_TP; | ||
4445 | ecmd->advertising |= ADVERTISED_10baseT_Half | | ||
4446 | ADVERTISED_10baseT_Full | | ||
4447 | ADVERTISED_TP; | ||
4448 | ecmd->speed = SPEED_10; | ||
4449 | ecmd->port = PORT_TP; | ||
4450 | } | ||
4451 | |||
4452 | return 0; | ||
4453 | } | ||
4454 | EXPORT_SYMBOL_GPL(qeth_core_ethtool_get_settings); | ||
4455 | |||
4436 | static int __init qeth_core_init(void) | 4456 | static int __init qeth_core_init(void) |
4437 | { | 4457 | { |
4438 | int rc; | 4458 | int rc; |
diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c index 3921d1631a78..86ec50ddae13 100644 --- a/drivers/s390/net/qeth_l2_main.c +++ b/drivers/s390/net/qeth_l2_main.c | |||
@@ -22,9 +22,6 @@ | |||
22 | #include "qeth_core.h" | 22 | #include "qeth_core.h" |
23 | #include "qeth_core_offl.h" | 23 | #include "qeth_core_offl.h" |
24 | 24 | ||
25 | #define QETH_DBF_TXT_BUF qeth_l2_dbf_txt_buf | ||
26 | static DEFINE_PER_CPU(char[256], qeth_l2_dbf_txt_buf); | ||
27 | |||
28 | static int qeth_l2_set_offline(struct ccwgroup_device *); | 25 | static int qeth_l2_set_offline(struct ccwgroup_device *); |
29 | static int qeth_l2_stop(struct net_device *); | 26 | static int qeth_l2_stop(struct net_device *); |
30 | static int qeth_l2_send_delmac(struct qeth_card *, __u8 *); | 27 | static int qeth_l2_send_delmac(struct qeth_card *, __u8 *); |
@@ -635,8 +632,6 @@ static int qeth_l2_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
635 | enum qeth_large_send_types large_send = QETH_LARGE_SEND_NO; | 632 | enum qeth_large_send_types large_send = QETH_LARGE_SEND_NO; |
636 | struct qeth_eddp_context *ctx = NULL; | 633 | struct qeth_eddp_context *ctx = NULL; |
637 | 634 | ||
638 | QETH_DBF_TEXT(TRACE, 6, "l2xmit"); | ||
639 | |||
640 | if ((card->state != CARD_STATE_UP) || !card->lan_online) { | 635 | if ((card->state != CARD_STATE_UP) || !card->lan_online) { |
641 | card->stats.tx_carrier_errors++; | 636 | card->stats.tx_carrier_errors++; |
642 | goto tx_drop; | 637 | goto tx_drop; |
@@ -658,9 +653,12 @@ static int qeth_l2_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
658 | if (card->info.type == QETH_CARD_TYPE_OSN) | 653 | if (card->info.type == QETH_CARD_TYPE_OSN) |
659 | hdr = (struct qeth_hdr *)skb->data; | 654 | hdr = (struct qeth_hdr *)skb->data; |
660 | else { | 655 | else { |
661 | new_skb = qeth_prepare_skb(card, skb, &hdr); | 656 | /* create a clone with writeable headroom */ |
657 | new_skb = skb_realloc_headroom(skb, sizeof(struct qeth_hdr)); | ||
662 | if (!new_skb) | 658 | if (!new_skb) |
663 | goto tx_drop; | 659 | goto tx_drop; |
660 | hdr = (struct qeth_hdr *)skb_push(new_skb, | ||
661 | sizeof(struct qeth_hdr)); | ||
664 | qeth_l2_fill_header(card, hdr, new_skb, ipv, cast_type); | 662 | qeth_l2_fill_header(card, hdr, new_skb, ipv, cast_type); |
665 | } | 663 | } |
666 | 664 | ||
@@ -747,7 +745,6 @@ static void qeth_l2_qdio_input_handler(struct ccw_device *ccwdev, | |||
747 | int index; | 745 | int index; |
748 | int i; | 746 | int i; |
749 | 747 | ||
750 | QETH_DBF_TEXT(TRACE, 6, "qdinput"); | ||
751 | card = (struct qeth_card *) card_ptr; | 748 | card = (struct qeth_card *) card_ptr; |
752 | net_dev = card->dev; | 749 | net_dev = card->dev; |
753 | if (card->options.performance_stats) { | 750 | if (card->options.performance_stats) { |
@@ -852,6 +849,22 @@ static void qeth_l2_remove_device(struct ccwgroup_device *cgdev) | |||
852 | return; | 849 | return; |
853 | } | 850 | } |
854 | 851 | ||
852 | static int qeth_l2_ethtool_set_tso(struct net_device *dev, u32 data) | ||
853 | { | ||
854 | struct qeth_card *card = netdev_priv(dev); | ||
855 | |||
856 | if (data) { | ||
857 | if (card->options.large_send == QETH_LARGE_SEND_NO) { | ||
858 | card->options.large_send = QETH_LARGE_SEND_EDDP; | ||
859 | dev->features |= NETIF_F_TSO; | ||
860 | } | ||
861 | } else { | ||
862 | dev->features &= ~NETIF_F_TSO; | ||
863 | card->options.large_send = QETH_LARGE_SEND_NO; | ||
864 | } | ||
865 | return 0; | ||
866 | } | ||
867 | |||
855 | static struct ethtool_ops qeth_l2_ethtool_ops = { | 868 | static struct ethtool_ops qeth_l2_ethtool_ops = { |
856 | .get_link = ethtool_op_get_link, | 869 | .get_link = ethtool_op_get_link, |
857 | .get_tx_csum = ethtool_op_get_tx_csum, | 870 | .get_tx_csum = ethtool_op_get_tx_csum, |
@@ -859,11 +872,12 @@ static struct ethtool_ops qeth_l2_ethtool_ops = { | |||
859 | .get_sg = ethtool_op_get_sg, | 872 | .get_sg = ethtool_op_get_sg, |
860 | .set_sg = ethtool_op_set_sg, | 873 | .set_sg = ethtool_op_set_sg, |
861 | .get_tso = ethtool_op_get_tso, | 874 | .get_tso = ethtool_op_get_tso, |
862 | .set_tso = ethtool_op_set_tso, | 875 | .set_tso = qeth_l2_ethtool_set_tso, |
863 | .get_strings = qeth_core_get_strings, | 876 | .get_strings = qeth_core_get_strings, |
864 | .get_ethtool_stats = qeth_core_get_ethtool_stats, | 877 | .get_ethtool_stats = qeth_core_get_ethtool_stats, |
865 | .get_stats_count = qeth_core_get_stats_count, | 878 | .get_stats_count = qeth_core_get_stats_count, |
866 | .get_drvinfo = qeth_core_get_drvinfo, | 879 | .get_drvinfo = qeth_core_get_drvinfo, |
880 | .get_settings = qeth_core_ethtool_get_settings, | ||
867 | }; | 881 | }; |
868 | 882 | ||
869 | static struct ethtool_ops qeth_l2_osn_ops = { | 883 | static struct ethtool_ops qeth_l2_osn_ops = { |
diff --git a/drivers/s390/net/qeth_l3.h b/drivers/s390/net/qeth_l3.h index 1be353593a59..9f143c83bba3 100644 --- a/drivers/s390/net/qeth_l3.h +++ b/drivers/s390/net/qeth_l3.h | |||
@@ -13,9 +13,6 @@ | |||
13 | 13 | ||
14 | #include "qeth_core.h" | 14 | #include "qeth_core.h" |
15 | 15 | ||
16 | #define QETH_DBF_TXT_BUF qeth_l3_dbf_txt_buf | ||
17 | DECLARE_PER_CPU(char[256], qeth_l3_dbf_txt_buf); | ||
18 | |||
19 | struct qeth_ipaddr { | 16 | struct qeth_ipaddr { |
20 | struct list_head entry; | 17 | struct list_head entry; |
21 | enum qeth_ip_types type; | 18 | enum qeth_ip_types type; |
diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index e1bfe56087d6..94a8ead64ed4 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c | |||
@@ -28,8 +28,6 @@ | |||
28 | #include "qeth_l3.h" | 28 | #include "qeth_l3.h" |
29 | #include "qeth_core_offl.h" | 29 | #include "qeth_core_offl.h" |
30 | 30 | ||
31 | DEFINE_PER_CPU(char[256], qeth_l3_dbf_txt_buf); | ||
32 | |||
33 | static int qeth_l3_set_offline(struct ccwgroup_device *); | 31 | static int qeth_l3_set_offline(struct ccwgroup_device *); |
34 | static int qeth_l3_recover(void *); | 32 | static int qeth_l3_recover(void *); |
35 | static int qeth_l3_stop(struct net_device *); | 33 | static int qeth_l3_stop(struct net_device *); |
@@ -2093,6 +2091,11 @@ static int qeth_l3_stop_card(struct qeth_card *card, int recovery_mode) | |||
2093 | (card->state == CARD_STATE_UP)) { | 2091 | (card->state == CARD_STATE_UP)) { |
2094 | if (recovery_mode) | 2092 | if (recovery_mode) |
2095 | qeth_l3_stop(card->dev); | 2093 | qeth_l3_stop(card->dev); |
2094 | else { | ||
2095 | rtnl_lock(); | ||
2096 | dev_close(card->dev); | ||
2097 | rtnl_unlock(); | ||
2098 | } | ||
2096 | if (!card->use_hard_stop) { | 2099 | if (!card->use_hard_stop) { |
2097 | rc = qeth_send_stoplan(card); | 2100 | rc = qeth_send_stoplan(card); |
2098 | if (rc) | 2101 | if (rc) |
@@ -2559,8 +2562,6 @@ static int qeth_l3_do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) | |||
2559 | static void qeth_l3_fill_header(struct qeth_card *card, struct qeth_hdr *hdr, | 2562 | static void qeth_l3_fill_header(struct qeth_card *card, struct qeth_hdr *hdr, |
2560 | struct sk_buff *skb, int ipv, int cast_type) | 2563 | struct sk_buff *skb, int ipv, int cast_type) |
2561 | { | 2564 | { |
2562 | QETH_DBF_TEXT(TRACE, 6, "fillhdr"); | ||
2563 | |||
2564 | memset(hdr, 0, sizeof(struct qeth_hdr)); | 2565 | memset(hdr, 0, sizeof(struct qeth_hdr)); |
2565 | hdr->hdr.l3.id = QETH_HEADER_TYPE_LAYER3; | 2566 | hdr->hdr.l3.id = QETH_HEADER_TYPE_LAYER3; |
2566 | hdr->hdr.l3.ext_flags = 0; | 2567 | hdr->hdr.l3.ext_flags = 0; |
@@ -2570,9 +2571,10 @@ static void qeth_l3_fill_header(struct qeth_card *card, struct qeth_hdr *hdr, | |||
2570 | * v6 uses passthrough, v4 sets the tag in the QDIO header. | 2571 | * v6 uses passthrough, v4 sets the tag in the QDIO header. |
2571 | */ | 2572 | */ |
2572 | if (card->vlangrp && vlan_tx_tag_present(skb)) { | 2573 | if (card->vlangrp && vlan_tx_tag_present(skb)) { |
2573 | hdr->hdr.l3.ext_flags = (ipv == 4) ? | 2574 | if ((ipv == 4) || (card->info.type == QETH_CARD_TYPE_IQD)) |
2574 | QETH_HDR_EXT_VLAN_FRAME : | 2575 | hdr->hdr.l3.ext_flags = QETH_HDR_EXT_VLAN_FRAME; |
2575 | QETH_HDR_EXT_INCLUDE_VLAN_TAG; | 2576 | else |
2577 | hdr->hdr.l3.ext_flags = QETH_HDR_EXT_INCLUDE_VLAN_TAG; | ||
2576 | hdr->hdr.l3.vlan_id = vlan_tx_tag_get(skb); | 2578 | hdr->hdr.l3.vlan_id = vlan_tx_tag_get(skb); |
2577 | } | 2579 | } |
2578 | 2580 | ||
@@ -2638,8 +2640,6 @@ static int qeth_l3_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
2638 | enum qeth_large_send_types large_send = QETH_LARGE_SEND_NO; | 2640 | enum qeth_large_send_types large_send = QETH_LARGE_SEND_NO; |
2639 | struct qeth_eddp_context *ctx = NULL; | 2641 | struct qeth_eddp_context *ctx = NULL; |
2640 | 2642 | ||
2641 | QETH_DBF_TEXT(TRACE, 6, "l3xmit"); | ||
2642 | |||
2643 | if ((card->info.type == QETH_CARD_TYPE_IQD) && | 2643 | if ((card->info.type == QETH_CARD_TYPE_IQD) && |
2644 | (skb->protocol != htons(ETH_P_IPV6)) && | 2644 | (skb->protocol != htons(ETH_P_IPV6)) && |
2645 | (skb->protocol != htons(ETH_P_IP))) | 2645 | (skb->protocol != htons(ETH_P_IP))) |
@@ -2890,6 +2890,7 @@ static struct ethtool_ops qeth_l3_ethtool_ops = { | |||
2890 | .get_ethtool_stats = qeth_core_get_ethtool_stats, | 2890 | .get_ethtool_stats = qeth_core_get_ethtool_stats, |
2891 | .get_stats_count = qeth_core_get_stats_count, | 2891 | .get_stats_count = qeth_core_get_stats_count, |
2892 | .get_drvinfo = qeth_core_get_drvinfo, | 2892 | .get_drvinfo = qeth_core_get_drvinfo, |
2893 | .get_settings = qeth_core_ethtool_get_settings, | ||
2893 | }; | 2894 | }; |
2894 | 2895 | ||
2895 | /* | 2896 | /* |
@@ -2982,7 +2983,6 @@ static void qeth_l3_qdio_input_handler(struct ccw_device *ccwdev, | |||
2982 | int index; | 2983 | int index; |
2983 | int i; | 2984 | int i; |
2984 | 2985 | ||
2985 | QETH_DBF_TEXT(TRACE, 6, "qdinput"); | ||
2986 | card = (struct qeth_card *) card_ptr; | 2986 | card = (struct qeth_card *) card_ptr; |
2987 | net_dev = card->dev; | 2987 | net_dev = card->dev; |
2988 | if (card->options.performance_stats) { | 2988 | if (card->options.performance_stats) { |
@@ -3140,9 +3140,15 @@ static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode) | |||
3140 | netif_carrier_on(card->dev); | 3140 | netif_carrier_on(card->dev); |
3141 | 3141 | ||
3142 | qeth_set_allowed_threads(card, 0xffffffff, 0); | 3142 | qeth_set_allowed_threads(card, 0xffffffff, 0); |
3143 | if ((recover_flag == CARD_STATE_RECOVER) && recovery_mode) { | 3143 | if (recover_flag == CARD_STATE_RECOVER) { |
3144 | if (recovery_mode) | ||
3144 | qeth_l3_open(card->dev); | 3145 | qeth_l3_open(card->dev); |
3145 | qeth_l3_set_multicast_list(card->dev); | 3146 | else { |
3147 | rtnl_lock(); | ||
3148 | dev_open(card->dev); | ||
3149 | rtnl_unlock(); | ||
3150 | } | ||
3151 | qeth_l3_set_multicast_list(card->dev); | ||
3146 | } | 3152 | } |
3147 | /* let user_space know that device is online */ | 3153 | /* let user_space know that device is online */ |
3148 | kobject_uevent(&gdev->dev.kobj, KOBJ_CHANGE); | 3154 | kobject_uevent(&gdev->dev.kobj, KOBJ_CHANGE); |