mirror of
https://github.com/torvalds/linux.git
synced 2024-11-19 02:21:47 +00:00
s390 updates for the 5.7 merge window #2
- 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. -----BEGIN PGP SIGNATURE----- iQEzBAABCAAdFiEE3QHqV+H2a8xAv27vjYWKoQLXFBgFAl6QS08ACgkQjYWKoQLX FBhW3Af8Cor9Dvy+EObX7vTwAgrVwfvBgkJGQzSpK/2/PBhV8SsZkTCTxTZmM2X1 TV6UZ9Afde6zWcF8ywn81iblZlt4SNrN3jLxgdETgR1oBQzOUi1lZDZ/71YdZREe 09u35KS5D6NLWHBT9RXU+2qu6PbpiO2rZJycdLxvOmmZJ1kx5WtPPmisG17hQq+e t2AhYLqQg6YkCtvs3Q8xrotjfqvx0XDhE8R67nbb9+HpAI4W9S4q5n7Zno03V622 WTTrsbEF++a8Q9SCyiP79G7/LgA/m6U72YWbjhcOGgN8g/24E6+/BXZj9b3eLOgF 4DNmJ4+kt+meaz2CcxCnVxTXwVO2ow== =yqbJ -----END PGP SIGNATURE----- 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;
This commit is contained in:
commit
523a05fc68
@ -325,7 +325,6 @@ typedef void qdio_handler_t(struct ccw_device *, unsigned int, int,
|
||||
|
||||
/**
|
||||
* struct qdio_initialize - qdio initialization data
|
||||
* @cdev: associated ccw device
|
||||
* @q_format: queue format
|
||||
* @qdr_ac: feature flags to set
|
||||
* @adapter_name: name for the adapter
|
||||
@ -341,12 +340,11 @@ typedef void qdio_handler_t(struct ccw_device *, unsigned int, int,
|
||||
* @irq_poll: Data IRQ polling handler (NULL when not supported)
|
||||
* @scan_threshold: # of in-use buffers that triggers scan on output queue
|
||||
* @int_parm: interruption parameter
|
||||
* @input_sbal_addr_array: address of no_input_qs * 128 pointers
|
||||
* @output_sbal_addr_array: address of no_output_qs * 128 pointers
|
||||
* @input_sbal_addr_array: per-queue array, each element points to 128 SBALs
|
||||
* @output_sbal_addr_array: per-queue array, each element points to 128 SBALs
|
||||
* @output_sbal_state_array: no_output_qs * 128 state info (for CQ or NULL)
|
||||
*/
|
||||
struct qdio_initialize {
|
||||
struct ccw_device *cdev;
|
||||
unsigned char q_format;
|
||||
unsigned char qdr_ac;
|
||||
unsigned char adapter_name[8];
|
||||
@ -362,8 +360,8 @@ struct qdio_initialize {
|
||||
void (*irq_poll)(struct ccw_device *cdev, unsigned long data);
|
||||
unsigned int scan_threshold;
|
||||
unsigned long int_parm;
|
||||
struct qdio_buffer **input_sbal_addr_array;
|
||||
struct qdio_buffer **output_sbal_addr_array;
|
||||
struct qdio_buffer ***input_sbal_addr_array;
|
||||
struct qdio_buffer ***output_sbal_addr_array;
|
||||
struct qdio_outbuf_state *output_sbal_state_array;
|
||||
};
|
||||
|
||||
@ -408,8 +406,10 @@ int qdio_alloc_buffers(struct qdio_buffer **buf, unsigned int count);
|
||||
void qdio_free_buffers(struct qdio_buffer **buf, unsigned int count);
|
||||
void qdio_reset_buffers(struct qdio_buffer **buf, unsigned int count);
|
||||
|
||||
extern int qdio_allocate(struct qdio_initialize *);
|
||||
extern int qdio_establish(struct qdio_initialize *);
|
||||
extern int qdio_allocate(struct ccw_device *cdev, unsigned int no_input_qs,
|
||||
unsigned int no_output_qs);
|
||||
extern int qdio_establish(struct ccw_device *cdev,
|
||||
struct qdio_initialize *init_data);
|
||||
extern int qdio_activate(struct ccw_device *);
|
||||
extern void qdio_release_aob(struct qaob *);
|
||||
extern int do_QDIO(struct ccw_device *, unsigned int, int, unsigned int,
|
||||
|
@ -852,9 +852,7 @@ void do_secure_storage_access(struct pt_regs *regs)
|
||||
BUG();
|
||||
break;
|
||||
case VDSO_FAULT:
|
||||
/* fallthrough */
|
||||
case GMAP_FAULT:
|
||||
/* fallthrough */
|
||||
default:
|
||||
do_fault_error(regs, VM_READ | VM_WRITE, VM_FAULT_BADMAP);
|
||||
WARN_ON_ONCE(1);
|
||||
|
@ -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) {
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
}
|
||||
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; 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;
|
||||
}
|
||||
|
||||
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)
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user