s390: qeth some more patches for 2.6.36
Subsystems (4)
cover s390: qeth some more patches for 2.6.36
Hi Dave,
this is the second patch set (qeth + 1 claw) for 2.6.36 (net-next).
shortlog:
Klaus Wacker (1)
qeth: IP address takeover flag setting
Ursula Braun (5)
qeth: serialize sysfs-triggered device configurations
qeth: avoid loop if ipa command response is missing
claw: A claw device is a group of just 2 ccw devices
qeth: return zero from reply callback functions
qeth: avoid useless removal of multicast addresses
Julia Lawall (1)
qeth: Use memdup_user when user data is immediately copied into the allocated region.
Carsten Otte (1)
qeth: Clear mac_bits field when switching between Layer 2 and Layer 3
Thanks,
Frank
PATCH 1/8 qeth: IP address takeover flag setting
From: Klaus-Dieter Wacker <[email protected]>
The qeth IP address flag setting is possible when device is offline. When setting device online afterwards the current set IP addresses have to be correctly registered with the device regarding the IP address takeover attribute.
---
drivers/s390/net/qeth_core.h | 3 +-- drivers/s390/net/qeth_core_main.c | 7 +------ drivers/s390/net/qeth_l3.h | 1 + drivers/s390/net/qeth_l3_main.c | 2 +- drivers/s390/net/qeth_l3_sys.c | 14 ++++++++++++++ 5 files changed, 18 insertions(+), 9 deletions(-)
drivers/s390/net/qeth_core.h +1 -2
@@ -188,8 +188,7 @@ static inline int qeth_is_ipa_enabled(st qeth_is_enabled6(c, f) : qeth_is_enabled(c, f))#define QETH_IDX_FUNC_LEVEL_OSD 0x0101 -#define QETH_IDX_FUNC_LEVEL_IQD_ENA_IPAT 0x4108 -#define QETH_IDX_FUNC_LEVEL_IQD_DIS_IPAT 0x5108 +#define QETH_IDX_FUNC_LEVEL_IQD 0x4108#define QETH_MODELLIST_ARRAY \ {{0x1731, 0x01, 0x1732, QETH_CARD_TYPE_OSD, QETH_MAX_QUEUES, 0}, \
drivers/s390/net/qeth_core_main.c +1 -6
@@ -1383,12 +1383,7 @@ static void qeth_init_func_level(struct {switch (card->info.type) {case QETH_CARD_TYPE_IQD : -if (card->ipato.enabled) - card->info.func_level = -QETH_IDX_FUNC_LEVEL_IQD_ENA_IPAT ; -else - card->info.func_level = -QETH_IDX_FUNC_LEVEL_IQD_DIS_IPAT ; + card->info.func_level =QETH_IDX_FUNC_LEVEL_IQD ;break ;case QETH_CARD_TYPE_OSD :case QETH_CARD_TYPE_OSN :
drivers/s390/net/qeth_l3.h +1 -0
@@ -64,5 +64,6 @@ void qeth_l3_del_rxip(struct qeth_card * const u8 *); int qeth_l3_set_large_send(struct qeth_card *, enum qeth_large_send_types);int qeth_l3_set_rx_csum (struct qeth_card *,enum qeth_checksum_types ); +int qeth_l3_is_addr_covered_by_ipato (struct qeth_card *,struct qeth_ipaddr *);#endif /* __QETH_L3_H__ */
drivers/s390/net/qeth_l3_main.c +1 -1
@@ -195,7 +195,7 @@ static void qeth_l3_convert_addr_to_bits } } -static int qeth_l3_is_addr_covered_by_ipato (struct qeth_card *card, +int qeth_l3_is_addr_covered_by_ipato (struct qeth_card *card,struct qeth_ipaddr *addr) {struct qeth_ipato_entry *ipatoe;
drivers/s390/net/qeth_l3_sys.c +14 -0
@@ -479,6 +479,7 @@ static ssize_t qeth_l3_dev_ipato_enable_ struct device_attribute *attr, const char *buf, size_t count) { struct qeth_card *card = dev_get_drvdata(dev); +struct qeth_ipaddr *tmpipa, *t;char *tmp;int rc =0 ;
@@ -497,8 +498,21 @@ static ssize_t qeth_l3_dev_ipato_enable_ card->ipato.enabled = (card->ipato.enabled)?0 :1 ; }else if (!strcmp (tmp,"1" )) { card->ipato.enabled =1 ; +list_for_each_entry_safe (tmpipa, t, card->ip_tbd_list, entry) { +if ((tmpipa->type ==QETH_IP_TYPE_NORMAL ) && +qeth_l3_is_addr_covered_by_ipato (card, tmpipa)) + tmpipa->set_flags |= +QETH_IPA_SETIP_TAKEOVER_FLAG ; + } + }else if (!strcmp (tmp,"0" )) { card->ipato.enabled =0 ; +list_for_each_entry_safe (tmpipa, t, card->ip_tbd_list, entry) { +if (tmpipa->set_flags & +QETH_IPA_SETIP_TAKEOVER_FLAG ) + tmpipa->set_flags &= + ~QETH_IPA_SETIP_TAKEOVER_FLAG ; + } }else rc = -EINVAL ; out:
PATCH 2/8 qeth: Clear mac_bits field when switching between Layer 2 and Layer 3
In reply to [email protected]From: Carsten Otte <[email protected]>
This patch fixes a problem that occurs when switching from layer 3 to layer 2 mode. Resetting this mac_bits makes sure that we retrieve our mac address from the card, otherwise the interface simply would'nt work.
---
drivers/s390/net/qeth_core_sys.c | 1 + 1 file changed, 1 insertion(+)
drivers/s390/net/qeth_core_sys.c +1 -0
@@ -433,6 +433,7 @@ static ssize_t qeth_dev_layer2_store(strif (card->options.layer2 == newdis) goto out;else { + card->info.mac_bits =0 ;if (card->discipline.ccwgdriver) { card->discipline.ccwgdriver->remove (card->gdev);qeth_core_free_discipline (card);
PATCH 3/8 qeth: serialize sysfs-triggered device configurations
In reply to [email protected]From: Ursula Braun <[email protected]>
This patch serializes device removal and other sysfs-triggered configurations by moving removal of sysfs-attributes to the beginning of the remove functions. And it serializes online/offline setting and discipline-switching (causing reestablishing of the net_device) by making use of a new discipline mutex.
---
drivers/s390/net/qeth_core.h | 1 + drivers/s390/net/qeth_core_main.c | 11 +++++++---- drivers/s390/net/qeth_core_sys.c | 4 ++-- drivers/s390/net/qeth_l2_main.c | 5 +++++ drivers/s390/net/qeth_l3_main.c | 8 +++++++- 5 files changed, 22 insertions(+), 7 deletions(-)
drivers/s390/net/qeth_core.h +1 -0
@@ -747,6 +747,7 @@ struct qeth_card {struct qdio_ssqd_desc ssqd;debug_info_t *debug;struct mutex conf_mutex; +struct mutex discipline_mutex; };struct qeth_card_list_struct {
drivers/s390/net/qeth_core_main.c +7 -4
@@ -1084,6 +1084,7 @@ static int qeth_setup_card(struct qeth_cspin_lock_init (&card->ip_lock);spin_lock_init (&card->thread_mask_lock);mutex_init (&card->conf_mutex); +mutex_init (&card->discipline_mutex); card->thread_start_mask =0 ; card->thread_allowed_mask =0 ; card->thread_running_mask =0 ;
@@ -4348,16 +4349,18 @@ static void qeth_core_remove_device(strustruct qeth_card *card =dev_get_drvdata (&gdev->dev);QETH_DBF_TEXT (SETUP ,2 ,"removedv" ); -if (card->discipline.ccwgdriver) { - card->discipline.ccwgdriver->remove (gdev); -qeth_core_free_discipline (card); - }if (card->info.type ==QETH_CARD_TYPE_OSN ) {qeth_core_remove_osn_attributes (&gdev->dev); }else {qeth_core_remove_device_attributes (&gdev->dev); } + +if (card->discipline.ccwgdriver) { + card->discipline.ccwgdriver->remove (gdev); +qeth_core_free_discipline (card); + } +debug_unregister (card->debug);write_lock_irqsave (&qeth_core_card_list.rwlock, flags);list_del (&card->list);
drivers/s390/net/qeth_core_sys.c +2 -2
@@ -411,7 +411,7 @@ static ssize_t qeth_dev_layer2_store(strif (!card)return -EINVAL ; -mutex_lock (&card->conf_mutex); +mutex_lock (&card->discipline_mutex);if (card->state !=CARD_STATE_DOWN ) { rc = -EPERM ; goto out;
@@ -446,7 +446,7 @@ static ssize_t qeth_dev_layer2_store(str rc = card->discipline.ccwgdriver->probe (card->gdev); out: -mutex_unlock (&card->conf_mutex); +mutex_unlock (&card->discipline_mutex);return rc ? rc : count; }
drivers/s390/net/qeth_l2_main.c +5 -0
@@ -935,6 +935,7 @@ static int __qeth_l2_set_online(struct cenum qeth_card_states recover_flag;BUG_ON (!card); +mutex_lock (&card->discipline_mutex);mutex_lock (&card->conf_mutex);QETH_DBF_TEXT (SETUP ,2 ,"setonlin" );QETH_DBF_HEX (SETUP ,2 , &card,sizeof (void *));
@@ -1012,6 +1013,7 @@ static int __qeth_l2_set_online(struct ckobject_uevent (&gdev->dev.kobj,KOBJ_CHANGE ); out:mutex_unlock (&card->conf_mutex); +mutex_unlock (&card->discipline_mutex);return 0 ; out_remove:
@@ -1025,6 +1027,7 @@ out_remove:else card->state =CARD_STATE_DOWN ;mutex_unlock (&card->conf_mutex); +mutex_unlock (&card->discipline_mutex);return rc; }
@@ -1040,6 +1043,7 @@ static int __qeth_l2_set_offline(structint rc =0 , rc2 =0 , rc3 =0 ;enum qeth_card_states recover_flag; +mutex_lock (&card->discipline_mutex);mutex_lock (&card->conf_mutex);QETH_DBF_TEXT (SETUP ,3 ,"setoffl" );QETH_DBF_HEX (SETUP ,3 , &card,sizeof (void *));
@@ -1060,6 +1064,7 @@ static int __qeth_l2_set_offline(struct/* let user_space know that device is offline */ kobject_uevent (&cgdev->dev.kobj,KOBJ_CHANGE );mutex_unlock (&card->conf_mutex); +mutex_unlock (&card->discipline_mutex);return 0 ; }
drivers/s390/net/qeth_l3_main.c +7 -1
@@ -3354,6 +3354,8 @@ static void qeth_l3_remove_device(struct {struct qeth_card *card =dev_get_drvdata (&cgdev->dev); +qeth_l3_remove_device_attributes (&cgdev->dev); +qeth_set_allowed_threads (card,0 ,1 );wait_event (card->wait_q,qeth_threads_running (card,0xffffffff ) ==0 );
@@ -3367,7 +3369,6 @@ static void qeth_l3_remove_device(struct card->dev =NULL ; } -qeth_l3_remove_device_attributes (&cgdev->dev);qeth_l3_clear_ip_list (card,0 ,0 );qeth_l3_clear_ipato_list (card);return ;
@@ -3380,6 +3381,7 @@ static int __qeth_l3_set_online(struct cenum qeth_card_states recover_flag;BUG_ON (!card); +mutex_lock (&card->discipline_mutex);mutex_lock (&card->conf_mutex);QETH_DBF_TEXT (SETUP ,2 ,"setonlin" );QETH_DBF_HEX (SETUP ,2 , &card,sizeof (void *));
@@ -3461,6 +3463,7 @@ static int __qeth_l3_set_online(struct ckobject_uevent (&gdev->dev.kobj,KOBJ_CHANGE ); out:mutex_unlock (&card->conf_mutex); +mutex_unlock (&card->discipline_mutex);return 0 ; out_remove: card->use_hard_stop =1 ;
@@ -3473,6 +3476,7 @@ out_remove:else card->state =CARD_STATE_DOWN ;mutex_unlock (&card->conf_mutex); +mutex_unlock (&card->discipline_mutex);return rc; }
@@ -3488,6 +3492,7 @@ static int __qeth_l3_set_offline(structint rc =0 , rc2 =0 , rc3 =0 ;enum qeth_card_states recover_flag; +mutex_lock (&card->discipline_mutex);mutex_lock (&card->conf_mutex);QETH_DBF_TEXT (SETUP ,3 ,"setoffl" );QETH_DBF_HEX (SETUP ,3 , &card,sizeof (void *));
@@ -3508,6 +3513,7 @@ static int __qeth_l3_set_offline(struct/* let user_space know that device is offline */ kobject_uevent (&cgdev->dev.kobj,KOBJ_CHANGE );mutex_unlock (&card->conf_mutex); +mutex_unlock (&card->discipline_mutex);return 0 ; }
PATCH 4/8 qeth: avoid loop if ipa command response is missing
In reply to [email protected]From: Ursula Braun <[email protected]>
If qeth issues an ipa command, but for some reasons the response never comes back, qeth reaches a timeout.
Reset the irq_pending flag of the write channel in timeout handling code and trigger a recovery to avoid endless looping for the following ipa command.
---
drivers/s390/net/qeth_core.h | 1 + drivers/s390/net/qeth_core_main.c | 15 +++++++++++++++ 2 files changed, 16 insertions(+)
drivers/s390/net/qeth_core.h +1 -0
@@ -740,6 +740,7 @@ struct qeth_card {struct qeth_qdio_info qdio;struct qeth_perf_stats perf_stats;int use_hard_stop; +int read_or_write_problem;struct qeth_osn_info osn_info;struct qeth_discipline discipline;atomic_t force_alloc_skb;
drivers/s390/net/qeth_core_main.c +15 -0
@@ -262,6 +262,7 @@ static int qeth_issue_next_read(struct qQETH_DBF_MESSAGE (2 ,"%s error in starting next read ccw! " "rc=%i\n" ,dev_name (&card->gdev->dev), rc);atomic_set (&card->read.irq_pending,0 ); + card->read_or_write_problem =1 ;qeth_schedule_recovery (card);wake_up (&card->wait_q); }
@@ -382,6 +383,7 @@ void qeth_clear_ipacmd_list(struct qeth_qeth_put_reply (reply); }spin_unlock_irqrestore (&card->lock, flags); +atomic_set (&card->write.irq_pending,0 ); }EXPORT_SYMBOL_GPL (qeth_clear_ipacmd_list);
@@ -1076,6 +1078,7 @@ static int qeth_setup_card(struct qeth_c card->state =CARD_STATE_DOWN ; card->lan_online =0 ; card->use_hard_stop =0 ; + card->read_or_write_problem =0 ; card->dev =NULL ;spin_lock_init (&card->vlanlock);spin_lock_init (&card->mclock);
@@ -1658,6 +1661,10 @@ int qeth_send_control_data(struct qeth_cQETH_CARD_TEXT (card,2 ,"sendctl" ); +if (card->read_or_write_problem) { +qeth_release_buffer (iob->channel, iob); +return -EIO ; + } reply =qeth_alloc_reply (card);if (!reply) {return -ENOMEM ;
@@ -1729,6 +1736,9 @@ time_err:spin_unlock_irqrestore (&reply->card->lock, flags); reply->rc = -ETIME ;atomic_inc (&reply->received); +atomic_set (&card->write.irq_pending,0 ); +qeth_release_buffer (iob->channel, iob); + card->write.buf_no = (card->write.buf_no +1 ) %QETH_CMD_BUFFER_NO ;wake_up (&reply->wait_q); rc = reply->rc;qeth_put_reply (reply);
@@ -2485,6 +2495,10 @@ int qeth_send_ipa_cmd(struct qeth_card *qeth_prepare_ipa_cmd (card, iob, prot_type); rc =qeth_send_control_data (card,IPA_CMD_LENGTH , iob, reply_cb, reply_param); +if (rc == -ETIME ) { +qeth_clear_ipacmd_list (card); +qeth_schedule_recovery (card); + }return rc; }EXPORT_SYMBOL_GPL (qeth_send_ipa_cmd);
@@ -3967,6 +3981,7 @@ retriable:else goto retry; } + card->read_or_write_problem =0 ; rc =qeth_mpc_initialize (card);if (rc) {QETH_DBF_TEXT_ (SETUP ,2 ,"5err%d" , rc);
PATCH 5/8 claw: A claw device is a group of just 2 ccw devices
In reply to [email protected]From: Ursula Braun <[email protected]>
When creating a claw device, just 2 subchannels have to be grouped.
---
drivers/s390/net/claw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/s390/net/claw.c +1 -1
@@ -295,7 +295,7 @@ claw_driver_group_store(struct device_drint err; err =ccwgroup_create_from_string (claw_root_dev, claw_group_driver.driver_id, - &claw_ccw_driver,3 , buf); + &claw_ccw_driver,2 , buf);return err ? err : count; }
PATCH 6/8 qeth: return zero from reply callback functions
In reply to [email protected]From: Ursula Braun <[email protected]>
Reply callback functions in qeth should return zero if command response consists of one part only, otherwise qeth continues waiting for further parts of the command response.
---
drivers/s390/net/qeth_core_main.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-)
drivers/s390/net/qeth_core_main.c +2 -8
@@ -1996,7 +1996,7 @@ static int qeth_ulp_setup_cb(struct qethQETH_DBF_TEXT (SETUP ,2 ,"olmlimit" );dev_err (&card->gdev->dev,"A connection could not be " "established because of an OLM limit\n" ); - rc = -EMLINK ; + iob->rc = -EMLINK ; }QETH_DBF_TEXT_ (SETUP ,2 ," rc%d" , iob->rc);return rc;
@@ -3423,7 +3423,6 @@ static int qeth_setadpparms_set_access_c {struct qeth_ipa_cmd *cmd;struct qeth_set_access_ctrl *access_ctrl_req; -int rc;QETH_CARD_TEXT (card,4 ,"setaccb" );
@@ -3450,7 +3449,6 @@ static int qeth_setadpparms_set_access_c card->gdev->dev.kobj.name, access_ctrl_req->subcmd_code, cmd->data.setadapterparms.hdr.return_code); - rc =0 ;break ; }case SET_ACCESS_CTRL_RC_NOT_SUPPORTED :
@@ -3464,7 +3462,6 @@ static int qeth_setadpparms_set_access_c/* ensure isolation mode is "none" */ card->options.isolation =ISOLATION_MODE_NONE ; - rc = -EOPNOTSUPP ;break ; }case SET_ACCESS_CTRL_RC_NONE_SHARED_ADAPTER :
@@ -3479,7 +3476,6 @@ static int qeth_setadpparms_set_access_c/* ensure isolation mode is "none" */ card->options.isolation =ISOLATION_MODE_NONE ; - rc = -EOPNOTSUPP ;break ; }case SET_ACCESS_CTRL_RC_ACTIVE_CHECKSUM_OFF :
@@ -3493,7 +3489,6 @@ static int qeth_setadpparms_set_access_c/* ensure isolation mode is "none" */ card->options.isolation =ISOLATION_MODE_NONE ; - rc = -EPERM ;break ; }default :
@@ -3507,12 +3502,11 @@ static int qeth_setadpparms_set_access_c/* ensure isolation mode is "none" */ card->options.isolation =ISOLATION_MODE_NONE ; - rc =0 ;break ; } }qeth_default_setadapterparms_cb (card, reply, (unsigned long ) cmd); -return rc; +return 0 ; } static int qeth_setadpparms_set_access_ctrl(struct qeth_card *card,
PATCH 7/8 qeth: Use memdup_user when user data is immediately copied into the allocated region.
In reply to [email protected]From: Julia Lawall <[email protected]>
The semantic patch that makes this change is as follows:
(http://coccinelle.lip6.fr/)
// <smpl>
@@
expression from,to,size,flag;
position p;
identifier l1,l2;
@@
- to = \(kmalloc@p\|kzalloc@p\)(size,flag);
+ to = memdup_user(from,size);
if (
- to==NULL
+ IS_ERR(to)
|| ...) { <+... when != goto l1;
- -ENOMEM
+ PTR_ERR(to)
...+>
}
- if (copy_from_user(to, from, size) != 0) {
- <+... when != goto l2; - -EFAULT - ...+>
- }
// </smpl>
---
drivers/s390/net/qeth_core_main.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-)
drivers/s390/net/qeth_core_main.c +3 -8
@@ -3748,15 +3748,10 @@ int qeth_snmp_command(struct qeth_card */* skip 4 bytes (data_len struct member) to get req_len */ if (copy_from_user (&req_len, udata +sizeof (int ),sizeof (int )))return -EFAULT ; - ureq =kmalloc (req_len+sizeof (struct qeth_snmp_ureq_hdr ),GFP_KERNEL ); -if (!ureq) { + ureq =memdup_user (udata, req_len +sizeof (struct qeth_snmp_ureq_hdr )); +if (IS_ERR (ureq)) {QETH_CARD_TEXT (card,2 ,"snmpnome" ); -return -ENOMEM ; - } -if (copy_from_user (ureq, udata, - req_len +sizeof (struct qeth_snmp_ureq_hdr ))) { -kfree (ureq); -return -EFAULT ; +return PTR_ERR (ureq); } qinfo.udata_len = ureq->hdr.data_len; qinfo.udata =kzalloc (qinfo.udata_len,GFP_KERNEL );
PATCH 8/8 qeth: avoid useless removal of multicast addresses
In reply to [email protected]From: Ursula Braun <[email protected]>
Function qeth_l2_remove_device invokes qeth_l2_del_all_mc at the end. This is needless, because it is already called in the offline function. And even more this is invalid, because multicast addresses cannot be removed in DOWN state. Thus this patch deletes invocation of qeth_l2_del_all_mc in function qeth_l2_remove_device.
---
drivers/s390/net/qeth_l2_main.c | 2 -- 1 file changed, 2 deletions(-)
drivers/s390/net/qeth_l2_main.c +0 -2
@@ -860,8 +860,6 @@ static void qeth_l2_remove_device(structunregister_netdev (card->dev); card->dev =NULL ; } - -qeth_l2_del_all_mc (card);return ; }
David Miller
maintainerFrom: [email protected]
Date: Fri, 23 Jul 2010 11:15:02 +0200
Quoted 1 line
this is the second patch set (qeth + 1 claw) for 2.6.36 (net-next).
All applied to net-next-2.6, thanks.