diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2020-04-10 09:47:26 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2020-04-10 09:47:26 -0700 |
commit | 523a05fc681d139ca98a083fa6685ef22c600326 (patch) | |
tree | e82a7d5a63578b1fbe5b830e9a52ae226386f0b6 /drivers/s390 | |
parent | c0cc271173b2e1c2d8d0ceaef14e4dfa79eefc0d (diff) | |
parent | 2bc55eaeb88d30accfc1b6ac2708d4e4b81ca260 (diff) |
Merge tag 's390-5.7-2' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
Pull more s390 updates from Vasily Gorbik:
"Second round of s390 fixes and features for 5.7:
- The rest of fallthrough; annotations conversion
- Couple of fixes for ADD uevents in the common I/O layer
- Minor refactoring of the queued direct I/O code"
* tag 's390-5.7-2' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux:
s390/cio: generate delayed uevent for vfio-ccw subchannels
s390/cio: avoid duplicated 'ADD' uevents
s390/qdio: clear DSCI early for polling drivers
s390/qdio: inline shared_ind()
s390/qdio: remove cdev from init_data
s390/qdio: allow for non-contiguous SBAL array in init_data
zfcp: inline zfcp_qdio_setup_init_data()
s390/qdio: cleanly split alloc and establish
s390/mm: use fallthrough;
Diffstat (limited to 'drivers/s390')
-rw-r--r-- | drivers/s390/cio/device.c | 13 | ||||
-rw-r--r-- | drivers/s390/cio/qdio.h | 1 | ||||
-rw-r--r-- | drivers/s390/cio/qdio_debug.c | 16 | ||||
-rw-r--r-- | drivers/s390/cio/qdio_debug.h | 3 | ||||
-rw-r--r-- | drivers/s390/cio/qdio_main.c | 63 | ||||
-rw-r--r-- | drivers/s390/cio/qdio_setup.c | 10 | ||||
-rw-r--r-- | drivers/s390/cio/qdio_thinint.c | 28 | ||||
-rw-r--r-- | drivers/s390/cio/vfio_ccw_drv.c | 5 | ||||
-rw-r--r-- | drivers/s390/net/qeth_core.h | 5 | ||||
-rw-r--r-- | drivers/s390/net/qeth_core_main.c | 65 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_qdio.c | 51 |
11 files changed, 102 insertions, 158 deletions
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c index 50007cb9be5b..b29fe8d50baf 100644 --- a/drivers/s390/cio/device.c +++ b/drivers/s390/cio/device.c @@ -849,8 +849,10 @@ static void io_subchannel_register(struct ccw_device *cdev) * Now we know this subchannel will stay, we can throw * our delayed uevent. */ - dev_set_uevent_suppress(&sch->dev, 0); - kobject_uevent(&sch->dev.kobj, KOBJ_ADD); + if (dev_get_uevent_suppress(&sch->dev)) { + dev_set_uevent_suppress(&sch->dev, 0); + kobject_uevent(&sch->dev.kobj, KOBJ_ADD); + } /* make it known to the system */ ret = ccw_device_add(cdev); if (ret) { @@ -1058,8 +1060,11 @@ static int io_subchannel_probe(struct subchannel *sch) * Throw the delayed uevent for the subchannel, register * the ccw_device and exit. */ - dev_set_uevent_suppress(&sch->dev, 0); - kobject_uevent(&sch->dev.kobj, KOBJ_ADD); + if (dev_get_uevent_suppress(&sch->dev)) { + /* should always be the case for the console */ + dev_set_uevent_suppress(&sch->dev, 0); + kobject_uevent(&sch->dev.kobj, KOBJ_ADD); + } cdev = sch_get_cdev(sch); rc = ccw_device_add(cdev); if (rc) { diff --git a/drivers/s390/cio/qdio.h b/drivers/s390/cio/qdio.h index b0beafc43d37..b8453b594679 100644 --- a/drivers/s390/cio/qdio.h +++ b/drivers/s390/cio/qdio.h @@ -374,7 +374,6 @@ int tiqdio_allocate_memory(void); void tiqdio_free_memory(void); int tiqdio_register_thinints(void); void tiqdio_unregister_thinints(void); -void clear_nonshared_ind(struct qdio_irq *); int test_nonshared_ind(struct qdio_irq *); /* prototypes for setup */ diff --git a/drivers/s390/cio/qdio_debug.c b/drivers/s390/cio/qdio_debug.c index 5a3d9ee90a7f..286b044fb027 100644 --- a/drivers/s390/cio/qdio_debug.c +++ b/drivers/s390/cio/qdio_debug.c @@ -58,25 +58,11 @@ static void qdio_clear_dbf_list(void) mutex_unlock(&qdio_dbf_list_mutex); } -int qdio_allocate_dbf(struct qdio_initialize *init_data, - struct qdio_irq *irq_ptr) +int qdio_allocate_dbf(struct qdio_irq *irq_ptr) { char text[QDIO_DBF_NAME_LEN]; struct qdio_dbf_entry *new_entry; - DBF_EVENT("qfmt:%1d", init_data->q_format); - DBF_HEX(init_data->adapter_name, 8); - DBF_EVENT("qpff%4x", init_data->qib_param_field_format); - DBF_HEX(&init_data->qib_param_field, sizeof(void *)); - DBF_HEX(&init_data->input_slib_elements, sizeof(void *)); - DBF_HEX(&init_data->output_slib_elements, sizeof(void *)); - DBF_EVENT("niq:%1d noq:%1d", init_data->no_input_qs, - init_data->no_output_qs); - DBF_HEX(&init_data->input_handler, sizeof(void *)); - DBF_HEX(&init_data->output_handler, sizeof(void *)); - DBF_HEX(&init_data->int_parm, sizeof(long)); - DBF_HEX(&init_data->input_sbal_addr_array, sizeof(void *)); - DBF_HEX(&init_data->output_sbal_addr_array, sizeof(void *)); DBF_EVENT("irq:%8lx", (unsigned long)irq_ptr); /* allocate trace view for the interface */ diff --git a/drivers/s390/cio/qdio_debug.h b/drivers/s390/cio/qdio_debug.h index 122450ba6b90..0dfba085f360 100644 --- a/drivers/s390/cio/qdio_debug.h +++ b/drivers/s390/cio/qdio_debug.h @@ -64,8 +64,7 @@ static inline void DBF_DEV_HEX(struct qdio_irq *dev, void *addr, debug_event(dev->debug_area, level, addr, len); } -int qdio_allocate_dbf(struct qdio_initialize *init_data, - struct qdio_irq *irq_ptr); +int qdio_allocate_dbf(struct qdio_irq *irq_ptr); void qdio_setup_debug_entries(struct qdio_irq *irq_ptr); void qdio_shutdown_debug_entries(struct qdio_irq *irq_ptr); int qdio_debug_init(void); diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c index c890848064fe..bcc3ab14e72d 100644 --- a/drivers/s390/cio/qdio_main.c +++ b/drivers/s390/cio/qdio_main.c @@ -1220,27 +1220,21 @@ EXPORT_SYMBOL_GPL(qdio_free); /** * qdio_allocate - allocate qdio queues and associated data - * @init_data: initialization data + * @cdev: associated ccw device + * @no_input_qs: allocate this number of Input Queues + * @no_output_qs: allocate this number of Output Queues */ -int qdio_allocate(struct qdio_initialize *init_data) +int qdio_allocate(struct ccw_device *cdev, unsigned int no_input_qs, + unsigned int no_output_qs) { - struct ccw_device *cdev = init_data->cdev; struct subchannel_id schid; struct qdio_irq *irq_ptr; ccw_device_get_schid(cdev, &schid); DBF_EVENT("qallocate:%4x", schid.sch_no); - if ((init_data->no_input_qs && !init_data->input_handler) || - (init_data->no_output_qs && !init_data->output_handler)) - return -EINVAL; - - if ((init_data->no_input_qs > QDIO_MAX_QUEUES_PER_IRQ) || - (init_data->no_output_qs > QDIO_MAX_QUEUES_PER_IRQ)) - return -EINVAL; - - if ((!init_data->input_sbal_addr_array) || - (!init_data->output_sbal_addr_array)) + if (no_input_qs > QDIO_MAX_QUEUES_PER_IRQ || + no_output_qs > QDIO_MAX_QUEUES_PER_IRQ) return -EINVAL; /* irq_ptr must be in GFP_DMA since it contains ccw1.cda */ @@ -1250,9 +1244,12 @@ int qdio_allocate(struct qdio_initialize *init_data) irq_ptr->cdev = cdev; mutex_init(&irq_ptr->setup_mutex); - if (qdio_allocate_dbf(init_data, irq_ptr)) + if (qdio_allocate_dbf(irq_ptr)) goto out_rel; + DBF_DEV_EVENT(DBF_ERR, irq_ptr, "alloc niq:%1u noq:%1u", no_input_qs, + no_output_qs); + /* * Allocate a page for the chsc calls in qdio_establish. * Must be pre-allocated since a zfcp recovery will call @@ -1268,8 +1265,7 @@ int qdio_allocate(struct qdio_initialize *init_data) if (!irq_ptr->qdr) goto out_rel; - if (qdio_allocate_qs(irq_ptr, init_data->no_input_qs, - init_data->no_output_qs)) + if (qdio_allocate_qs(irq_ptr, no_input_qs, no_output_qs)) goto out_rel; INIT_LIST_HEAD(&irq_ptr->entry); @@ -1305,13 +1301,33 @@ static void qdio_detect_hsicq(struct qdio_irq *irq_ptr) DBF_EVENT("use_cq:%d", use_cq); } +static void qdio_trace_init_data(struct qdio_irq *irq, + struct qdio_initialize *data) +{ + DBF_DEV_EVENT(DBF_ERR, irq, "qfmt:%1u", data->q_format); + DBF_DEV_HEX(irq, data->adapter_name, 8, DBF_ERR); + DBF_DEV_EVENT(DBF_ERR, irq, "qpff%4x", data->qib_param_field_format); + DBF_DEV_HEX(irq, &data->qib_param_field, sizeof(void *), DBF_ERR); + DBF_DEV_HEX(irq, &data->input_slib_elements, sizeof(void *), DBF_ERR); + DBF_DEV_HEX(irq, &data->output_slib_elements, sizeof(void *), DBF_ERR); + DBF_DEV_EVENT(DBF_ERR, irq, "niq:%1u noq:%1u", data->no_input_qs, + data->no_output_qs); + DBF_DEV_HEX(irq, &data->input_handler, sizeof(void *), DBF_ERR); + DBF_DEV_HEX(irq, &data->output_handler, sizeof(void *), DBF_ERR); + DBF_DEV_HEX(irq, &data->int_parm, sizeof(long), DBF_ERR); + DBF_DEV_HEX(irq, &data->input_sbal_addr_array, sizeof(void *), DBF_ERR); + DBF_DEV_HEX(irq, &data->output_sbal_addr_array, sizeof(void *), + DBF_ERR); +} + /** * qdio_establish - establish queues on a qdio subchannel + * @cdev: associated ccw device * @init_data: initialization data */ -int qdio_establish(struct qdio_initialize *init_data) +int qdio_establish(struct ccw_device *cdev, + struct qdio_initialize *init_data) { - struct ccw_device *cdev = init_data->cdev; struct qdio_irq *irq_ptr = cdev->private->qdio_data; struct subchannel_id schid; int rc; @@ -1322,7 +1338,16 @@ int qdio_establish(struct qdio_initialize *init_data) if (!irq_ptr) return -ENODEV; + if ((init_data->no_input_qs && !init_data->input_handler) || + (init_data->no_output_qs && !init_data->output_handler)) + return -EINVAL; + + if (!init_data->input_sbal_addr_array || + !init_data->output_sbal_addr_array) + return -EINVAL; + mutex_lock(&irq_ptr->setup_mutex); + qdio_trace_init_data(irq_ptr, init_data); qdio_setup_irq(irq_ptr, init_data); rc = qdio_establish_thinint(irq_ptr); @@ -1618,8 +1643,6 @@ int qdio_start_irq(struct ccw_device *cdev) if (!irq_ptr) return -ENODEV; - clear_nonshared_ind(irq_ptr); - for_each_input_queue(irq_ptr, q, i) qdio_stop_polling(q); diff --git a/drivers/s390/cio/qdio_setup.c b/drivers/s390/cio/qdio_setup.c index bbbefc9f9e04..3083edd61f0c 100644 --- a/drivers/s390/cio/qdio_setup.c +++ b/drivers/s390/cio/qdio_setup.c @@ -213,8 +213,6 @@ static void setup_queues(struct qdio_irq *irq_ptr, struct qdio_initialize *qdio_init) { struct qdio_q *q; - struct qdio_buffer **input_sbal_array = qdio_init->input_sbal_addr_array; - struct qdio_buffer **output_sbal_array = qdio_init->output_sbal_addr_array; struct qdio_outbuf_state *output_sbal_state_array = qdio_init->output_sbal_state_array; int i; @@ -225,8 +223,8 @@ static void setup_queues(struct qdio_irq *irq_ptr, q->is_input_q = 1; - setup_storage_lists(q, irq_ptr, input_sbal_array, i); - input_sbal_array += QDIO_MAX_BUFFERS_PER_Q; + setup_storage_lists(q, irq_ptr, + qdio_init->input_sbal_addr_array[i], i); if (is_thinint_irq(irq_ptr)) { tasklet_init(&q->tasklet, tiqdio_inbound_processing, @@ -245,8 +243,8 @@ static void setup_queues(struct qdio_irq *irq_ptr, output_sbal_state_array += QDIO_MAX_BUFFERS_PER_Q; q->is_input_q = 0; - setup_storage_lists(q, irq_ptr, output_sbal_array, i); - output_sbal_array += QDIO_MAX_BUFFERS_PER_Q; + setup_storage_lists(q, irq_ptr, + qdio_init->output_sbal_addr_array[i], i); tasklet_init(&q->tasklet, qdio_outbound_processing, (unsigned long) q); diff --git a/drivers/s390/cio/qdio_thinint.c b/drivers/s390/cio/qdio_thinint.c index ea09df7209f0..ae50373617cd 100644 --- a/drivers/s390/cio/qdio_thinint.c +++ b/drivers/s390/cio/qdio_thinint.c @@ -82,36 +82,16 @@ void tiqdio_remove_device(struct qdio_irq *irq_ptr) INIT_LIST_HEAD(&irq_ptr->entry); } -static inline int has_multiple_inq_on_dsci(struct qdio_irq *irq_ptr) -{ - return irq_ptr->nr_input_qs > 1; -} - static inline int references_shared_dsci(struct qdio_irq *irq_ptr) { return irq_ptr->dsci == &q_indicators[TIQDIO_SHARED_IND].ind; } -static inline int shared_ind(struct qdio_irq *irq_ptr) -{ - return references_shared_dsci(irq_ptr) || - has_multiple_inq_on_dsci(irq_ptr); -} - -void clear_nonshared_ind(struct qdio_irq *irq_ptr) -{ - if (!is_thinint_irq(irq_ptr)) - return; - if (shared_ind(irq_ptr)) - return; - xchg(irq_ptr->dsci, 0); -} - int test_nonshared_ind(struct qdio_irq *irq_ptr) { if (!is_thinint_irq(irq_ptr)) return 0; - if (shared_ind(irq_ptr)) + if (references_shared_dsci(irq_ptr)) return 0; if (*irq_ptr->dsci) return 1; @@ -131,8 +111,7 @@ static inline void tiqdio_call_inq_handlers(struct qdio_irq *irq) struct qdio_q *q; int i; - if (!references_shared_dsci(irq) && - has_multiple_inq_on_dsci(irq)) + if (!references_shared_dsci(irq)) xchg(irq->dsci, 0); if (irq->irq_poll) { @@ -145,9 +124,6 @@ static inline void tiqdio_call_inq_handlers(struct qdio_irq *irq) } for_each_input_queue(irq, q, i) { - if (!shared_ind(irq)) - xchg(irq->dsci, 0); - /* * Call inbound processing but not directly * since that could starve other thinint queues. diff --git a/drivers/s390/cio/vfio_ccw_drv.c b/drivers/s390/cio/vfio_ccw_drv.c index e401a3d0aa57..339a6bc0339b 100644 --- a/drivers/s390/cio/vfio_ccw_drv.c +++ b/drivers/s390/cio/vfio_ccw_drv.c @@ -167,6 +167,11 @@ static int vfio_ccw_sch_probe(struct subchannel *sch) if (ret) goto out_disable; + if (dev_get_uevent_suppress(&sch->dev)) { + dev_set_uevent_suppress(&sch->dev, 0); + kobject_uevent(&sch->dev.kobj, KOBJ_ADD); + } + VFIO_CCW_MSG_EVENT(4, "bound to subchannel %x.%x.%04x\n", sch->schid.cssid, sch->schid.ssid, sch->schid.sch_no); diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h index acda230323d5..e0b26310ecab 100644 --- a/drivers/s390/net/qeth_core.h +++ b/drivers/s390/net/qeth_core.h @@ -181,11 +181,12 @@ struct qeth_vnicc_info { /*****************************************************************************/ /* QDIO queue and buffer handling */ /*****************************************************************************/ -#define QETH_MAX_QUEUES 4 +#define QETH_MAX_OUT_QUEUES 4 #define QETH_IQD_MIN_TXQ 2 /* One for ucast, one for mcast. */ #define QETH_IQD_MCAST_TXQ 0 #define QETH_IQD_MIN_UCAST_TXQ 1 +#define QETH_MAX_IN_QUEUES 2 #define QETH_RX_COPYBREAK (PAGE_SIZE >> 1) #define QETH_IN_BUF_SIZE_DEFAULT 65536 #define QETH_IN_BUF_COUNT_DEFAULT 64 @@ -539,7 +540,7 @@ struct qeth_qdio_info { /* output */ int no_out_queues; - struct qeth_qdio_out_q *out_qs[QETH_MAX_QUEUES]; + struct qeth_qdio_out_q *out_qs[QETH_MAX_OUT_QUEUES]; struct qdio_outbuf_state *out_bufstates; /* priority queueing */ diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index 24fd17b347fe..f7689461c242 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -4812,28 +4812,13 @@ out: return; } -static void qeth_qdio_establish_cq(struct qeth_card *card, - struct qdio_buffer **in_sbal_ptrs) -{ - int i; - - if (card->options.cq == QETH_CQ_ENABLED) { - int offset = QDIO_MAX_BUFFERS_PER_Q * - (card->qdio.no_in_queues - 1); - - for (i = 0; i < QDIO_MAX_BUFFERS_PER_Q; i++) - in_sbal_ptrs[offset + i] = - card->qdio.c_q->bufs[i].buffer; - } -} - static int qeth_qdio_establish(struct qeth_card *card) { + struct qdio_buffer **out_sbal_ptrs[QETH_MAX_OUT_QUEUES]; + struct qdio_buffer **in_sbal_ptrs[QETH_MAX_IN_QUEUES]; struct qdio_initialize init_data; char *qib_param_field; - struct qdio_buffer **in_sbal_ptrs; - struct qdio_buffer **out_sbal_ptrs; - int i, j, k; + unsigned int i; int rc = 0; QETH_CARD_TEXT(card, 2, "qdioest"); @@ -4847,35 +4832,14 @@ static int qeth_qdio_establish(struct qeth_card *card) qeth_create_qib_param_field(card, qib_param_field); qeth_create_qib_param_field_blkt(card, qib_param_field); - in_sbal_ptrs = kcalloc(card->qdio.no_in_queues * QDIO_MAX_BUFFERS_PER_Q, - sizeof(void *), - GFP_KERNEL); - if (!in_sbal_ptrs) { - rc = -ENOMEM; - goto out_free_qib_param; - } - - for (i = 0; i < QDIO_MAX_BUFFERS_PER_Q; i++) - in_sbal_ptrs[i] = card->qdio.in_q->bufs[i].buffer; - - qeth_qdio_establish_cq(card, in_sbal_ptrs); - - out_sbal_ptrs = - kcalloc(card->qdio.no_out_queues * QDIO_MAX_BUFFERS_PER_Q, - sizeof(void *), - GFP_KERNEL); - if (!out_sbal_ptrs) { - rc = -ENOMEM; - goto out_free_in_sbals; - } + in_sbal_ptrs[0] = card->qdio.in_q->qdio_bufs; + if (card->options.cq == QETH_CQ_ENABLED) + in_sbal_ptrs[1] = card->qdio.c_q->qdio_bufs; - for (i = 0, k = 0; i < card->qdio.no_out_queues; ++i) - for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; j++, k++) - out_sbal_ptrs[k] = - card->qdio.out_qs[i]->bufs[j]->buffer; + for (i = 0; i < card->qdio.no_out_queues; i++) + out_sbal_ptrs[i] = card->qdio.out_qs[i]->qdio_bufs; memset(&init_data, 0, sizeof(struct qdio_initialize)); - init_data.cdev = CARD_DDEV(card); init_data.q_format = IS_IQD(card) ? QDIO_IQDIO_QFMT : QDIO_QETH_QFMT; init_data.qib_param_field_format = 0; @@ -4893,12 +4857,13 @@ static int qeth_qdio_establish(struct qeth_card *card) if (atomic_cmpxchg(&card->qdio.state, QETH_QDIO_ALLOCATED, QETH_QDIO_ESTABLISHED) == QETH_QDIO_ALLOCATED) { - rc = qdio_allocate(&init_data); + rc = qdio_allocate(CARD_DDEV(card), init_data.no_input_qs, + init_data.no_output_qs); if (rc) { atomic_set(&card->qdio.state, QETH_QDIO_ALLOCATED); goto out; } - rc = qdio_establish(&init_data); + rc = qdio_establish(CARD_DDEV(card), &init_data); if (rc) { atomic_set(&card->qdio.state, QETH_QDIO_ALLOCATED); qdio_free(CARD_DDEV(card)); @@ -4916,10 +4881,6 @@ static int qeth_qdio_establish(struct qeth_card *card) break; } out: - kfree(out_sbal_ptrs); -out_free_in_sbals: - kfree(in_sbal_ptrs); -out_free_qib_param: kfree(qib_param_field); out_free_nothing: return rc; @@ -5985,7 +5946,7 @@ static struct net_device *qeth_alloc_netdev(struct qeth_card *card) switch (card->info.type) { case QETH_CARD_TYPE_IQD: dev = alloc_netdev_mqs(sizeof(*priv), "hsi%d", NET_NAME_UNKNOWN, - ether_setup, QETH_MAX_QUEUES, 1); + ether_setup, QETH_MAX_OUT_QUEUES, 1); break; case QETH_CARD_TYPE_OSM: dev = alloc_etherdev(sizeof(*priv)); @@ -5995,7 +5956,7 @@ static struct net_device *qeth_alloc_netdev(struct qeth_card *card) ether_setup); break; default: - dev = alloc_etherdev_mqs(sizeof(*priv), QETH_MAX_QUEUES, 1); + dev = alloc_etherdev_mqs(sizeof(*priv), QETH_MAX_OUT_QUEUES, 1); } if (!dev) diff --git a/drivers/s390/scsi/zfcp_qdio.c b/drivers/s390/scsi/zfcp_qdio.c index f0d6296e673b..26702b56a7ab 100644 --- a/drivers/s390/scsi/zfcp_qdio.c +++ b/drivers/s390/scsi/zfcp_qdio.c @@ -277,29 +277,6 @@ int zfcp_qdio_send(struct zfcp_qdio *qdio, struct zfcp_qdio_req *q_req) return 0; } - -static void zfcp_qdio_setup_init_data(struct qdio_initialize *id, - struct zfcp_qdio *qdio) -{ - memset(id, 0, sizeof(*id)); - id->cdev = qdio->adapter->ccw_device; - id->q_format = QDIO_ZFCP_QFMT; - memcpy(id->adapter_name, dev_name(&id->cdev->dev), 8); - ASCEBC(id->adapter_name, 8); - id->qib_rflags = QIB_RFLAGS_ENABLE_DATA_DIV; - if (enable_multibuffer) - id->qdr_ac |= QDR_AC_MULTI_BUFFER_ENABLE; - id->no_input_qs = 1; - id->no_output_qs = 1; - id->input_handler = zfcp_qdio_int_resp; - id->output_handler = zfcp_qdio_int_req; - id->int_parm = (unsigned long) qdio; - id->input_sbal_addr_array = qdio->res_q; - id->output_sbal_addr_array = qdio->req_q; - id->scan_threshold = - QDIO_MAX_BUFFERS_PER_Q - ZFCP_QDIO_MAX_SBALS_PER_REQ * 2; -} - /** * zfcp_qdio_allocate - allocate queue memory and initialize QDIO data * @qdio: pointer to struct zfcp_qdio @@ -308,7 +285,6 @@ static void zfcp_qdio_setup_init_data(struct qdio_initialize *id, */ static int zfcp_qdio_allocate(struct zfcp_qdio *qdio) { - struct qdio_initialize init_data; int ret; ret = qdio_alloc_buffers(qdio->req_q, QDIO_MAX_BUFFERS_PER_Q); @@ -319,10 +295,9 @@ static int zfcp_qdio_allocate(struct zfcp_qdio *qdio) if (ret) goto free_req_q; - zfcp_qdio_setup_init_data(&init_data, qdio); init_waitqueue_head(&qdio->req_q_wq); - ret = qdio_allocate(&init_data); + ret = qdio_allocate(qdio->adapter->ccw_device, 1, 1); if (ret) goto free_res_q; @@ -374,8 +349,10 @@ void zfcp_qdio_close(struct zfcp_qdio *qdio) */ int zfcp_qdio_open(struct zfcp_qdio *qdio) { + struct qdio_buffer **input_sbals[1] = {qdio->res_q}; + struct qdio_buffer **output_sbals[1] = {qdio->req_q}; struct qdio_buffer_element *sbale; - struct qdio_initialize init_data; + struct qdio_initialize init_data = {0}; struct zfcp_adapter *adapter = qdio->adapter; struct ccw_device *cdev = adapter->ccw_device; struct qdio_ssqd_desc ssqd; @@ -387,12 +364,26 @@ int zfcp_qdio_open(struct zfcp_qdio *qdio) atomic_andnot(ZFCP_STATUS_ADAPTER_SIOSL_ISSUED, &qdio->adapter->status); - zfcp_qdio_setup_init_data(&init_data, qdio); + init_data.q_format = QDIO_ZFCP_QFMT; + memcpy(init_data.adapter_name, dev_name(&cdev->dev), 8); + ASCEBC(init_data.adapter_name, 8); + init_data.qib_rflags = QIB_RFLAGS_ENABLE_DATA_DIV; + if (enable_multibuffer) + init_data.qdr_ac |= QDR_AC_MULTI_BUFFER_ENABLE; + init_data.no_input_qs = 1; + init_data.no_output_qs = 1; + init_data.input_handler = zfcp_qdio_int_resp; + init_data.output_handler = zfcp_qdio_int_req; + init_data.int_parm = (unsigned long) qdio; + init_data.input_sbal_addr_array = input_sbals; + init_data.output_sbal_addr_array = output_sbals; + init_data.scan_threshold = + QDIO_MAX_BUFFERS_PER_Q - ZFCP_QDIO_MAX_SBALS_PER_REQ * 2; - if (qdio_establish(&init_data)) + if (qdio_establish(cdev, &init_data)) goto failed_establish; - if (qdio_get_ssqd_desc(init_data.cdev, &ssqd)) + if (qdio_get_ssqd_desc(cdev, &ssqd)) goto failed_qdio; if (ssqd.qdioac2 & CHSC_AC2_DATA_DIV_ENABLED) |