diff options
author | James Morris <jmorris@namei.org> | 2011-03-08 10:55:06 +1100 |
---|---|---|
committer | James Morris <jmorris@namei.org> | 2011-03-08 10:55:06 +1100 |
commit | 1cc26bada9f6807814806db2f0d78792eecdac71 (patch) | |
tree | 5509b5139db04af6c13db0a580c84116a4a54039 /drivers/s390 | |
parent | eae61f3c829439f8f9121b5cd48a14be04df451f (diff) | |
parent | 214d93b02c4fe93638ad268613c9702a81ed9192 (diff) |
Merge branch 'master'; commit 'v2.6.38-rc7' into next
Diffstat (limited to 'drivers/s390')
-rw-r--r-- | drivers/s390/block/dasd_alias.c | 6 | ||||
-rw-r--r-- | drivers/s390/block/dasd_eckd.c | 2 | ||||
-rw-r--r-- | drivers/s390/block/dasd_genhd.c | 2 | ||||
-rw-r--r-- | drivers/s390/block/xpram.c | 4 | ||||
-rw-r--r-- | drivers/s390/char/keyboard.c | 3 | ||||
-rw-r--r-- | drivers/s390/char/tape.h | 8 | ||||
-rw-r--r-- | drivers/s390/char/tape_34xx.c | 59 | ||||
-rw-r--r-- | drivers/s390/char/tape_3590.c | 83 | ||||
-rw-r--r-- | drivers/s390/char/tape_class.h | 1 | ||||
-rw-r--r-- | drivers/s390/cio/device.c | 1 | ||||
-rw-r--r-- | drivers/s390/cio/qdio_main.c | 4 | ||||
-rw-r--r-- | drivers/s390/net/lcs.c | 2 | ||||
-rw-r--r-- | drivers/s390/net/netiucv.c | 2 | ||||
-rw-r--r-- | drivers/s390/net/qeth_core_main.c | 149 | ||||
-rw-r--r-- | drivers/s390/net/qeth_l2_main.c | 22 | ||||
-rw-r--r-- | drivers/s390/net/qeth_l3_main.c | 22 | ||||
-rw-r--r-- | drivers/s390/net/smsgiucv.c | 2 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_cfdc.c | 2 |
18 files changed, 248 insertions, 126 deletions
diff --git a/drivers/s390/block/dasd_alias.c b/drivers/s390/block/dasd_alias.c index 4155805dcdff..2b771f18d1ad 100644 --- a/drivers/s390/block/dasd_alias.c +++ b/drivers/s390/block/dasd_alias.c @@ -319,6 +319,9 @@ void dasd_alias_disconnect_device_from_lcu(struct dasd_device *device) private = (struct dasd_eckd_private *) device->private; lcu = private->lcu; + /* nothing to do if already disconnected */ + if (!lcu) + return; device->discipline->get_uid(device, &uid); spin_lock_irqsave(&lcu->lock, flags); list_del_init(&device->alias_list); @@ -680,6 +683,9 @@ int dasd_alias_remove_device(struct dasd_device *device) private = (struct dasd_eckd_private *) device->private; lcu = private->lcu; + /* nothing to do if already removed */ + if (!lcu) + return 0; spin_lock_irqsave(&lcu->lock, flags); _remove_device_from_lcu(lcu, device); spin_unlock_irqrestore(&lcu->lock, flags); diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c index 318672d05563..a9fe23d5bd0f 100644 --- a/drivers/s390/block/dasd_eckd.c +++ b/drivers/s390/block/dasd_eckd.c @@ -72,7 +72,7 @@ static struct dasd_discipline dasd_eckd_discipline; static struct ccw_device_id dasd_eckd_ids[] = { { CCW_DEVICE_DEVTYPE (0x3990, 0, 0x3390, 0), .driver_info = 0x1}, { CCW_DEVICE_DEVTYPE (0x2105, 0, 0x3390, 0), .driver_info = 0x2}, - { CCW_DEVICE_DEVTYPE (0x3880, 0, 0x3390, 0), .driver_info = 0x3}, + { CCW_DEVICE_DEVTYPE (0x3880, 0, 0x3380, 0), .driver_info = 0x3}, { CCW_DEVICE_DEVTYPE (0x3990, 0, 0x3380, 0), .driver_info = 0x4}, { CCW_DEVICE_DEVTYPE (0x2105, 0, 0x3380, 0), .driver_info = 0x5}, { CCW_DEVICE_DEVTYPE (0x9343, 0, 0x9345, 0), .driver_info = 0x6}, diff --git a/drivers/s390/block/dasd_genhd.c b/drivers/s390/block/dasd_genhd.c index 30a1ca3d08b7..5505bc07e1e7 100644 --- a/drivers/s390/block/dasd_genhd.c +++ b/drivers/s390/block/dasd_genhd.c @@ -103,7 +103,7 @@ int dasd_scan_partitions(struct dasd_block *block) struct block_device *bdev; bdev = bdget_disk(block->gdp, 0); - if (!bdev || blkdev_get(bdev, FMODE_READ) < 0) + if (!bdev || blkdev_get(bdev, FMODE_READ, NULL) < 0) return -ENODEV; /* * See fs/partition/check.c:register_disk,rescan_partitions diff --git a/drivers/s390/block/xpram.c b/drivers/s390/block/xpram.c index c881a14fa5dd..1f6a4d894e73 100644 --- a/drivers/s390/block/xpram.c +++ b/drivers/s390/block/xpram.c @@ -62,8 +62,8 @@ static int xpram_devs; /* * Parameter parsing functions. */ -static int __initdata devs = XPRAM_DEVS; -static char __initdata *sizes[XPRAM_MAX_DEVS]; +static int devs = XPRAM_DEVS; +static char *sizes[XPRAM_MAX_DEVS]; module_param(devs, int, 0); module_param_array(sizes, charp, NULL, 0); diff --git a/drivers/s390/char/keyboard.c b/drivers/s390/char/keyboard.c index 8cd58e412b5e..5ad44daef73b 100644 --- a/drivers/s390/char/keyboard.c +++ b/drivers/s390/char/keyboard.c @@ -460,7 +460,8 @@ kbd_ioctl(struct kbd_data *kbd, struct file *file, unsigned int cmd, unsigned long arg) { void __user *argp; - int ct, perm; + unsigned int ct; + int perm; argp = (void __user *)arg; diff --git a/drivers/s390/char/tape.h b/drivers/s390/char/tape.h index 7a242f073632..267b54e8ff5a 100644 --- a/drivers/s390/char/tape.h +++ b/drivers/s390/char/tape.h @@ -280,6 +280,14 @@ tape_do_io_free(struct tape_device *device, struct tape_request *request) return rc; } +static inline void +tape_do_io_async_free(struct tape_device *device, struct tape_request *request) +{ + request->callback = (void *) tape_free_request; + request->callback_data = NULL; + tape_do_io_async(device, request); +} + extern int tape_oper_handler(int irq, int status); extern void tape_noper_handler(int irq, int status); extern int tape_open(struct tape_device *); diff --git a/drivers/s390/char/tape_34xx.c b/drivers/s390/char/tape_34xx.c index c17f35b6136a..c26511171ffe 100644 --- a/drivers/s390/char/tape_34xx.c +++ b/drivers/s390/char/tape_34xx.c @@ -53,23 +53,11 @@ static void tape_34xx_delete_sbid_from(struct tape_device *, int); * Medium sense for 34xx tapes. There is no 'real' medium sense call. * So we just do a normal sense. */ -static int -tape_34xx_medium_sense(struct tape_device *device) +static void __tape_34xx_medium_sense(struct tape_request *request) { - struct tape_request *request; - unsigned char *sense; - int rc; - - request = tape_alloc_request(1, 32); - if (IS_ERR(request)) { - DBF_EXCEPTION(6, "MSEN fail\n"); - return PTR_ERR(request); - } - - request->op = TO_MSEN; - tape_ccw_end(request->cpaddr, SENSE, 32, request->cpdata); + struct tape_device *device = request->device; + unsigned char *sense; - rc = tape_do_io_interruptible(device, request); if (request->rc == 0) { sense = request->cpdata; @@ -88,15 +76,47 @@ tape_34xx_medium_sense(struct tape_device *device) device->tape_generic_status |= GMT_WR_PROT(~0); else device->tape_generic_status &= ~GMT_WR_PROT(~0); - } else { + } else DBF_EVENT(4, "tape_34xx: medium sense failed with rc=%d\n", request->rc); - } tape_free_request(request); +} + +static int tape_34xx_medium_sense(struct tape_device *device) +{ + struct tape_request *request; + int rc; + + request = tape_alloc_request(1, 32); + if (IS_ERR(request)) { + DBF_EXCEPTION(6, "MSEN fail\n"); + return PTR_ERR(request); + } + request->op = TO_MSEN; + tape_ccw_end(request->cpaddr, SENSE, 32, request->cpdata); + rc = tape_do_io_interruptible(device, request); + __tape_34xx_medium_sense(request); return rc; } +static void tape_34xx_medium_sense_async(struct tape_device *device) +{ + struct tape_request *request; + + request = tape_alloc_request(1, 32); + if (IS_ERR(request)) { + DBF_EXCEPTION(6, "MSEN fail\n"); + return; + } + + request->op = TO_MSEN; + tape_ccw_end(request->cpaddr, SENSE, 32, request->cpdata); + request->callback = (void *) __tape_34xx_medium_sense; + request->callback_data = NULL; + tape_do_io_async(device, request); +} + struct tape_34xx_work { struct tape_device *device; enum tape_op op; @@ -109,6 +129,9 @@ struct tape_34xx_work { * is inserted but cannot call tape_do_io* from an interrupt context. * Maybe that's useful for other actions we want to start from the * interrupt handler. + * Note: the work handler is called by the system work queue. The tape + * commands started by the handler need to be asynchrounous, otherwise + * a deadlock can occur e.g. in case of a deferred cc=1 (see __tape_do_irq). */ static void tape_34xx_work_handler(struct work_struct *work) @@ -119,7 +142,7 @@ tape_34xx_work_handler(struct work_struct *work) switch(p->op) { case TO_MSEN: - tape_34xx_medium_sense(device); + tape_34xx_medium_sense_async(device); break; default: DBF_EVENT(3, "T34XX: internal error: unknown work\n"); diff --git a/drivers/s390/char/tape_3590.c b/drivers/s390/char/tape_3590.c index fbe361fcd2c0..de2e99e0a71b 100644 --- a/drivers/s390/char/tape_3590.c +++ b/drivers/s390/char/tape_3590.c @@ -329,17 +329,17 @@ out: /* * Enable encryption */ -static int tape_3592_enable_crypt(struct tape_device *device) +static struct tape_request *__tape_3592_enable_crypt(struct tape_device *device) { struct tape_request *request; char *data; DBF_EVENT(6, "tape_3592_enable_crypt\n"); if (!crypt_supported(device)) - return -ENOSYS; + return ERR_PTR(-ENOSYS); request = tape_alloc_request(2, 72); if (IS_ERR(request)) - return PTR_ERR(request); + return request; data = request->cpdata; memset(data,0,72); @@ -354,23 +354,42 @@ static int tape_3592_enable_crypt(struct tape_device *device) request->op = TO_CRYPT_ON; tape_ccw_cc(request->cpaddr, MODE_SET_CB, 36, data); tape_ccw_end(request->cpaddr + 1, MODE_SET_CB, 36, data + 36); + return request; +} + +static int tape_3592_enable_crypt(struct tape_device *device) +{ + struct tape_request *request; + + request = __tape_3592_enable_crypt(device); + if (IS_ERR(request)) + return PTR_ERR(request); return tape_do_io_free(device, request); } +static void tape_3592_enable_crypt_async(struct tape_device *device) +{ + struct tape_request *request; + + request = __tape_3592_enable_crypt(device); + if (!IS_ERR(request)) + tape_do_io_async_free(device, request); +} + /* * Disable encryption */ -static int tape_3592_disable_crypt(struct tape_device *device) +static struct tape_request *__tape_3592_disable_crypt(struct tape_device *device) { struct tape_request *request; char *data; DBF_EVENT(6, "tape_3592_disable_crypt\n"); if (!crypt_supported(device)) - return -ENOSYS; + return ERR_PTR(-ENOSYS); request = tape_alloc_request(2, 72); if (IS_ERR(request)) - return PTR_ERR(request); + return request; data = request->cpdata; memset(data,0,72); @@ -383,9 +402,28 @@ static int tape_3592_disable_crypt(struct tape_device *device) tape_ccw_cc(request->cpaddr, MODE_SET_CB, 36, data); tape_ccw_end(request->cpaddr + 1, MODE_SET_CB, 36, data + 36); + return request; +} + +static int tape_3592_disable_crypt(struct tape_device *device) +{ + struct tape_request *request; + + request = __tape_3592_disable_crypt(device); + if (IS_ERR(request)) + return PTR_ERR(request); return tape_do_io_free(device, request); } +static void tape_3592_disable_crypt_async(struct tape_device *device) +{ + struct tape_request *request; + + request = __tape_3592_disable_crypt(device); + if (!IS_ERR(request)) + tape_do_io_async_free(device, request); +} + /* * IOCTL: Set encryption status */ @@ -457,8 +495,7 @@ tape_3590_ioctl(struct tape_device *device, unsigned int cmd, unsigned long arg) /* * SENSE Medium: Get Sense data about medium state */ -static int -tape_3590_sense_medium(struct tape_device *device) +static int tape_3590_sense_medium(struct tape_device *device) { struct tape_request *request; @@ -470,6 +507,18 @@ tape_3590_sense_medium(struct tape_device *device) return tape_do_io_free(device, request); } +static void tape_3590_sense_medium_async(struct tape_device *device) +{ + struct tape_request *request; + + request = tape_alloc_request(1, 128); + if (IS_ERR(request)) + return; + request->op = TO_MSEN; + tape_ccw_end(request->cpaddr, MEDIUM_SENSE, 128, request->cpdata); + tape_do_io_async_free(device, request); +} + /* * MTTELL: Tell block. Return the number of block relative to current file. */ @@ -546,15 +595,14 @@ tape_3590_read_opposite(struct tape_device *device, * 2. The attention msg is written to the "read subsystem data" buffer. * In this case we probably should print it to the console. */ -static int -tape_3590_read_attmsg(struct tape_device *device) +static void tape_3590_read_attmsg_async(struct tape_device *device) { struct tape_request *request; char *buf; request = tape_alloc_request(3, 4096); if (IS_ERR(request)) - return PTR_ERR(request); + return; request->op = TO_READ_ATTMSG; buf = request->cpdata; buf[0] = PREP_RD_SS_DATA; @@ -562,12 +610,15 @@ tape_3590_read_attmsg(struct tape_device *device) tape_ccw_cc(request->cpaddr, PERFORM_SS_FUNC, 12, buf); tape_ccw_cc(request->cpaddr + 1, READ_SS_DATA, 4096 - 12, buf + 12); tape_ccw_end(request->cpaddr + 2, NOP, 0, NULL); - return tape_do_io_free(device, request); + tape_do_io_async_free(device, request); } /* * These functions are used to schedule follow-up actions from within an * interrupt context (like unsolicited interrupts). + * Note: the work handler is called by the system work queue. The tape + * commands started by the handler need to be asynchrounous, otherwise + * a deadlock can occur e.g. in case of a deferred cc=1 (see __tape_do_irq). */ struct work_handler_data { struct tape_device *device; @@ -583,16 +634,16 @@ tape_3590_work_handler(struct work_struct *work) switch (p->op) { case TO_MSEN: - tape_3590_sense_medium(p->device); + tape_3590_sense_medium_async(p->device); break; case TO_READ_ATTMSG: - tape_3590_read_attmsg(p->device); + tape_3590_read_attmsg_async(p->device); break; case TO_CRYPT_ON: - tape_3592_enable_crypt(p->device); + tape_3592_enable_crypt_async(p->device); break; case TO_CRYPT_OFF: - tape_3592_disable_crypt(p->device); + tape_3592_disable_crypt_async(p->device); break; default: DBF_EVENT(3, "T3590: work handler undefined for " diff --git a/drivers/s390/char/tape_class.h b/drivers/s390/char/tape_class.h index 707b7f48c232..9e32780c317f 100644 --- a/drivers/s390/char/tape_class.h +++ b/drivers/s390/char/tape_class.h @@ -14,7 +14,6 @@ #include <linux/module.h> #include <linux/fs.h> #include <linux/major.h> -#include <linux/kobject.h> #include <linux/kobj_map.h> #include <linux/cdev.h> diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c index e8391b89eff4..b7eaff9ca19e 100644 --- a/drivers/s390/cio/device.c +++ b/drivers/s390/cio/device.c @@ -1835,6 +1835,7 @@ static void __ccw_device_pm_restore(struct ccw_device *cdev) * available again. Kick re-detection. */ cdev->private->flags.resuming = 1; + cdev->private->path_new_mask = LPM_ANYPATH; css_schedule_eval(sch->schid); spin_unlock_irq(sch->lock); css_complete_work(); diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c index e9fff2b9bce2..5640c89cd9de 100644 --- a/drivers/s390/cio/qdio_main.c +++ b/drivers/s390/cio/qdio_main.c @@ -476,7 +476,7 @@ static inline void inbound_primed(struct qdio_q *q, int count) static int get_inbound_buffer_frontier(struct qdio_q *q) { int count, stop; - unsigned char state; + unsigned char state = 0; /* * Don't check 128 buffers, as otherwise qdio_inbound_q_moved @@ -643,7 +643,7 @@ void qdio_inbound_processing(unsigned long data) static int get_outbound_buffer_frontier(struct qdio_q *q) { int count, stop; - unsigned char state; + unsigned char state = 0; if (need_siga_sync(q)) if (((queue_type(q) != QDIO_IQDIO_QFMT) && diff --git a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c index 09e7a053c844..30b2a820e670 100644 --- a/drivers/s390/net/lcs.c +++ b/drivers/s390/net/lcs.c @@ -841,7 +841,7 @@ lcs_notify_lancmd_waiters(struct lcs_card *card, struct lcs_cmd *cmd) } /** - * Emit buffer of a lan comand. + * Emit buffer of a lan command. */ static void lcs_lancmd_timeout(unsigned long data) diff --git a/drivers/s390/net/netiucv.c b/drivers/s390/net/netiucv.c index 65ebee0a3266..b6a6356d09b3 100644 --- a/drivers/s390/net/netiucv.c +++ b/drivers/s390/net/netiucv.c @@ -565,7 +565,7 @@ static int netiucv_callback_connreq(struct iucv_path *path, struct iucv_event ev; int rc; - if (memcmp(iucvMagic, ipuser, sizeof(ipuser))) + if (memcmp(iucvMagic, ipuser, 16)) /* ipuser must match iucvMagic. */ return -EINVAL; rc = -EINVAL; diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index 29f848bfc12f..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) chp_dsc = (struct channelPath_dsc *)ccw_device_get_chp_desc(ccwdev, 0); if (chp_dsc != NULL) { /* CHPP field bit 6 == 1 -> single queue */ - if ((chp_dsc->chpp & 0x02) == 0x02) + if ((chp_dsc->chpp & 0x02) == 0x02) { + if ((atomic_read(&card->qdio.state) != + QETH_QDIO_UNINITIALIZED) && + (card->qdio.no_out_queues == 4)) + /* change from 4 to 1 outbound queues */ + qeth_free_qdio_buffers(card); card->qdio.no_out_queues = 1; + if (card->qdio.default_out_queue != 0) + dev_info(&card->gdev->dev, + "Priority Queueing not supported\n"); + card->qdio.default_out_queue = 0; + } else { + if ((atomic_read(&card->qdio.state) != + QETH_QDIO_UNINITIALIZED) && + (card->qdio.no_out_queues == 1)) { + /* change from 1 to 4 outbound queues */ + qeth_free_qdio_buffers(card); + card->qdio.default_out_queue = 2; + } + card->qdio.no_out_queues = 4; + } card->info.func_level = 0x4100 + chp_dsc->desc; kfree(chp_dsc); } - if (card->qdio.no_out_queues == 1) { - card->qdio.default_out_queue = 0; - dev_info(&card->gdev->dev, - "Priority Queueing not supported\n"); - } QETH_DBF_TEXT_(SETUP, 2, "nr:%x", card->qdio.no_out_queues); QETH_DBF_TEXT_(SETUP, 2, "lvl:%02x", card->info.func_level); return; @@ -1832,33 +1846,6 @@ static inline int qeth_get_initial_mtu_for_card(struct qeth_card *card) } } -static inline int qeth_get_max_mtu_for_card(int cardtype) -{ - switch (cardtype) { - - case QETH_CARD_TYPE_UNKNOWN: - case QETH_CARD_TYPE_OSD: - case QETH_CARD_TYPE_OSN: - case QETH_CARD_TYPE_OSM: - case QETH_CARD_TYPE_OSX: - return 61440; - case QETH_CARD_TYPE_IQD: - return 57344; - default: - return 1500; - } -} - -static inline int qeth_get_mtu_out_of_mpc(int cardtype) -{ - switch (cardtype) { - case QETH_CARD_TYPE_IQD: - return 1; - default: - return 0; - } -} - static inline int qeth_get_mtu_outof_framesize(int framesize) { switch (framesize) { @@ -1881,10 +1868,9 @@ static inline int qeth_mtu_is_valid(struct qeth_card *card, int mtu) case QETH_CARD_TYPE_OSD: case QETH_CARD_TYPE_OSM: case QETH_CARD_TYPE_OSX: - return ((mtu >= 576) && (mtu <= 61440)); case QETH_CARD_TYPE_IQD: return ((mtu >= 576) && - (mtu <= card->info.max_mtu + 4096 - 32)); + (mtu <= card->info.max_mtu)); case QETH_CARD_TYPE_OSN: case QETH_CARD_TYPE_UNKNOWN: default: @@ -1907,7 +1893,7 @@ static int qeth_ulp_enable_cb(struct qeth_card *card, struct qeth_reply *reply, memcpy(&card->token.ulp_filter_r, QETH_ULP_ENABLE_RESP_FILTER_TOKEN(iob->data), QETH_MPC_TOKEN_LENGTH); - if (qeth_get_mtu_out_of_mpc(card->info.type)) { + if (card->info.type == QETH_CARD_TYPE_IQD) { memcpy(&framesize, QETH_ULP_ENABLE_RESP_MAX_MTU(iob->data), 2); mtu = qeth_get_mtu_outof_framesize(framesize); if (!mtu) { @@ -1915,12 +1901,21 @@ static int qeth_ulp_enable_cb(struct qeth_card *card, struct qeth_reply *reply, QETH_DBF_TEXT_(SETUP, 2, " rc%d", iob->rc); return 0; } - card->info.max_mtu = mtu; + if (card->info.initial_mtu && (card->info.initial_mtu != mtu)) { + /* frame size has changed */ + if (card->dev && + ((card->dev->mtu == card->info.initial_mtu) || + (card->dev->mtu > mtu))) + card->dev->mtu = mtu; + qeth_free_qdio_buffers(card); + } card->info.initial_mtu = mtu; + card->info.max_mtu = mtu; card->qdio.in_buf_size = mtu + 2 * PAGE_SIZE; } else { card->info.initial_mtu = qeth_get_initial_mtu_for_card(card); - card->info.max_mtu = qeth_get_max_mtu_for_card(card->info.type); + card->info.max_mtu = *(__u16 *)QETH_ULP_ENABLE_RESP_MAX_MTU( + iob->data); card->qdio.in_buf_size = QETH_IN_BUF_SIZE_DEFAULT; } @@ -3775,6 +3770,47 @@ static inline int qeth_get_qdio_q_format(struct qeth_card *card) } } +static void qeth_determine_capabilities(struct qeth_card *card) +{ + int rc; + int length; + char *prcd; + struct ccw_device *ddev; + int ddev_offline = 0; + + QETH_DBF_TEXT(SETUP, 2, "detcapab"); + ddev = CARD_DDEV(card); + if (!ddev->online) { + ddev_offline = 1; + rc = ccw_device_set_online(ddev); + if (rc) { + QETH_DBF_TEXT_(SETUP, 2, "3err%d", rc); + goto out; + } + } + + rc = qeth_read_conf_data(card, (void **) &prcd, &length); + if (rc) { + QETH_DBF_MESSAGE(2, "%s qeth_read_conf_data returned %i\n", + dev_name(&card->gdev->dev), rc); + QETH_DBF_TEXT_(SETUP, 2, "5err%d", rc); + goto out_offline; + } + qeth_configure_unitaddr(card, prcd); + qeth_configure_blkt_default(card, prcd); + kfree(prcd); + + rc = qdio_get_ssqd_desc(ddev, &card->ssqd); + if (rc) + QETH_DBF_TEXT_(SETUP, 2, "6err%d", rc); + +out_offline: + if (ddev_offline == 1) + ccw_device_set_offline(ddev); +out: + return; +} + static int qeth_qdio_establish(struct qeth_card *card) { struct qdio_initialize init_data; @@ -3905,6 +3941,7 @@ int qeth_core_hardsetup_card(struct qeth_card *card) QETH_DBF_TEXT(SETUP, 2, "hrdsetup"); atomic_set(&card->force_alloc_skb, 0); + qeth_get_channel_path_desc(card); retry: if (retries) QETH_DBF_MESSAGE(2, "%s Retrying to do IDX activates.\n", @@ -3933,6 +3970,7 @@ retriable: else goto retry; } + qeth_determine_capabilities(card); qeth_init_tokens(card); qeth_init_func_level(card); rc = qeth_idx_activate_channel(&card->read, qeth_idx_read_cb); @@ -4202,41 +4240,6 @@ void qeth_core_free_discipline(struct qeth_card *card) card->discipline.ccwgdriver = NULL; } -static void qeth_determine_capabilities(struct qeth_card *card) -{ - int rc; - int length; - char *prcd; - - QETH_DBF_TEXT(SETUP, 2, "detcapab"); - rc = ccw_device_set_online(CARD_DDEV(card)); - if (rc) { - QETH_DBF_TEXT_(SETUP, 2, "3err%d", rc); - goto out; - } - - - rc = qeth_read_conf_data(card, (void **) &prcd, &length); - if (rc) { - QETH_DBF_MESSAGE(2, "%s qeth_read_conf_data returned %i\n", - dev_name(&card->gdev->dev), rc); - QETH_DBF_TEXT_(SETUP, 2, "5err%d", rc); - goto out_offline; - } - qeth_configure_unitaddr(card, prcd); - qeth_configure_blkt_default(card, prcd); - kfree(prcd); - - rc = qdio_get_ssqd_desc(CARD_DDEV(card), &card->ssqd); - if (rc) - QETH_DBF_TEXT_(SETUP, 2, "6err%d", rc); - -out_offline: - ccw_device_set_offline(CARD_DDEV(card)); -out: - return; -} - static int qeth_core_probe_device(struct ccwgroup_device *gdev) { struct qeth_card *card; diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c index 7a7a1b664781..ada0fe782373 100644 --- a/drivers/s390/net/qeth_l2_main.c +++ b/drivers/s390/net/qeth_l2_main.c @@ -573,13 +573,13 @@ static int qeth_l2_send_setmac_cb(struct qeth_card *card, case IPA_RC_L2_DUP_LAYER3_MAC: dev_warn(&card->gdev->dev, "MAC address %pM already exists\n", - card->dev->dev_addr); + cmd->data.setdelmac.mac); break; case IPA_RC_L2_MAC_NOT_AUTH_BY_HYP: case IPA_RC_L2_MAC_NOT_AUTH_BY_ADP: dev_warn(&card->gdev->dev, "MAC address %pM is not authorized\n", - card->dev->dev_addr); + cmd->data.setdelmac.mac); break; default: break; @@ -831,12 +831,14 @@ tx_drop: return NETDEV_TX_OK; } -static int qeth_l2_open(struct net_device *dev) +static int __qeth_l2_open(struct net_device *dev) { struct qeth_card *card = dev->ml_priv; int rc = 0; QETH_CARD_TEXT(card, 4, "qethopen"); + if (card->state == CARD_STATE_UP) + return rc; if (card->state != CARD_STATE_SOFTSETUP) return -ENODEV; @@ -857,6 +859,18 @@ static int qeth_l2_open(struct net_device *dev) return rc; } +static int qeth_l2_open(struct net_device *dev) +{ + struct qeth_card *card = dev->ml_priv; + + QETH_CARD_TEXT(card, 5, "qethope_"); + if (qeth_wait_for_threads(card, QETH_RECOVER_THREAD)) { + QETH_CARD_TEXT(card, 3, "openREC"); + return -ERESTARTSYS; + } + return __qeth_l2_open(dev); +} + static int qeth_l2_stop(struct net_device *dev) { struct qeth_card *card = dev->ml_priv; @@ -1046,7 +1060,7 @@ contin: if (recover_flag == CARD_STATE_RECOVER) { if (recovery_mode && card->info.type != QETH_CARD_TYPE_OSN) { - qeth_l2_open(card->dev); + __qeth_l2_open(card->dev); } else { rtnl_lock(); dev_open(card->dev); diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index e227e465bfc4..d09b0c44fc3d 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c @@ -2998,7 +2998,9 @@ static inline void qeth_l3_hdr_csum(struct qeth_card *card, */ if (iph->protocol == IPPROTO_UDP) hdr->hdr.l3.ext_flags |= QETH_HDR_EXT_UDP; - hdr->hdr.l3.ext_flags |= QETH_HDR_EXT_CSUM_TRANSP_REQ; + hdr->hdr.l3.ext_flags |= QETH_HDR_EXT_CSUM_TRANSP_REQ | + QETH_HDR_EXT_CSUM_HDR_REQ; + iph->check = 0; if (card->options.performance_stats) card->perf_stats.tx_csum++; } @@ -3240,12 +3242,14 @@ tx_drop: return NETDEV_TX_OK; } -static int qeth_l3_open(struct net_device *dev) +static int __qeth_l3_open(struct net_device *dev) { struct qeth_card *card = dev->ml_priv; int rc = 0; QETH_CARD_TEXT(card, 4, "qethopen"); + if (card->state == CARD_STATE_UP) + return rc; if (card->state != CARD_STATE_SOFTSETUP) return -ENODEV; card->data.state = CH_STATE_UP; @@ -3260,6 +3264,18 @@ static int qeth_l3_open(struct net_device *dev) return rc; } +static int qeth_l3_open(struct net_device *dev) +{ + struct qeth_card *card = dev->ml_priv; + + QETH_CARD_TEXT(card, 5, "qethope_"); + if (qeth_wait_for_threads(card, QETH_RECOVER_THREAD)) { + QETH_CARD_TEXT(card, 3, "openREC"); + return -ERESTARTSYS; + } + return __qeth_l3_open(dev); +} + static int qeth_l3_stop(struct net_device *dev) { struct qeth_card *card = dev->ml_priv; @@ -3564,7 +3580,7 @@ contin: netif_carrier_off(card->dev); if (recover_flag == CARD_STATE_RECOVER) { if (recovery_mode) - qeth_l3_open(card->dev); + __qeth_l3_open(card->dev); else { rtnl_lock(); dev_open(card->dev); diff --git a/drivers/s390/net/smsgiucv.c b/drivers/s390/net/smsgiucv.c index 65e1cf104943..207b7d742443 100644 --- a/drivers/s390/net/smsgiucv.c +++ b/drivers/s390/net/smsgiucv.c @@ -60,7 +60,7 @@ static struct iucv_handler smsg_handler = { static int smsg_path_pending(struct iucv_path *path, u8 ipvmid[8], u8 ipuser[16]) { - if (strncmp(ipvmid, "*MSG ", sizeof(ipvmid)) != 0) + if (strncmp(ipvmid, "*MSG ", 8) != 0) return -EINVAL; /* Path pending from *MSG. */ return iucv_path_accept(path, &smsg_handler, "SMSGIUCV ", NULL); diff --git a/drivers/s390/scsi/zfcp_cfdc.c b/drivers/s390/scsi/zfcp_cfdc.c index 46342fee394d..303dde09d294 100644 --- a/drivers/s390/scsi/zfcp_cfdc.c +++ b/drivers/s390/scsi/zfcp_cfdc.c @@ -317,7 +317,7 @@ static void zfcp_act_eval_err(struct zfcp_adapter *adapter, u32 table) /** * zfcp_cfdc_port_denied - Process "access denied" for port - * @port: The port where the acces has been denied + * @port: The port where the access has been denied * @qual: The FSF status qualifier for the access denied FSF status */ void zfcp_cfdc_port_denied(struct zfcp_port *port, |