aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390
diff options
context:
space:
mode:
authorUrsula Braun <ursula.braun@de.ibm.com>2011-02-02 01:04:34 -0500
committerDavid S. Miller <davem@davemloft.net>2011-02-02 18:00:01 -0500
commitd0ff1f52361d714863c49abb721a8714ea4e76d6 (patch)
treea7fe4ddcb49a0b38d0cbf713664df5f4c19d73cd /drivers/s390
parent8b2e18f662939fb3d9b0ffe5da953ba56d259e3a (diff)
qeth: allow OSA CHPARM change in suspend state
For OSA the CHPARM-definition determines the number of available outbound queues. A CHPARM-change may occur while a Linux system with probed OSA device is in suspend state. This patch enables proper resuming of an OSA device in this case. Signed-off-by: Ursula braun <ursula.braun@de.ibm.com> Signed-off-by: Frank Blaschka <frank.blaschka@de.ibm.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/s390')
-rw-r--r--drivers/s390/net/qeth_core_main.c104
1 files changed, 63 insertions, 41 deletions
diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c
index eca3e094031a..019ae58ab913 100644
--- a/drivers/s390/net/qeth_core_main.c
+++ b/drivers/s390/net/qeth_core_main.c
@@ -988,16 +988,30 @@ static void qeth_get_channel_path_desc(struct qeth_card *card)
988 chp_dsc = (struct channelPath_dsc *)ccw_device_get_chp_desc(ccwdev, 0); 988 chp_dsc = (struct channelPath_dsc *)ccw_device_get_chp_desc(ccwdev, 0);
989 if (chp_dsc != NULL) { 989 if (chp_dsc != NULL) {
990 /* CHPP field bit 6 == 1 -> single queue */ 990 /* CHPP field bit 6 == 1 -> single queue */
991 if ((chp_dsc->chpp & 0x02) == 0x02) 991 if ((chp_dsc->chpp & 0x02) == 0x02) {
992 if ((atomic_read(&card->qdio.state) !=
993 QETH_QDIO_UNINITIALIZED) &&
994 (card->qdio.no_out_queues == 4))
995 /* change from 4 to 1 outbound queues */
996 qeth_free_qdio_buffers(card);
992 card->qdio.no_out_queues = 1; 997 card->qdio.no_out_queues = 1;
998 if (card->qdio.default_out_queue != 0)
999 dev_info(&card->gdev->dev,
1000 "Priority Queueing not supported\n");
1001 card->qdio.default_out_queue = 0;
1002 } else {
1003 if ((atomic_read(&card->qdio.state) !=
1004 QETH_QDIO_UNINITIALIZED) &&
1005 (card->qdio.no_out_queues == 1)) {
1006 /* change from 1 to 4 outbound queues */
1007 qeth_free_qdio_buffers(card);
1008 card->qdio.default_out_queue = 2;
1009 }
1010 card->qdio.no_out_queues = 4;
1011 }
993 card->info.func_level = 0x4100 + chp_dsc->desc; 1012 card->info.func_level = 0x4100 + chp_dsc->desc;
994 kfree(chp_dsc); 1013 kfree(chp_dsc);
995 } 1014 }
996 if (card->qdio.no_out_queues == 1) {
997 card->qdio.default_out_queue = 0;
998 dev_info(&card->gdev->dev,
999 "Priority Queueing not supported\n");
1000 }
1001 QETH_DBF_TEXT_(SETUP, 2, "nr:%x", card->qdio.no_out_queues); 1015 QETH_DBF_TEXT_(SETUP, 2, "nr:%x", card->qdio.no_out_queues);
1002 QETH_DBF_TEXT_(SETUP, 2, "lvl:%02x", card->info.func_level); 1016 QETH_DBF_TEXT_(SETUP, 2, "lvl:%02x", card->info.func_level);
1003 return; 1017 return;
@@ -3756,6 +3770,47 @@ static inline int qeth_get_qdio_q_format(struct qeth_card *card)
3756 } 3770 }
3757} 3771}
3758 3772
3773static void qeth_determine_capabilities(struct qeth_card *card)
3774{
3775 int rc;
3776 int length;
3777 char *prcd;
3778 struct ccw_device *ddev;
3779 int ddev_offline = 0;
3780
3781 QETH_DBF_TEXT(SETUP, 2, "detcapab");
3782 ddev = CARD_DDEV(card);
3783 if (!ddev->online) {
3784 ddev_offline = 1;
3785 rc = ccw_device_set_online(ddev);
3786 if (rc) {
3787 QETH_DBF_TEXT_(SETUP, 2, "3err%d", rc);
3788 goto out;
3789 }
3790 }
3791
3792 rc = qeth_read_conf_data(card, (void **) &prcd, &length);
3793 if (rc) {
3794 QETH_DBF_MESSAGE(2, "%s qeth_read_conf_data returned %i\n",
3795 dev_name(&card->gdev->dev), rc);
3796 QETH_DBF_TEXT_(SETUP, 2, "5err%d", rc);
3797 goto out_offline;
3798 }
3799 qeth_configure_unitaddr(card, prcd);
3800 qeth_configure_blkt_default(card, prcd);
3801 kfree(prcd);
3802
3803 rc = qdio_get_ssqd_desc(ddev, &card->ssqd);
3804 if (rc)
3805 QETH_DBF_TEXT_(SETUP, 2, "6err%d", rc);
3806
3807out_offline:
3808 if (ddev_offline == 1)
3809 ccw_device_set_offline(ddev);
3810out:
3811 return;
3812}
3813
3759static int qeth_qdio_establish(struct qeth_card *card) 3814static int qeth_qdio_establish(struct qeth_card *card)
3760{ 3815{
3761 struct qdio_initialize init_data; 3816 struct qdio_initialize init_data;
@@ -3886,6 +3941,7 @@ int qeth_core_hardsetup_card(struct qeth_card *card)
3886 3941
3887 QETH_DBF_TEXT(SETUP, 2, "hrdsetup"); 3942 QETH_DBF_TEXT(SETUP, 2, "hrdsetup");
3888 atomic_set(&card->force_alloc_skb, 0); 3943 atomic_set(&card->force_alloc_skb, 0);
3944 qeth_get_channel_path_desc(card);
3889retry: 3945retry:
3890 if (retries) 3946 if (retries)
3891 QETH_DBF_MESSAGE(2, "%s Retrying to do IDX activates.\n", 3947 QETH_DBF_MESSAGE(2, "%s Retrying to do IDX activates.\n",
@@ -3914,6 +3970,7 @@ retriable:
3914 else 3970 else
3915 goto retry; 3971 goto retry;
3916 } 3972 }
3973 qeth_determine_capabilities(card);
3917 qeth_init_tokens(card); 3974 qeth_init_tokens(card);
3918 qeth_init_func_level(card); 3975 qeth_init_func_level(card);
3919 rc = qeth_idx_activate_channel(&card->read, qeth_idx_read_cb); 3976 rc = qeth_idx_activate_channel(&card->read, qeth_idx_read_cb);
@@ -4183,41 +4240,6 @@ void qeth_core_free_discipline(struct qeth_card *card)
4183 card->discipline.ccwgdriver = NULL; 4240 card->discipline.ccwgdriver = NULL;
4184} 4241}
4185 4242
4186static void qeth_determine_capabilities(struct qeth_card *card)
4187{
4188 int rc;
4189 int length;
4190 char *prcd;
4191
4192 QETH_DBF_TEXT(SETUP, 2, "detcapab");
4193 rc = ccw_device_set_online(CARD_DDEV(card));
4194 if (rc) {
4195 QETH_DBF_TEXT_(SETUP, 2, "3err%d", rc);
4196 goto out;
4197 }
4198
4199
4200 rc = qeth_read_conf_data(card, (void **) &prcd, &length);
4201 if (rc) {
4202 QETH_DBF_MESSAGE(2, "%s qeth_read_conf_data returned %i\n",
4203 dev_name(&card->gdev->dev), rc);
4204 QETH_DBF_TEXT_(SETUP, 2, "5err%d", rc);
4205 goto out_offline;
4206 }
4207 qeth_configure_unitaddr(card, prcd);
4208 qeth_configure_blkt_default(card, prcd);
4209 kfree(prcd);
4210
4211 rc = qdio_get_ssqd_desc(CARD_DDEV(card), &card->ssqd);
4212 if (rc)
4213 QETH_DBF_TEXT_(SETUP, 2, "6err%d", rc);
4214
4215out_offline:
4216 ccw_device_set_offline(CARD_DDEV(card));
4217out:
4218 return;
4219}
4220
4221static int qeth_core_probe_device(struct ccwgroup_device *gdev) 4243static int qeth_core_probe_device(struct ccwgroup_device *gdev)
4222{ 4244{
4223 struct qeth_card *card; 4245 struct qeth_card *card;