diff options
Diffstat (limited to 'drivers/s390')
32 files changed, 645 insertions, 586 deletions
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c index e34c6cc61983..8e87a31e329d 100644 --- a/drivers/s390/block/dasd.c +++ b/drivers/s390/block/dasd.c @@ -2077,12 +2077,15 @@ static void __dasd_device_check_path_events(struct dasd_device *device) if (device->stopped & ~(DASD_STOPPED_DC_WAIT)) return; + + dasd_path_clear_all_verify(device); + dasd_path_clear_all_fcsec(device); + rc = device->discipline->pe_handler(device, tbvpm, fcsecpm); if (rc) { + dasd_path_add_tbvpm(device, tbvpm); + dasd_path_add_fcsecpm(device, fcsecpm); dasd_device_set_timer(device, 50); - } else { - dasd_path_clear_all_verify(device); - dasd_path_clear_all_fcsec(device); } }; diff --git a/drivers/s390/block/dasd_3990_erp.c b/drivers/s390/block/dasd_3990_erp.c index 4691a3c35d72..299001ad9a32 100644 --- a/drivers/s390/block/dasd_3990_erp.c +++ b/drivers/s390/block/dasd_3990_erp.c @@ -201,7 +201,7 @@ dasd_3990_erp_DCTL(struct dasd_ccw_req * erp, char modifier) struct ccw1 *ccw; struct dasd_ccw_req *dctl_cqr; - dctl_cqr = dasd_alloc_erp_request((char *) &erp->magic, 1, + dctl_cqr = dasd_alloc_erp_request(erp->magic, 1, sizeof(struct DCTL_data), device); if (IS_ERR(dctl_cqr)) { @@ -1652,7 +1652,7 @@ dasd_3990_erp_action_1B_32(struct dasd_ccw_req * default_erp, char *sense) } /* Build new ERP request including DE/LO */ - erp = dasd_alloc_erp_request((char *) &cqr->magic, + erp = dasd_alloc_erp_request(cqr->magic, 2 + 1,/* DE/LO + TIC */ sizeof(struct DE_eckd_data) + sizeof(struct LO_eckd_data), device); @@ -2388,7 +2388,7 @@ static struct dasd_ccw_req *dasd_3990_erp_add_erp(struct dasd_ccw_req *cqr) } /* allocate additional request block */ - erp = dasd_alloc_erp_request((char *) &cqr->magic, + erp = dasd_alloc_erp_request(cqr->magic, cplength, datasize, device); if (IS_ERR(erp)) { if (cqr->retries <= 0) { diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c index 460e0f1cca53..8410a25a65c1 100644 --- a/drivers/s390/block/dasd_eckd.c +++ b/drivers/s390/block/dasd_eckd.c @@ -560,8 +560,8 @@ static int prefix_LRE(struct ccw1 *ccw, struct PFX_eckd_data *pfxdata, return -EINVAL; } pfxdata->format = format; - pfxdata->base_address = basepriv->ned->unit_addr; - pfxdata->base_lss = basepriv->ned->ID; + pfxdata->base_address = basepriv->conf.ned->unit_addr; + pfxdata->base_lss = basepriv->conf.ned->ID; pfxdata->validity.define_extent = 1; /* private uid is kept up to date, conf_data may be outdated */ @@ -736,32 +736,30 @@ dasd_eckd_cdl_reclen(int recid) return LABEL_SIZE; } /* create unique id from private structure. */ -static void create_uid(struct dasd_eckd_private *private) +static void create_uid(struct dasd_conf *conf, struct dasd_uid *uid) { int count; - struct dasd_uid *uid; - uid = &private->uid; memset(uid, 0, sizeof(struct dasd_uid)); - memcpy(uid->vendor, private->ned->HDA_manufacturer, + memcpy(uid->vendor, conf->ned->HDA_manufacturer, sizeof(uid->vendor) - 1); EBCASC(uid->vendor, sizeof(uid->vendor) - 1); - memcpy(uid->serial, &private->ned->serial, + memcpy(uid->serial, &conf->ned->serial, sizeof(uid->serial) - 1); EBCASC(uid->serial, sizeof(uid->serial) - 1); - uid->ssid = private->gneq->subsystemID; - uid->real_unit_addr = private->ned->unit_addr; - if (private->sneq) { - uid->type = private->sneq->sua_flags; + uid->ssid = conf->gneq->subsystemID; + uid->real_unit_addr = conf->ned->unit_addr; + if (conf->sneq) { + uid->type = conf->sneq->sua_flags; if (uid->type == UA_BASE_PAV_ALIAS) - uid->base_unit_addr = private->sneq->base_unit_addr; + uid->base_unit_addr = conf->sneq->base_unit_addr; } else { uid->type = UA_BASE_DEVICE; } - if (private->vdsneq) { + if (conf->vdsneq) { for (count = 0; count < 16; count++) { sprintf(uid->vduit+2*count, "%02x", - private->vdsneq->uit[count]); + conf->vdsneq->uit[count]); } } } @@ -776,10 +774,10 @@ static int dasd_eckd_generate_uid(struct dasd_device *device) if (!private) return -ENODEV; - if (!private->ned || !private->gneq) + if (!private->conf.ned || !private->conf.gneq) return -ENODEV; spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags); - create_uid(private); + create_uid(&private->conf, &private->uid); spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags); return 0; } @@ -803,14 +801,15 @@ static int dasd_eckd_get_uid(struct dasd_device *device, struct dasd_uid *uid) * return 0 for match */ static int dasd_eckd_compare_path_uid(struct dasd_device *device, - struct dasd_eckd_private *private) + struct dasd_conf *path_conf) { struct dasd_uid device_uid; + struct dasd_uid path_uid; - create_uid(private); + create_uid(path_conf, &path_uid); dasd_eckd_get_uid(device, &device_uid); - return memcmp(&device_uid, &private->uid, sizeof(struct dasd_uid)); + return memcmp(&device_uid, &path_uid, sizeof(struct dasd_uid)); } static void dasd_eckd_fill_rcd_cqr(struct dasd_device *device, @@ -946,34 +945,34 @@ out_error: return ret; } -static int dasd_eckd_identify_conf_parts(struct dasd_eckd_private *private) +static int dasd_eckd_identify_conf_parts(struct dasd_conf *conf) { struct dasd_sneq *sneq; int i, count; - private->ned = NULL; - private->sneq = NULL; - private->vdsneq = NULL; - private->gneq = NULL; - count = private->conf_len / sizeof(struct dasd_sneq); - sneq = (struct dasd_sneq *)private->conf_data; + conf->ned = NULL; + conf->sneq = NULL; + conf->vdsneq = NULL; + conf->gneq = NULL; + count = conf->len / sizeof(struct dasd_sneq); + sneq = (struct dasd_sneq *)conf->data; for (i = 0; i < count; ++i) { if (sneq->flags.identifier == 1 && sneq->format == 1) - private->sneq = sneq; + conf->sneq = sneq; else if (sneq->flags.identifier == 1 && sneq->format == 4) - private->vdsneq = (struct vd_sneq *)sneq; + conf->vdsneq = (struct vd_sneq *)sneq; else if (sneq->flags.identifier == 2) - private->gneq = (struct dasd_gneq *)sneq; + conf->gneq = (struct dasd_gneq *)sneq; else if (sneq->flags.identifier == 3 && sneq->res1 == 1) - private->ned = (struct dasd_ned *)sneq; + conf->ned = (struct dasd_ned *)sneq; sneq++; } - if (!private->ned || !private->gneq) { - private->ned = NULL; - private->sneq = NULL; - private->vdsneq = NULL; - private->gneq = NULL; + if (!conf->ned || !conf->gneq) { + conf->ned = NULL; + conf->sneq = NULL; + conf->vdsneq = NULL; + conf->gneq = NULL; return -EINVAL; } return 0; @@ -1016,9 +1015,9 @@ static void dasd_eckd_store_conf_data(struct dasd_device *device, * with the new one if this points to the same data */ cdp = device->path[chp].conf_data; - if (private->conf_data == cdp) { - private->conf_data = (void *)conf_data; - dasd_eckd_identify_conf_parts(private); + if (private->conf.data == cdp) { + private->conf.data = (void *)conf_data; + dasd_eckd_identify_conf_parts(&private->conf); } ccw_device_get_schid(device->cdev, &sch_id); device->path[chp].conf_data = conf_data; @@ -1036,8 +1035,8 @@ static void dasd_eckd_clear_conf_data(struct dasd_device *device) struct dasd_eckd_private *private = device->private; int i; - private->conf_data = NULL; - private->conf_len = 0; + private->conf.data = NULL; + private->conf.len = 0; for (i = 0; i < 8; i++) { kfree(device->path[i].conf_data); device->path[i].conf_data = NULL; @@ -1071,15 +1070,55 @@ static void dasd_eckd_read_fc_security(struct dasd_device *device) } } +static void dasd_eckd_get_uid_string(struct dasd_conf *conf, + char *print_uid) +{ + struct dasd_uid uid; + + create_uid(conf, &uid); + if (strlen(uid.vduit) > 0) + snprintf(print_uid, sizeof(*print_uid), + "%s.%s.%04x.%02x.%s", + uid.vendor, uid.serial, uid.ssid, + uid.real_unit_addr, uid.vduit); + else + snprintf(print_uid, sizeof(*print_uid), + "%s.%s.%04x.%02x", + uid.vendor, uid.serial, uid.ssid, + uid.real_unit_addr); +} + +static int dasd_eckd_check_cabling(struct dasd_device *device, + void *conf_data, __u8 lpm) +{ + struct dasd_eckd_private *private = device->private; + char print_path_uid[60], print_device_uid[60]; + struct dasd_conf path_conf; + + path_conf.data = conf_data; + path_conf.len = DASD_ECKD_RCD_DATA_SIZE; + if (dasd_eckd_identify_conf_parts(&path_conf)) + return 1; + + if (dasd_eckd_compare_path_uid(device, &path_conf)) { + dasd_eckd_get_uid_string(&path_conf, print_path_uid); + dasd_eckd_get_uid_string(&private->conf, print_device_uid); + dev_err(&device->cdev->dev, + "Not all channel paths lead to the same device, path %02X leads to device %s instead of %s\n", + lpm, print_path_uid, print_device_uid); + return 1; + } + + return 0; +} + static int dasd_eckd_read_conf(struct dasd_device *device) { void *conf_data; int conf_len, conf_data_saved; int rc, path_err, pos; __u8 lpm, opm; - struct dasd_eckd_private *private, path_private; - struct dasd_uid *uid; - char print_path_uid[60], print_device_uid[60]; + struct dasd_eckd_private *private; private = device->private; opm = ccw_device_get_path_mask(device->cdev); @@ -1109,11 +1148,11 @@ static int dasd_eckd_read_conf(struct dasd_device *device) if (!conf_data_saved) { /* initially clear previously stored conf_data */ dasd_eckd_clear_conf_data(device); - private->conf_data = conf_data; - private->conf_len = conf_len; - if (dasd_eckd_identify_conf_parts(private)) { - private->conf_data = NULL; - private->conf_len = 0; + private->conf.data = conf_data; + private->conf.len = conf_len; + if (dasd_eckd_identify_conf_parts(&private->conf)) { + private->conf.data = NULL; + private->conf.len = 0; kfree(conf_data); continue; } @@ -1123,59 +1162,11 @@ static int dasd_eckd_read_conf(struct dasd_device *device) */ dasd_eckd_generate_uid(device); conf_data_saved++; - } else { - path_private.conf_data = conf_data; - path_private.conf_len = DASD_ECKD_RCD_DATA_SIZE; - if (dasd_eckd_identify_conf_parts( - &path_private)) { - path_private.conf_data = NULL; - path_private.conf_len = 0; - kfree(conf_data); - continue; - } - if (dasd_eckd_compare_path_uid( - device, &path_private)) { - uid = &path_private.uid; - if (strlen(uid->vduit) > 0) - snprintf(print_path_uid, - sizeof(print_path_uid), - "%s.%s.%04x.%02x.%s", - uid->vendor, uid->serial, - uid->ssid, uid->real_unit_addr, - uid->vduit); - else - snprintf(print_path_uid, - sizeof(print_path_uid), - "%s.%s.%04x.%02x", - uid->vendor, uid->serial, - uid->ssid, - uid->real_unit_addr); - uid = &private->uid; - if (strlen(uid->vduit) > 0) - snprintf(print_device_uid, - sizeof(print_device_uid), - "%s.%s.%04x.%02x.%s", - uid->vendor, uid->serial, - uid->ssid, uid->real_unit_addr, - uid->vduit); - else - snprintf(print_device_uid, - sizeof(print_device_uid), - "%s.%s.%04x.%02x", - uid->vendor, uid->serial, - uid->ssid, - uid->real_unit_addr); - dev_err(&device->cdev->dev, - "Not all channel paths lead to " - "the same device, path %02X leads to " - "device %s instead of %s\n", lpm, - print_path_uid, print_device_uid); - path_err = -EINVAL; - dasd_path_add_cablepm(device, lpm); - continue; - } - path_private.conf_data = NULL; - path_private.conf_len = 0; + } else if (dasd_eckd_check_cabling(device, conf_data, lpm)) { + dasd_path_add_cablepm(device, lpm); + path_err = -EINVAL; + kfree(conf_data); + continue; } pos = pathmask_to_pos(lpm); @@ -1197,8 +1188,6 @@ static int dasd_eckd_read_conf(struct dasd_device *device) } } - dasd_eckd_read_fc_security(device); - return path_err; } @@ -1213,7 +1202,7 @@ static u32 get_fcx_max_data(struct dasd_device *device) return 0; /* is transport mode supported? */ fcx_in_css = css_general_characteristics.fcx; - fcx_in_gneq = private->gneq->reserved2[7] & 0x04; + fcx_in_gneq = private->conf.gneq->reserved2[7] & 0x04; fcx_in_features = private->features.feature[40] & 0x80; tpm = fcx_in_css && fcx_in_gneq && fcx_in_features; @@ -1282,9 +1271,9 @@ static int rebuild_device_uid(struct dasd_device *device, "returned error %d", rc); break; } - memcpy(private->conf_data, data->rcd_buffer, + memcpy(private->conf.data, data->rcd_buffer, DASD_ECKD_RCD_DATA_SIZE); - if (dasd_eckd_identify_conf_parts(private)) { + if (dasd_eckd_identify_conf_parts(&private->conf)) { rc = -ENODEV; } else /* first valid path is enough */ break; @@ -1299,11 +1288,10 @@ static int rebuild_device_uid(struct dasd_device *device, static void dasd_eckd_path_available_action(struct dasd_device *device, struct pe_handler_work_data *data) { - struct dasd_eckd_private path_private; - struct dasd_uid *uid; __u8 path_rcd_buf[DASD_ECKD_RCD_DATA_SIZE]; __u8 lpm, opm, npm, ppm, epm, hpfpm, cablepm; struct dasd_conf_data *conf_data; + struct dasd_conf path_conf; unsigned long flags; char print_uid[60]; int rc, pos; @@ -1367,11 +1355,11 @@ static void dasd_eckd_path_available_action(struct dasd_device *device, */ memcpy(&path_rcd_buf, data->rcd_buffer, DASD_ECKD_RCD_DATA_SIZE); - path_private.conf_data = (void *) &path_rcd_buf; - path_private.conf_len = DASD_ECKD_RCD_DATA_SIZE; - if (dasd_eckd_identify_conf_parts(&path_private)) { - path_private.conf_data = NULL; - path_private.conf_len = 0; + path_conf.data = (void *)&path_rcd_buf; + path_conf.len = DASD_ECKD_RCD_DATA_SIZE; + if (dasd_eckd_identify_conf_parts(&path_conf)) { + path_conf.data = NULL; + path_conf.len = 0; continue; } @@ -1382,7 +1370,7 @@ static void dasd_eckd_path_available_action(struct dasd_device *device, * the first working path UID will be used as device UID */ if (dasd_path_get_opm(device) && - dasd_eckd_compare_path_uid(device, &path_private)) { + dasd_eckd_compare_path_uid(device, &path_conf)) { /* * the comparison was not successful * rebuild the device UID with at least one @@ -1396,20 +1384,8 @@ static void dasd_eckd_path_available_action(struct dasd_device *device, */ if (rebuild_device_uid(device, data) || dasd_eckd_compare_path_uid( - device, &path_private)) { - uid = &path_private.uid; - if (strlen(uid->vduit) > 0) - snprintf(print_uid, sizeof(print_uid), - "%s.%s.%04x.%02x.%s", - uid->vendor, uid->serial, - uid->ssid, uid->real_unit_addr, - uid->vduit); - else - snprintf(print_uid, sizeof(print_uid), - "%s.%s.%04x.%02x", - uid->vendor, uid->serial, - uid->ssid, - uid->real_unit_addr); + device, &path_conf)) { + dasd_eckd_get_uid_string(&path_conf, print_uid); dev_err(&device->cdev->dev, "The newly added channel path %02X " "will not be used because it leads " @@ -1427,6 +1403,14 @@ static void dasd_eckd_path_available_action(struct dasd_device *device, if (conf_data) { memcpy(conf_data, data->rcd_buffer, DASD_ECKD_RCD_DATA_SIZE); + } else { + /* + * path is operational but path config data could not + * be stored due to low mem condition + * add it to the error path mask and schedule a path + * verification later that this could be added again + */ + epm |= lpm; } pos = pathmask_to_pos(lpm); dasd_eckd_store_conf_data(device, conf_data, pos); @@ -1447,7 +1431,10 @@ static void dasd_eckd_path_available_action(struct dasd_device *device, } dasd_path_add_nppm(device, npm); dasd_path_add_ppm(device, ppm); - dasd_path_add_tbvpm(device, epm); + if (epm) { + dasd_path_add_tbvpm(device, epm); + dasd_device_set_timer(device, 50); + } dasd_path_add_cablepm(device, cablepm); dasd_path_add_nohpfpm(device, hpfpm); spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags); @@ -1625,8 +1612,8 @@ static int dasd_eckd_read_vol_info(struct dasd_device *device) prssdp = cqr->data; prssdp->order = PSF_ORDER_PRSSD; prssdp->suborder = PSF_SUBORDER_VSQ; /* Volume Storage Query */ - prssdp->lss = private->ned->ID; - prssdp->volume = private->ned->unit_addr; + prssdp->lss = private->conf.ned->ID; + prssdp->volume = private->conf.ned->unit_addr; ccw = cqr->cpaddr; ccw->cmd_code = DASD_ECKD_CCW_PSF; @@ -2085,11 +2072,11 @@ dasd_eckd_check_characteristics(struct dasd_device *device) device->path_thrhld = DASD_ECKD_PATH_THRHLD; device->path_interval = DASD_ECKD_PATH_INTERVAL; - if (private->gneq) { + if (private->conf.gneq) { value = 1; - for (i = 0; i < private->gneq->timeout.value; i++) + for (i = 0; i < private->conf.gneq->timeout.value; i++) value = 10 * value; - value = value * private->gneq->timeout.number; + value = value * private->conf.gneq->timeout.number; /* do not accept useless values */ if (value != 0 && value <= DASD_EXPIRES_MAX) device->default_expires = value; @@ -2121,6 +2108,7 @@ dasd_eckd_check_characteristics(struct dasd_device *device) if (rc) goto out_err3; + dasd_eckd_read_fc_security(device); dasd_path_create_kobjects(device); /* Read Feature Codes */ @@ -2195,10 +2183,10 @@ static void dasd_eckd_uncheck_device(struct dasd_device *device) return; dasd_alias_disconnect_device_from_lcu(device); - private->ned = NULL; - private->sneq = NULL; - private->vdsneq = NULL; - private->gneq = NULL; + private->conf.ned = NULL; + private->conf.sneq = NULL; + private->conf.vdsneq = NULL; + private->conf.gneq = NULL; dasd_eckd_clear_conf_data(device); dasd_path_remove_kobjects(device); } @@ -3750,8 +3738,8 @@ dasd_eckd_dso_ras(struct dasd_device *device, struct dasd_block *block, * subset. */ ras_data->op_flags.guarantee_init = !!(features->feature[56] & 0x01); - ras_data->lss = private->ned->ID; - ras_data->dev_addr = private->ned->unit_addr; + ras_data->lss = private->conf.ned->ID; + ras_data->dev_addr = private->conf.ned->unit_addr; ras_data->nr_exts = nr_exts; if (by_extent) { @@ -4293,8 +4281,8 @@ static int prepare_itcw(struct itcw *itcw, memset(&pfxdata, 0, sizeof(pfxdata)); pfxdata.format = 1; /* PFX with LRE */ - pfxdata.base_address = basepriv->ned->unit_addr; - pfxdata.base_lss = basepriv->ned->ID; + pfxdata.base_address = basepriv->conf.ned->unit_addr; + pfxdata.base_lss = basepriv->conf.ned->ID; pfxdata.validity.define_extent = 1; /* private uid is kept up to date, conf_data may be outdated */ @@ -4963,9 +4951,9 @@ dasd_eckd_fill_info(struct dasd_device * device, info->characteristics_size = sizeof(private->rdc_data); memcpy(info->characteristics, &private->rdc_data, sizeof(private->rdc_data)); - info->confdata_size = min((unsigned long)private->conf_len, - sizeof(info->configuration_data)); - memcpy(info->configuration_data, private->conf_data, + info->confdata_size = min_t(unsigned long, private->conf.len, + sizeof(info->configuration_data)); + memcpy(info->configuration_data, private->conf.data, info->confdata_size); return 0; } @@ -5808,6 +5796,8 @@ static int dasd_eckd_reload_device(struct dasd_device *device) if (rc) goto out_err; + dasd_eckd_read_fc_security(device); + rc = dasd_eckd_generate_uid(device); if (rc) goto out_err; @@ -5820,15 +5810,7 @@ static int dasd_eckd_reload_device(struct dasd_device *device) dasd_eckd_get_uid(device, &uid); if (old_base != uid.base_unit_addr) { - if (strlen(uid.vduit) > 0) - snprintf(print_uid, sizeof(print_uid), - "%s.%s.%04x.%02x.%s", uid.vendor, uid.serial, - uid.ssid, uid.base_unit_addr, uid.vduit); - else - snprintf(print_uid, sizeof(print_uid), - "%s.%s.%04x.%02x", uid.vendor, uid.serial, - uid.ssid, uid.base_unit_addr); - + dasd_eckd_get_uid_string(&private->conf, print_uid); dev_info(&device->cdev->dev, "An Alias device was reassigned to a new base device " "with UID: %s\n", print_uid); @@ -5966,8 +5948,8 @@ static int dasd_eckd_query_host_access(struct dasd_device *device, prssdp->order = PSF_ORDER_PRSSD; prssdp->suborder = PSF_SUBORDER_QHA; /* query host access */ /* LSS and Volume that will be queried */ - prssdp->lss = private->ned->ID; - prssdp->volume = private->ned->unit_addr; + prssdp->lss = private->conf.ned->ID; + prssdp->volume = private->conf.ned->unit_addr; /* all other bytes of prssdp must be zero */ ccw = cqr->cpaddr; diff --git a/drivers/s390/block/dasd_eckd.h b/drivers/s390/block/dasd_eckd.h index 65e4630ad2ae..a91b265441cc 100644 --- a/drivers/s390/block/dasd_eckd.h +++ b/drivers/s390/block/dasd_eckd.h @@ -658,16 +658,19 @@ struct dasd_conf_data { struct dasd_gneq gneq; } __packed; -struct dasd_eckd_private { - struct dasd_eckd_characteristics rdc_data; - u8 *conf_data; - int conf_len; - +struct dasd_conf { + u8 *data; + int len; /* pointers to specific parts in the conf_data */ struct dasd_ned *ned; struct dasd_sneq *sneq; struct vd_sneq *vdsneq; struct dasd_gneq *gneq; +}; + +struct dasd_eckd_private { + struct dasd_eckd_characteristics rdc_data; + struct dasd_conf conf; struct eckd_count count_area[5]; int init_cqr_status; diff --git a/drivers/s390/block/dasd_erp.c b/drivers/s390/block/dasd_erp.c index ba4fa372d02d..c07e6e713518 100644 --- a/drivers/s390/block/dasd_erp.c +++ b/drivers/s390/block/dasd_erp.c @@ -24,7 +24,7 @@ #include "dasd_int.h" struct dasd_ccw_req * -dasd_alloc_erp_request(char *magic, int cplength, int datasize, +dasd_alloc_erp_request(unsigned int magic, int cplength, int datasize, struct dasd_device * device) { unsigned long flags; @@ -33,8 +33,8 @@ dasd_alloc_erp_request(char *magic, int cplength, int datasize, int size; /* Sanity checks */ - BUG_ON( magic == NULL || datasize > PAGE_SIZE || - (cplength*sizeof(struct ccw1)) > PAGE_SIZE); + BUG_ON(datasize > PAGE_SIZE || + (cplength*sizeof(struct ccw1)) > PAGE_SIZE); size = (sizeof(struct dasd_ccw_req) + 7L) & -8L; if (cplength > 0) @@ -62,7 +62,7 @@ dasd_alloc_erp_request(char *magic, int cplength, int datasize, cqr->data = data; memset(cqr->data, 0, datasize); } - strncpy((char *) &cqr->magic, magic, 4); + cqr->magic = magic; ASCEBC((char *) &cqr->magic, 4); set_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags); dasd_get_device(device); diff --git a/drivers/s390/block/dasd_genhd.c b/drivers/s390/block/dasd_genhd.c index fa966e0db6ca..3a6f3af240fa 100644 --- a/drivers/s390/block/dasd_genhd.c +++ b/drivers/s390/block/dasd_genhd.c @@ -14,6 +14,7 @@ #define KMSG_COMPONENT "dasd" #include <linux/interrupt.h> +#include <linux/major.h> #include <linux/fs.h> #include <linux/blkpg.h> diff --git a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h index 155428bfed8a..8b458010f88a 100644 --- a/drivers/s390/block/dasd_int.h +++ b/drivers/s390/block/dasd_int.h @@ -887,7 +887,7 @@ void dasd_proc_exit(void); /* externals in dasd_erp.c */ struct dasd_ccw_req *dasd_default_erp_action(struct dasd_ccw_req *); struct dasd_ccw_req *dasd_default_erp_postaction(struct dasd_ccw_req *); -struct dasd_ccw_req *dasd_alloc_erp_request(char *, int, int, +struct dasd_ccw_req *dasd_alloc_erp_request(unsigned int, int, int, struct dasd_device *); void dasd_free_erp_request(struct dasd_ccw_req *, struct dasd_device *); void dasd_log_sense(struct dasd_ccw_req *, struct irb *); @@ -1305,6 +1305,15 @@ static inline void dasd_path_add_ppm(struct dasd_device *device, __u8 pm) dasd_path_preferred(device, chp); } +static inline void dasd_path_add_fcsecpm(struct dasd_device *device, __u8 pm) +{ + int chp; + + for (chp = 0; chp < 8; chp++) + if (pm & (0x80 >> chp)) + dasd_path_fcsec(device, chp); +} + /* * set functions for path masks * the existing path mask will be replaced by the given path mask diff --git a/drivers/s390/block/dasd_ioctl.c b/drivers/s390/block/dasd_ioctl.c index 468cbeb539ff..95349f95758c 100644 --- a/drivers/s390/block/dasd_ioctl.c +++ b/drivers/s390/block/dasd_ioctl.c @@ -650,8 +650,8 @@ int dasd_ioctl(struct block_device *bdev, fmode_t mode, /** * dasd_biodasdinfo() - fill out the dasd information structure - * @disk [in]: pointer to gendisk structure that references a DASD - * @info [out]: pointer to the dasd_information2_t structure + * @disk: [in] pointer to gendisk structure that references a DASD + * @info: [out] pointer to the dasd_information2_t structure * * Provide access to DASD specific information. * The gendisk structure is checked if it belongs to the DASD driver by diff --git a/drivers/s390/block/dcssblk.c b/drivers/s390/block/dcssblk.c index 5be3d1c39a78..59e513d34b0f 100644 --- a/drivers/s390/block/dcssblk.c +++ b/drivers/s390/block/dcssblk.c @@ -30,7 +30,7 @@ static int dcssblk_open(struct block_device *bdev, fmode_t mode); static void dcssblk_release(struct gendisk *disk, fmode_t mode); -static blk_qc_t dcssblk_submit_bio(struct bio *bio); +static void dcssblk_submit_bio(struct bio *bio); static long dcssblk_dax_direct_access(struct dax_device *dax_dev, pgoff_t pgoff, long nr_pages, void **kaddr, pfn_t *pfn); @@ -854,7 +854,7 @@ dcssblk_release(struct gendisk *disk, fmode_t mode) up_write(&dcssblk_devices_sem); } -static blk_qc_t +static void dcssblk_submit_bio(struct bio *bio) { struct dcssblk_dev_info *dev_info; @@ -907,10 +907,9 @@ dcssblk_submit_bio(struct bio *bio) bytes_done += bvec.bv_len; } bio_endio(bio); - return BLK_QC_T_NONE; + return; fail: bio_io_error(bio); - return BLK_QC_T_NONE; } static long diff --git a/drivers/s390/char/sclp_early.c b/drivers/s390/char/sclp_early.c index 2f3515fa242a..f3d5c7f4c13d 100644 --- a/drivers/s390/char/sclp_early.c +++ b/drivers/s390/char/sclp_early.c @@ -45,13 +45,14 @@ static void __init sclp_early_facilities_detect(void) sclp.has_gisaf = !!(sccb->fac118 & 0x08); sclp.has_hvs = !!(sccb->fac119 & 0x80); sclp.has_kss = !!(sccb->fac98 & 0x01); - sclp.has_sipl = !!(sccb->cbl & 0x4000); if (sccb->fac85 & 0x02) S390_lowcore.machine_flags |= MACHINE_FLAG_ESOP; if (sccb->fac91 & 0x40) S390_lowcore.machine_flags |= MACHINE_FLAG_TLB_GUEST; if (sccb->cpuoff > 134) sclp.has_diag318 = !!(sccb->byte_134 & 0x80); + if (sccb->cpuoff > 137) + sclp.has_sipl = !!(sccb->cbl & 0x4000); sclp.rnmax = sccb->rnmax ? sccb->rnmax : sccb->rnmax2; sclp.rzm = sccb->rnsize ? sccb->rnsize : sccb->rnsize2; sclp.rzm <<= 20; diff --git a/drivers/s390/cio/blacklist.c b/drivers/s390/cio/blacklist.c index f3c656975e05..93695d535380 100644 --- a/drivers/s390/cio/blacklist.c +++ b/drivers/s390/cio/blacklist.c @@ -262,10 +262,12 @@ static int blacklist_parse_proc_parameters(char *buf) if (strcmp("free", parm) == 0) { rc = blacklist_parse_parameters(buf, free, 0); - /* There could be subchannels without proper devices connected. - * evaluate all the entries + /* + * Evaluate the subchannels without an online device. This way, + * no path-verification will be triggered on those subchannels + * and it avoids unnecessary delays. */ - css_schedule_eval_all(); + css_schedule_eval_cond(CSS_EVAL_NOT_ONLINE, 0); } else if (strcmp("add", parm) == 0) rc = blacklist_parse_parameters(buf, add, 0); else if (strcmp("purge", parm) == 0) diff --git a/drivers/s390/cio/ccwgroup.c b/drivers/s390/cio/ccwgroup.c index 2ec741106cb6..f0538609dfe4 100644 --- a/drivers/s390/cio/ccwgroup.c +++ b/drivers/s390/cio/ccwgroup.c @@ -77,12 +77,13 @@ EXPORT_SYMBOL(ccwgroup_set_online); /** * ccwgroup_set_offline() - disable a ccwgroup device * @gdev: target ccwgroup device + * @call_gdrv: Call the registered gdrv set_offline function * * This function attempts to put the ccwgroup device into the offline state. * Returns: * %0 on success and a negative error value on failure. */ -int ccwgroup_set_offline(struct ccwgroup_device *gdev) +int ccwgroup_set_offline(struct ccwgroup_device *gdev, bool call_gdrv) { struct ccwgroup_driver *gdrv = to_ccwgroupdrv(gdev->dev.driver); int ret = -EINVAL; @@ -91,11 +92,16 @@ int ccwgroup_set_offline(struct ccwgroup_device *gdev) return -EAGAIN; if (gdev->state == CCWGROUP_OFFLINE) goto out; + if (!call_gdrv) { + ret = 0; + goto offline; + } if (gdrv->set_offline) ret = gdrv->set_offline(gdev); if (ret) goto out; +offline: gdev->state = CCWGROUP_OFFLINE; out: atomic_set(&gdev->onoff, 0); @@ -124,7 +130,7 @@ static ssize_t ccwgroup_online_store(struct device *dev, if (value == 1) ret = ccwgroup_set_online(gdev); else if (value == 0) - ret = ccwgroup_set_offline(gdev); + ret = ccwgroup_set_offline(gdev, true); else ret = -EINVAL; out: diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c index 3377097e65de..44461928aab8 100644 --- a/drivers/s390/cio/css.c +++ b/drivers/s390/cio/css.c @@ -788,27 +788,49 @@ static int __unset_registered(struct device *dev, void *data) return 0; } -void css_schedule_eval_all_unreg(unsigned long delay) +static int __unset_online(struct device *dev, void *data) +{ + struct idset *set = data; + struct subchannel *sch = to_subchannel(dev); + struct ccw_device *cdev = sch_get_cdev(sch); + + if (cdev && cdev->online) + idset_sch_del(set, sch->schid); + + return 0; +} + +void css_schedule_eval_cond(enum css_eval_cond cond, unsigned long delay) { unsigned long flags; - struct idset *unreg_set; + struct idset *set; /* Find unregistered subchannels. */ - unreg_set = idset_sch_new(); - if (!unreg_set) { + set = idset_sch_new(); + if (!set) { /* Fallback. */ css_schedule_eval_all(); return; } - idset_fill(unreg_set); - bus_for_each_dev(&css_bus_type, NULL, unreg_set, __unset_registered); + idset_fill(set); + switch (cond) { + case CSS_EVAL_UNREG: + bus_for_each_dev(&css_bus_type, NULL, set, __unset_registered); + break; + case CSS_EVAL_NOT_ONLINE: + bus_for_each_dev(&css_bus_type, NULL, set, __unset_online); + break; + default: + break; + } + /* Apply to slow_subchannel_set. */ spin_lock_irqsave(&slow_subchannel_lock, flags); - idset_add_set(slow_subchannel_set, unreg_set); + idset_add_set(slow_subchannel_set, set); atomic_set(&css_eval_scheduled, 1); queue_delayed_work(cio_work_q, &slow_path_work, delay); spin_unlock_irqrestore(&slow_subchannel_lock, flags); - idset_free(unreg_set); + idset_free(set); } void css_wait_for_slow_path(void) @@ -820,7 +842,7 @@ void css_wait_for_slow_path(void) void css_schedule_reprobe(void) { /* Schedule with a delay to allow merging of subsequent calls. */ - css_schedule_eval_all_unreg(1 * HZ); + css_schedule_eval_cond(CSS_EVAL_UNREG, 1 * HZ); } EXPORT_SYMBOL_GPL(css_schedule_reprobe); diff --git a/drivers/s390/cio/css.h b/drivers/s390/cio/css.h index c98522cbe276..ede0b905bc6f 100644 --- a/drivers/s390/cio/css.h +++ b/drivers/s390/cio/css.h @@ -34,6 +34,14 @@ #define SNID_STATE3_MULTI_PATH 1 #define SNID_STATE3_SINGLE_PATH 0 +/* + * Conditions used to specify which subchannels need evaluation + */ +enum css_eval_cond { + CSS_EVAL_UNREG, /* unregistered subchannels */ + CSS_EVAL_NOT_ONLINE /* sch without an online-device */ +}; + struct path_state { __u8 state1 : 2; /* path state value 1 */ __u8 state2 : 2; /* path state value 2 */ @@ -136,7 +144,7 @@ static inline struct channel_subsystem *css_by_id(u8 cssid) /* Helper functions to build lists for the slow path. */ void css_schedule_eval(struct subchannel_id schid); void css_schedule_eval_all(void); -void css_schedule_eval_all_unreg(unsigned long delay); +void css_schedule_eval_cond(enum css_eval_cond, unsigned long delay); int css_complete_work(void); int sch_is_pseudo_sch(struct subchannel *); diff --git a/drivers/s390/cio/qdio_setup.c b/drivers/s390/cio/qdio_setup.c index 20efafe47897..efbb5e5eca05 100644 --- a/drivers/s390/cio/qdio_setup.c +++ b/drivers/s390/cio/qdio_setup.c @@ -24,19 +24,6 @@ #define QBUFF_PER_PAGE (PAGE_SIZE / sizeof(struct qdio_buffer)) static struct kmem_cache *qdio_q_cache; -static struct kmem_cache *qdio_aob_cache; - -struct qaob *qdio_allocate_aob(void) -{ - return kmem_cache_zalloc(qdio_aob_cache, GFP_ATOMIC); -} -EXPORT_SYMBOL_GPL(qdio_allocate_aob); - -void qdio_release_aob(struct qaob *aob) -{ - kmem_cache_free(qdio_aob_cache, aob); -} -EXPORT_SYMBOL_GPL(qdio_release_aob); /** * qdio_free_buffers() - free qdio buffers @@ -447,39 +434,22 @@ void qdio_print_subchannel_info(struct qdio_irq *irq_ptr) int __init qdio_setup_init(void) { - int rc; - qdio_q_cache = kmem_cache_create("qdio_q", sizeof(struct qdio_q), 256, 0, NULL); if (!qdio_q_cache) return -ENOMEM; - qdio_aob_cache = kmem_cache_create("qdio_aob", - sizeof(struct qaob), - sizeof(struct qaob), - 0, - NULL); - if (!qdio_aob_cache) { - rc = -ENOMEM; - goto free_qdio_q_cache; - } - /* Check for OSA/FCP thin interrupts (bit 67). */ DBF_EVENT("thinint:%1d", (css_general_characteristics.aif_osa) ? 1 : 0); /* Check for QEBSM support in general (bit 58). */ DBF_EVENT("cssQEBSM:%1d", css_general_characteristics.qebsm); - rc = 0; -out: - return rc; -free_qdio_q_cache: - kmem_cache_destroy(qdio_q_cache); - goto out; + + return 0; } void qdio_setup_exit(void) { - kmem_cache_destroy(qdio_aob_cache); kmem_cache_destroy(qdio_q_cache); } diff --git a/drivers/s390/cio/vfio_ccw_drv.c b/drivers/s390/cio/vfio_ccw_drv.c index 76099bcb765b..040742777095 100644 --- a/drivers/s390/cio/vfio_ccw_drv.c +++ b/drivers/s390/cio/vfio_ccw_drv.c @@ -137,77 +137,107 @@ static void vfio_ccw_sch_irq(struct subchannel *sch) vfio_ccw_fsm_event(private, VFIO_CCW_EVENT_INTERRUPT); } -static void vfio_ccw_free_regions(struct vfio_ccw_private *private) +static struct vfio_ccw_private *vfio_ccw_alloc_private(struct subchannel *sch) { - if (private->crw_region) - kmem_cache_free(vfio_ccw_crw_region, private->crw_region); - if (private->schib_region) - kmem_cache_free(vfio_ccw_schib_region, private->schib_region); - if (private->cmd_region) - kmem_cache_free(vfio_ccw_cmd_region, private->cmd_region); - if (private->io_region) - kmem_cache_free(vfio_ccw_io_region, private->io_region); -} - -static int vfio_ccw_sch_probe(struct subchannel *sch) -{ - struct pmcw *pmcw = &sch->schib.pmcw; struct vfio_ccw_private *private; - int ret = -ENOMEM; - if (pmcw->qf) { - dev_warn(&sch->dev, "vfio: ccw: does not support QDIO: %s\n", - dev_name(&sch->dev)); - return -ENODEV; - } - - private = kzalloc(sizeof(*private), GFP_KERNEL | GFP_DMA); + private = kzalloc(sizeof(*private), GFP_KERNEL); if (!private) - return -ENOMEM; + return ERR_PTR(-ENOMEM); + + private->sch = sch; + mutex_init(&private->io_mutex); + private->state = VFIO_CCW_STATE_NOT_OPER; + INIT_LIST_HEAD(&private->crw); + INIT_WORK(&private->io_work, vfio_ccw_sch_io_todo); + INIT_WORK(&private->crw_work, vfio_ccw_crw_todo); + atomic_set(&private->avail, 1); private->cp.guest_cp = kcalloc(CCWCHAIN_LEN_MAX, sizeof(struct ccw1), GFP_KERNEL); if (!private->cp.guest_cp) - goto out_free; + goto out_free_private; private->io_region = kmem_cache_zalloc(vfio_ccw_io_region, GFP_KERNEL | GFP_DMA); if (!private->io_region) - goto out_free; + goto out_free_cp; private->cmd_region = kmem_cache_zalloc(vfio_ccw_cmd_region, GFP_KERNEL | GFP_DMA); if (!private->cmd_region) - goto out_free; + goto out_free_io; private->schib_region = kmem_cache_zalloc(vfio_ccw_schib_region, GFP_KERNEL | GFP_DMA); if (!private->schib_region) - goto out_free; + goto out_free_cmd; private->crw_region = kmem_cache_zalloc(vfio_ccw_crw_region, GFP_KERNEL | GFP_DMA); if (!private->crw_region) - goto out_free; + goto out_free_schib; + return private; + +out_free_schib: + kmem_cache_free(vfio_ccw_schib_region, private->schib_region); +out_free_cmd: + kmem_cache_free(vfio_ccw_cmd_region, private->cmd_region); +out_free_io: + kmem_cache_free(vfio_ccw_io_region, private->io_region); +out_free_cp: + kfree(private->cp.guest_cp); +out_free_private: + mutex_destroy(&private->io_mutex); + kfree(private); + return ERR_PTR(-ENOMEM); +} + +static void vfio_ccw_free_private(struct vfio_ccw_private *private) +{ + struct vfio_ccw_crw *crw, *temp; + + list_for_each_entry_safe(crw, temp, &private->crw, next) { + list_del(&crw->next); + kfree(crw); + } + + kmem_cache_free(vfio_ccw_crw_region, private->crw_region); + kmem_cache_free(vfio_ccw_schib_region, private->schib_region); + kmem_cache_free(vfio_ccw_cmd_region, private->cmd_region); + kmem_cache_free(vfio_ccw_io_region, private->io_region); + kfree(private->cp.guest_cp); + mutex_destroy(&private->io_mutex); + kfree(private); +} + +static int vfio_ccw_sch_probe(struct subchannel *sch) +{ + struct pmcw *pmcw = &sch->schib.pmcw; + struct vfio_ccw_private *private; + int ret = -ENOMEM; + + if (pmcw->qf) { + dev_warn(&sch->dev, "vfio: ccw: does not support QDIO: %s\n", + dev_name(&sch->dev)); + return -ENODEV; + } + + private = vfio_ccw_alloc_private(sch); + if (IS_ERR(private)) + return PTR_ERR(private); - private->sch = sch; dev_set_drvdata(&sch->dev, private); - mutex_init(&private->io_mutex); spin_lock_irq(sch->lock); - private->state = VFIO_CCW_STATE_NOT_OPER; sch->isc = VFIO_CCW_ISC; ret = cio_enable_subchannel(sch, (u32)(unsigned long)sch); spin_unlock_irq(sch->lock); if (ret) goto out_free; - INIT_LIST_HEAD(&private->crw); - INIT_WORK(&private->io_work, vfio_ccw_sch_io_todo); - INIT_WORK(&private->crw_work, vfio_ccw_crw_todo); - atomic_set(&private->avail, 1); private->state = VFIO_CCW_STATE_STANDBY; ret = vfio_ccw_mdev_reg(sch); @@ -228,31 +258,20 @@ out_disable: cio_disable_subchannel(sch); out_free: dev_set_drvdata(&sch->dev, NULL); - vfio_ccw_free_regions(private); - kfree(private->cp.guest_cp); - kfree(private); + vfio_ccw_free_private(private); return ret; } static void vfio_ccw_sch_remove(struct subchannel *sch) { struct vfio_ccw_private *private = dev_get_drvdata(&sch->dev); - struct vfio_ccw_crw *crw, *temp; vfio_ccw_sch_quiesce(sch); - - list_for_each_entry_safe(crw, temp, &private->crw, next) { - list_del(&crw->next); - kfree(crw); - } - vfio_ccw_mdev_unreg(sch); dev_set_drvdata(&sch->dev, NULL); - vfio_ccw_free_regions(private); - kfree(private->cp.guest_cp); - kfree(private); + vfio_ccw_free_private(private); VFIO_CCW_MSG_EVENT(4, "unbound from subchannel %x.%x.%04x\n", sch->schid.cssid, sch->schid.ssid, @@ -449,7 +468,7 @@ static int __init vfio_ccw_sch_init(void) vfio_ccw_work_q = create_singlethread_workqueue("vfio-ccw"); if (!vfio_ccw_work_q) { ret = -ENOMEM; - goto out_err; + goto out_regions; } vfio_ccw_io_region = kmem_cache_create_usercopy("vfio_ccw_io_region", @@ -458,7 +477,7 @@ static int __init vfio_ccw_sch_init(void) sizeof(struct ccw_io_region), NULL); if (!vfio_ccw_io_region) { ret = -ENOMEM; - goto out_err; + goto out_regions; } vfio_ccw_cmd_region = kmem_cache_create_usercopy("vfio_ccw_cmd_region", @@ -467,7 +486,7 @@ static int __init vfio_ccw_sch_init(void) sizeof(struct ccw_cmd_region), NULL); if (!vfio_ccw_cmd_region) { ret = -ENOMEM; - goto out_err; + goto out_regions; } vfio_ccw_schib_region = kmem_cache_create_usercopy("vfio_ccw_schib_region", @@ -477,7 +496,7 @@ static int __init vfio_ccw_sch_init(void) if (!vfio_ccw_schib_region) { ret = -ENOMEM; - goto out_err; + goto out_regions; } vfio_ccw_crw_region = kmem_cache_create_usercopy("vfio_ccw_crw_region", @@ -487,19 +506,25 @@ static int __init vfio_ccw_sch_init(void) if (!vfio_ccw_crw_region) { ret = -ENOMEM; - goto out_err; + goto out_regions; } + ret = mdev_register_driver(&vfio_ccw_mdev_driver); + if (ret) + goto out_regions; + isc_register(VFIO_CCW_ISC); ret = css_driver_register(&vfio_ccw_sch_driver); if (ret) { isc_unregister(VFIO_CCW_ISC); - goto out_err; + goto out_driver; } return ret; -out_err: +out_driver: + mdev_unregister_driver(&vfio_ccw_mdev_driver); +out_regions: vfio_ccw_destroy_regions(); destroy_workqueue(vfio_ccw_work_q); vfio_ccw_debug_exit(); @@ -509,6 +534,7 @@ out_err: static void __exit vfio_ccw_sch_exit(void) { css_driver_unregister(&vfio_ccw_sch_driver); + mdev_unregister_driver(&vfio_ccw_mdev_driver); isc_unregister(VFIO_CCW_ISC); vfio_ccw_destroy_regions(); destroy_workqueue(vfio_ccw_work_q); diff --git a/drivers/s390/cio/vfio_ccw_ops.c b/drivers/s390/cio/vfio_ccw_ops.c index 7f540ad0b568..d8589afac272 100644 --- a/drivers/s390/cio/vfio_ccw_ops.c +++ b/drivers/s390/cio/vfio_ccw_ops.c @@ -17,13 +17,13 @@ #include "vfio_ccw_private.h" -static int vfio_ccw_mdev_reset(struct mdev_device *mdev) +static const struct vfio_device_ops vfio_ccw_dev_ops; + +static int vfio_ccw_mdev_reset(struct vfio_ccw_private *private) { - struct vfio_ccw_private *private; struct subchannel *sch; int ret; - private = dev_get_drvdata(mdev_parent_dev(mdev)); sch = private->sch; /* * TODO: @@ -61,7 +61,7 @@ static int vfio_ccw_mdev_notifier(struct notifier_block *nb, if (!cp_iova_pinned(&private->cp, unmap->iova)) return NOTIFY_OK; - if (vfio_ccw_mdev_reset(private->mdev)) + if (vfio_ccw_mdev_reset(private)) return NOTIFY_BAD; cp_free(&private->cp); @@ -113,10 +113,10 @@ static struct attribute_group *mdev_type_groups[] = { NULL, }; -static int vfio_ccw_mdev_create(struct mdev_device *mdev) +static int vfio_ccw_mdev_probe(struct mdev_device *mdev) { - struct vfio_ccw_private *private = - dev_get_drvdata(mdev_parent_dev(mdev)); + struct vfio_ccw_private *private = dev_get_drvdata(mdev->dev.parent); + int ret; if (private->state == VFIO_CCW_STATE_NOT_OPER) return -ENODEV; @@ -124,6 +124,10 @@ static int vfio_ccw_mdev_create(struct mdev_device *mdev) if (atomic_dec_if_positive(&private->avail) < 0) return -EPERM; + memset(&private->vdev, 0, sizeof(private->vdev)); + vfio_init_group_dev(&private->vdev, &mdev->dev, + &vfio_ccw_dev_ops); + private->mdev = mdev; private->state = VFIO_CCW_STATE_IDLE; @@ -132,19 +136,31 @@ static int vfio_ccw_mdev_create(struct mdev_device *mdev) private->sch->schid.ssid, private->sch->schid.sch_no); + ret = vfio_register_emulated_iommu_dev(&private->vdev); + if (ret) + goto err_atomic; + dev_set_drvdata(&mdev->dev, private); return 0; + +err_atomic: + vfio_uninit_group_dev(&private->vdev); + atomic_inc(&private->avail); + private->mdev = NULL; + private->state = VFIO_CCW_STATE_IDLE; + return ret; } -static int vfio_ccw_mdev_remove(struct mdev_device *mdev) +static void vfio_ccw_mdev_remove(struct mdev_device *mdev) { - struct vfio_ccw_private *private = - dev_get_drvdata(mdev_parent_dev(mdev)); + struct vfio_ccw_private *private = dev_get_drvdata(mdev->dev.parent); VFIO_CCW_MSG_EVENT(2, "mdev %pUl, sch %x.%x.%04x: remove\n", mdev_uuid(mdev), private->sch->schid.cssid, private->sch->schid.ssid, private->sch->schid.sch_no); + vfio_unregister_group_dev(&private->vdev); + if ((private->state != VFIO_CCW_STATE_NOT_OPER) && (private->state != VFIO_CCW_STATE_STANDBY)) { if (!vfio_ccw_sch_quiesce(private->sch)) @@ -152,23 +168,22 @@ static int vfio_ccw_mdev_remove(struct mdev_device *mdev) /* The state will be NOT_OPER on error. */ } + vfio_uninit_group_dev(&private->vdev); cp_free(&private->cp); private->mdev = NULL; atomic_inc(&private->avail); - - return 0; } -static int vfio_ccw_mdev_open_device(struct mdev_device *mdev) +static int vfio_ccw_mdev_open_device(struct vfio_device *vdev) { struct vfio_ccw_private *private = - dev_get_drvdata(mdev_parent_dev(mdev)); + container_of(vdev, struct vfio_ccw_private, vdev); unsigned long events = VFIO_IOMMU_NOTIFY_DMA_UNMAP; int ret; private->nb.notifier_call = vfio_ccw_mdev_notifier; - ret = vfio_register_notifier(mdev_dev(mdev), VFIO_IOMMU_NOTIFY, + ret = vfio_register_notifier(vdev->dev, VFIO_IOMMU_NOTIFY, &events, &private->nb); if (ret) return ret; @@ -189,27 +204,26 @@ static int vfio_ccw_mdev_open_device(struct mdev_device *mdev) out_unregister: vfio_ccw_unregister_dev_regions(private); - vfio_unregister_notifier(mdev_dev(mdev), VFIO_IOMMU_NOTIFY, + vfio_unregister_notifier(vdev->dev, VFIO_IOMMU_NOTIFY, &private->nb); return ret; } -static void vfio_ccw_mdev_close_device(struct mdev_device *mdev) +static void vfio_ccw_mdev_close_device(struct vfio_device *vdev) { struct vfio_ccw_private *private = - dev_get_drvdata(mdev_parent_dev(mdev)); + container_of(vdev, struct vfio_ccw_private, vdev); if ((private->state != VFIO_CCW_STATE_NOT_OPER) && (private->state != VFIO_CCW_STATE_STANDBY)) { - if (!vfio_ccw_mdev_reset(mdev)) + if (!vfio_ccw_mdev_reset(private)) private->state = VFIO_CCW_STATE_STANDBY; /* The state will be NOT_OPER on error. */ } cp_free(&private->cp); vfio_ccw_unregister_dev_regions(private); - vfio_unregister_notifier(mdev_dev(mdev), VFIO_IOMMU_NOTIFY, - &private->nb); + vfio_unregister_notifier(vdev->dev, VFIO_IOMMU_NOTIFY, &private->nb); } static ssize_t vfio_ccw_mdev_read_io_region(struct vfio_ccw_private *private, @@ -233,15 +247,14 @@ static ssize_t vfio_ccw_mdev_read_io_region(struct vfio_ccw_private *private, return ret; } -static ssize_t vfio_ccw_mdev_read(struct mdev_device *mdev, +static ssize_t vfio_ccw_mdev_read(struct vfio_device *vdev, char __user *buf, size_t count, loff_t *ppos) { + struct vfio_ccw_private *private = + container_of(vdev, struct vfio_ccw_private, vdev); unsigned int index = VFIO_CCW_OFFSET_TO_INDEX(*ppos); - struct vfio_ccw_private *private; - - private = dev_get_drvdata(mdev_parent_dev(mdev)); if (index >= VFIO_CCW_NUM_REGIONS + private->num_regions) return -EINVAL; @@ -286,15 +299,14 @@ out_unlock: return ret; } -static ssize_t vfio_ccw_mdev_write(struct mdev_device *mdev, +static ssize_t vfio_ccw_mdev_write(struct vfio_device *vdev, const char __user *buf, size_t count, loff_t *ppos) { + struct vfio_ccw_private *private = + container_of(vdev, struct vfio_ccw_private, vdev); unsigned int index = VFIO_CCW_OFFSET_TO_INDEX(*ppos); - struct vfio_ccw_private *private; - - private = dev_get_drvdata(mdev_parent_dev(mdev)); if (index >= VFIO_CCW_NUM_REGIONS + private->num_regions) return -EINVAL; @@ -311,12 +323,9 @@ static ssize_t vfio_ccw_mdev_write(struct mdev_device *mdev, return -EINVAL; } -static int vfio_ccw_mdev_get_device_info(struct vfio_device_info *info, - struct mdev_device *mdev) +static int vfio_ccw_mdev_get_device_info(struct vfio_ccw_private *private, + struct vfio_device_info *info) { - struct vfio_ccw_private *private; - - private = dev_get_drvdata(mdev_parent_dev(mdev)); info->flags = VFIO_DEVICE_FLAGS_CCW | VFIO_DEVICE_FLAGS_RESET; info->num_regions = VFIO_CCW_NUM_REGIONS + private->num_regions; info->num_irqs = VFIO_CCW_NUM_IRQS; @@ -324,14 +333,12 @@ static int vfio_ccw_mdev_get_device_info(struct vfio_device_info *info, return 0; } -static int vfio_ccw_mdev_get_region_info(struct vfio_region_info *info, - struct mdev_device *mdev, +static int vfio_ccw_mdev_get_region_info(struct vfio_ccw_private *private, + struct vfio_region_info *info, unsigned long arg) { - struct vfio_ccw_private *private; int i; - private = dev_get_drvdata(mdev_parent_dev(mdev)); switch (info->index) { case VFIO_CCW_CONFIG_REGION_INDEX: info->offset = 0; @@ -406,19 +413,16 @@ static int vfio_ccw_mdev_get_irq_info(struct vfio_irq_info *info) return 0; } -static int vfio_ccw_mdev_set_irqs(struct mdev_device *mdev, +static int vfio_ccw_mdev_set_irqs(struct vfio_ccw_private *private, uint32_t flags, uint32_t index, void __user *data) { - struct vfio_ccw_private *private; struct eventfd_ctx **ctx; if (!(flags & VFIO_IRQ_SET_ACTION_TRIGGER)) return -EINVAL; - private = dev_get_drvdata(mdev_parent_dev(mdev)); - switch (index) { case VFIO_CCW_IO_IRQ_INDEX: ctx = &private->io_trigger; @@ -520,10 +524,12 @@ void vfio_ccw_unregister_dev_regions(struct vfio_ccw_private *private) private->region = NULL; } -static ssize_t vfio_ccw_mdev_ioctl(struct mdev_device *mdev, +static ssize_t vfio_ccw_mdev_ioctl(struct vfio_device *vdev, unsigned int cmd, unsigned long arg) { + struct vfio_ccw_private *private = + container_of(vdev, struct vfio_ccw_private, vdev); int ret = 0; unsigned long minsz; @@ -540,7 +546,7 @@ static ssize_t vfio_ccw_mdev_ioctl(struct mdev_device *mdev, if (info.argsz < minsz) return -EINVAL; - ret = vfio_ccw_mdev_get_device_info(&info, mdev); + ret = vfio_ccw_mdev_get_device_info(private, &info); if (ret) return ret; @@ -558,7 +564,7 @@ static ssize_t vfio_ccw_mdev_ioctl(struct mdev_device *mdev, if (info.argsz < minsz) return -EINVAL; - ret = vfio_ccw_mdev_get_region_info(&info, mdev, arg); + ret = vfio_ccw_mdev_get_region_info(private, &info, arg); if (ret) return ret; @@ -603,47 +609,59 @@ static ssize_t vfio_ccw_mdev_ioctl(struct mdev_device *mdev, return ret; data = (void __user *)(arg + minsz); - return vfio_ccw_mdev_set_irqs(mdev, hdr.flags, hdr.index, data); + return vfio_ccw_mdev_set_irqs(private, hdr.flags, hdr.index, + data); } case VFIO_DEVICE_RESET: - return vfio_ccw_mdev_reset(mdev); + return vfio_ccw_mdev_reset(private); default: return -ENOTTY; } } /* Request removal of the device*/ -static void vfio_ccw_mdev_request(struct mdev_device *mdev, unsigned int count) +static void vfio_ccw_mdev_request(struct vfio_device *vdev, unsigned int count) { - struct vfio_ccw_private *private = dev_get_drvdata(mdev_parent_dev(mdev)); - - if (!private) - return; + struct vfio_ccw_private *private = + container_of(vdev, struct vfio_ccw_private, vdev); + struct device *dev = vdev->dev; if (private->req_trigger) { if (!(count % 10)) - dev_notice_ratelimited(mdev_dev(private->mdev), + dev_notice_ratelimited(dev, "Relaying device request to user (#%u)\n", count); eventfd_signal(private->req_trigger, 1); } else if (count == 0) { - dev_notice(mdev_dev(private->mdev), + dev_notice(dev, "No device request channel registered, blocked until released by user\n"); } } +static const struct vfio_device_ops vfio_ccw_dev_ops = { + .open_device = vfio_ccw_mdev_open_device, + .close_device = vfio_ccw_mdev_close_device, + .read = vfio_ccw_mdev_read, + .write = vfio_ccw_mdev_write, + .ioctl = vfio_ccw_mdev_ioctl, + .request = vfio_ccw_mdev_request, +}; + +struct mdev_driver vfio_ccw_mdev_driver = { + .driver = { + .name = "vfio_ccw_mdev", + .owner = THIS_MODULE, + .mod_name = KBUILD_MODNAME, + }, + .probe = vfio_ccw_mdev_probe, + .remove = vfio_ccw_mdev_remove, +}; + static const struct mdev_parent_ops vfio_ccw_mdev_ops = { .owner = THIS_MODULE, + .device_driver = &vfio_ccw_mdev_driver, .supported_type_groups = mdev_type_groups, - .create = vfio_ccw_mdev_create, - .remove = vfio_ccw_mdev_remove, - .open_device = vfio_ccw_mdev_open_device, - .close_device = vfio_ccw_mdev_close_device, - .read = vfio_ccw_mdev_read, - .write = vfio_ccw_mdev_write, - .ioctl = vfio_ccw_mdev_ioctl, - .request = vfio_ccw_mdev_request, }; int vfio_ccw_mdev_reg(struct subchannel *sch) diff --git a/drivers/s390/cio/vfio_ccw_private.h b/drivers/s390/cio/vfio_ccw_private.h index b2c762eb42b9..7272eb788612 100644 --- a/drivers/s390/cio/vfio_ccw_private.h +++ b/drivers/s390/cio/vfio_ccw_private.h @@ -17,6 +17,7 @@ #include <linux/eventfd.h> #include <linux/workqueue.h> #include <linux/vfio_ccw.h> +#include <linux/vfio.h> #include <asm/crw.h> #include <asm/debug.h> @@ -67,6 +68,7 @@ struct vfio_ccw_crw { /** * struct vfio_ccw_private + * @vdev: Embedded VFIO device * @sch: pointer to the subchannel * @state: internal state of the device * @completion: synchronization helper of the I/O completion @@ -90,6 +92,7 @@ struct vfio_ccw_crw { * @crw_work: work for deferral process of CRW handling */ struct vfio_ccw_private { + struct vfio_device vdev; struct subchannel *sch; int state; struct completion *completion; @@ -121,6 +124,8 @@ extern void vfio_ccw_mdev_unreg(struct subchannel *sch); extern int vfio_ccw_sch_quiesce(struct subchannel *sch); +extern struct mdev_driver vfio_ccw_mdev_driver; + /* * States of the device statemachine. */ diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c index f433428057d9..d9b804943d19 100644 --- a/drivers/s390/crypto/ap_bus.c +++ b/drivers/s390/crypto/ap_bus.c @@ -213,7 +213,6 @@ static inline int ap_fetch_qci_info(struct ap_config_info *info) * ap_init_qci_info(): Allocate and query qci config info. * Does also update the static variables ap_max_domain_id * and ap_max_adapter_id if this info is available. - */ static void __init ap_init_qci_info(void) { @@ -439,6 +438,7 @@ static enum hrtimer_restart ap_poll_timeout(struct hrtimer *unused) /** * ap_interrupt_handler() - Schedule ap_tasklet on interrupt * @airq: pointer to adapter interrupt descriptor + * @floating: ignored */ static void ap_interrupt_handler(struct airq_struct *airq, bool floating) { @@ -1786,6 +1786,7 @@ static inline void ap_scan_adapter(int ap) /** * ap_scan_bus(): Scan the AP bus for new devices * Runs periodically, workqueue timer (ap_config_time) + * @unused: Unused pointer. */ static void ap_scan_bus(struct work_struct *unused) { diff --git a/drivers/s390/crypto/ap_queue.c b/drivers/s390/crypto/ap_queue.c index d70c4d3d0907..9ea48bf0ee40 100644 --- a/drivers/s390/crypto/ap_queue.c +++ b/drivers/s390/crypto/ap_queue.c @@ -20,7 +20,7 @@ static void __ap_flush_queue(struct ap_queue *aq); /** * ap_queue_enable_irq(): Enable interrupt support on this AP queue. - * @qid: The AP queue number + * @aq: The AP queue * @ind: the notification indicator byte * * Enables interruption on AP queue via ap_aqic(). Based on the return @@ -311,7 +311,7 @@ static enum ap_sm_wait ap_sm_read_write(struct ap_queue *aq) /** * ap_sm_reset(): Reset an AP queue. - * @qid: The AP queue number + * @aq: The AP queue * * Submit the Reset command to an AP queue. */ diff --git a/drivers/s390/crypto/vfio_ap_ops.c b/drivers/s390/crypto/vfio_ap_ops.c index 118939a7729a..2341425f6967 100644 --- a/drivers/s390/crypto/vfio_ap_ops.c +++ b/drivers/s390/crypto/vfio_ap_ops.c @@ -351,7 +351,7 @@ static int vfio_ap_mdev_probe(struct mdev_device *mdev) list_add(&matrix_mdev->node, &matrix_dev->mdev_list); mutex_unlock(&matrix_dev->lock); - ret = vfio_register_group_dev(&matrix_mdev->vdev); + ret = vfio_register_emulated_iommu_dev(&matrix_mdev->vdev); if (ret) goto err_list; dev_set_drvdata(&mdev->dev, matrix_mdev); @@ -361,6 +361,7 @@ err_list: mutex_lock(&matrix_dev->lock); list_del(&matrix_mdev->node); mutex_unlock(&matrix_dev->lock); + vfio_uninit_group_dev(&matrix_mdev->vdev); kfree(matrix_mdev); err_dec_available: atomic_inc(&matrix_dev->available_instances); @@ -376,9 +377,10 @@ static void vfio_ap_mdev_remove(struct mdev_device *mdev) mutex_lock(&matrix_dev->lock); vfio_ap_mdev_reset_queues(matrix_mdev); list_del(&matrix_mdev->node); + mutex_unlock(&matrix_dev->lock); + vfio_uninit_group_dev(&matrix_mdev->vdev); kfree(matrix_mdev); atomic_inc(&matrix_dev->available_instances); - mutex_unlock(&matrix_dev->lock); } static ssize_t name_show(struct mdev_type *mtype, diff --git a/drivers/s390/net/ctcm_fsms.c b/drivers/s390/net/ctcm_fsms.c index 06281a0a0552..de2423c72b02 100644 --- a/drivers/s390/net/ctcm_fsms.c +++ b/drivers/s390/net/ctcm_fsms.c @@ -182,7 +182,7 @@ static void ctcmpc_chx_attnbusy(fsm_instance *, int, void *); static void ctcmpc_chx_resend(fsm_instance *, int, void *); static void ctcmpc_chx_send_sweep(fsm_instance *fsm, int event, void *arg); -/** +/* * Check return code of a preceding ccw_device call, halt_IO etc... * * ch : The channel, the error belongs to. @@ -223,7 +223,7 @@ void ctcm_purge_skb_queue(struct sk_buff_head *q) } } -/** +/* * NOP action for statemachines */ static void ctcm_action_nop(fsm_instance *fi, int event, void *arg) @@ -234,7 +234,7 @@ static void ctcm_action_nop(fsm_instance *fi, int event, void *arg) * Actions for channel - statemachines. */ -/** +/* * Normal data has been send. Free the corresponding * skb (it's in io_queue), reset dev->tbusy and * revert to idle state. @@ -322,7 +322,7 @@ static void chx_txdone(fsm_instance *fi, int event, void *arg) ctcm_clear_busy_do(dev); } -/** +/* * Initial data is sent. * Notify device statemachine that we are up and * running. @@ -344,7 +344,7 @@ void ctcm_chx_txidle(fsm_instance *fi, int event, void *arg) fsm_event(priv->fsm, DEV_EVENT_TXUP, ch->netdev); } -/** +/* * Got normal data, check for sanity, queue it up, allocate new buffer * trigger bottom half, and initiate next read. * @@ -421,7 +421,7 @@ static void chx_rx(fsm_instance *fi, int event, void *arg) ctcm_ccw_check_rc(ch, rc, "normal RX"); } -/** +/* * Initialize connection by sending a __u16 of value 0. * * fi An instance of a channel statemachine. @@ -497,7 +497,7 @@ static void chx_firstio(fsm_instance *fi, int event, void *arg) } } -/** +/* * Got initial data, check it. If OK, * notify device statemachine that we are up and * running. @@ -538,7 +538,7 @@ static void chx_rxidle(fsm_instance *fi, int event, void *arg) } } -/** +/* * Set channel into extended mode. * * fi An instance of a channel statemachine. @@ -578,7 +578,7 @@ static void ctcm_chx_setmode(fsm_instance *fi, int event, void *arg) ch->retry = 0; } -/** +/* * Setup channel. * * fi An instance of a channel statemachine. @@ -641,7 +641,7 @@ static void ctcm_chx_start(fsm_instance *fi, int event, void *arg) } } -/** +/* * Shutdown a channel. * * fi An instance of a channel statemachine. @@ -682,7 +682,7 @@ static void ctcm_chx_haltio(fsm_instance *fi, int event, void *arg) } } -/** +/* * Cleanup helper for chx_fail and chx_stopped * cleanup channels queue and notify interface statemachine. * @@ -728,7 +728,7 @@ static void ctcm_chx_cleanup(fsm_instance *fi, int state, } } -/** +/* * A channel has successfully been halted. * Cleanup it's queue and notify interface statemachine. * @@ -741,7 +741,7 @@ static void ctcm_chx_stopped(fsm_instance *fi, int event, void *arg) ctcm_chx_cleanup(fi, CTC_STATE_STOPPED, arg); } -/** +/* * A stop command from device statemachine arrived and we are in * not operational mode. Set state to stopped. * @@ -754,7 +754,7 @@ static void ctcm_chx_stop(fsm_instance *fi, int event, void *arg) fsm_newstate(fi, CTC_STATE_STOPPED); } -/** +/* * A machine check for no path, not operational status or gone device has * happened. * Cleanup queue and notify interface statemachine. @@ -768,7 +768,7 @@ static void ctcm_chx_fail(fsm_instance *fi, int event, void *arg) ctcm_chx_cleanup(fi, CTC_STATE_NOTOP, arg); } -/** +/* * Handle error during setup of channel. * * fi An instance of a channel statemachine. @@ -817,7 +817,7 @@ static void ctcm_chx_setuperr(fsm_instance *fi, int event, void *arg) } } -/** +/* * Restart a channel after an error. * * fi An instance of a channel statemachine. @@ -858,7 +858,7 @@ static void ctcm_chx_restart(fsm_instance *fi, int event, void *arg) } } -/** +/* * Handle error during RX initial handshake (exchange of * 0-length block header) * @@ -893,7 +893,7 @@ static void ctcm_chx_rxiniterr(fsm_instance *fi, int event, void *arg) } } -/** +/* * Notify device statemachine if we gave up initialization * of RX channel. * @@ -914,7 +914,7 @@ static void ctcm_chx_rxinitfail(fsm_instance *fi, int event, void *arg) fsm_event(priv->fsm, DEV_EVENT_RXDOWN, dev); } -/** +/* * Handle RX Unit check remote reset (remote disconnected) * * fi An instance of a channel statemachine. @@ -946,7 +946,7 @@ static void ctcm_chx_rxdisc(fsm_instance *fi, int event, void *arg) ccw_device_halt(ch2->cdev, 0); } -/** +/* * Handle error during TX channel initialization. * * fi An instance of a channel statemachine. @@ -978,7 +978,7 @@ static void ctcm_chx_txiniterr(fsm_instance *fi, int event, void *arg) } } -/** +/* * Handle TX timeout by retrying operation. * * fi An instance of a channel statemachine. @@ -1050,7 +1050,7 @@ done: return; } -/** +/* * Handle fatal errors during an I/O command. * * fi An instance of a channel statemachine. @@ -1198,7 +1198,7 @@ int ch_fsm_len = ARRAY_SIZE(ch_fsm); * Actions for mpc channel statemachine. */ -/** +/* * Normal data has been send. Free the corresponding * skb (it's in io_queue), reset dev->tbusy and * revert to idle state. @@ -1361,7 +1361,7 @@ done: return; } -/** +/* * Got normal data, check for sanity, queue it up, allocate new buffer * trigger bottom half, and initiate next read. * @@ -1464,7 +1464,7 @@ again: } -/** +/* * Initialize connection by sending a __u16 of value 0. * * fi An instance of a channel statemachine. @@ -1516,7 +1516,7 @@ done: return; } -/** +/* * Got initial data, check it. If OK, * notify device statemachine that we are up and * running. @@ -2043,7 +2043,7 @@ int mpc_ch_fsm_len = ARRAY_SIZE(ctcmpc_ch_fsm); * Actions for interface - statemachine. */ -/** +/* * Startup channels by sending CTC_EVENT_START to each channel. * * fi An instance of an interface statemachine. @@ -2068,7 +2068,7 @@ static void dev_action_start(fsm_instance *fi, int event, void *arg) } } -/** +/* * Shutdown channels by sending CTC_EVENT_STOP to each channel. * * fi An instance of an interface statemachine. @@ -2122,7 +2122,7 @@ static void dev_action_restart(fsm_instance *fi, int event, void *arg) DEV_EVENT_START, dev); } -/** +/* * Called from channel statemachine * when a channel is up and running. * @@ -2183,7 +2183,7 @@ static void dev_action_chup(fsm_instance *fi, int event, void *arg) } } -/** +/* * Called from device statemachine * when a channel has been shutdown. * diff --git a/drivers/s390/net/ctcm_main.c b/drivers/s390/net/ctcm_main.c index fd705429708e..5ea7eeb07002 100644 --- a/drivers/s390/net/ctcm_main.c +++ b/drivers/s390/net/ctcm_main.c @@ -55,7 +55,7 @@ /* Some common global variables */ -/** +/* * The root device for ctcm group devices */ static struct device *ctcm_root_dev; @@ -65,7 +65,7 @@ static struct device *ctcm_root_dev; */ struct channel *channels; -/** +/* * Unpack a just received skb and hand it over to * upper layers. * @@ -180,7 +180,7 @@ void ctcm_unpack_skb(struct channel *ch, struct sk_buff *pskb) } } -/** +/* * Release a specific channel in the channel list. * * ch Pointer to channel struct to be released. @@ -192,7 +192,7 @@ static void channel_free(struct channel *ch) fsm_newstate(ch->fsm, CTC_STATE_IDLE); } -/** +/* * Remove a specific channel in the channel list. * * ch Pointer to channel struct to be released. @@ -240,7 +240,7 @@ static void channel_remove(struct channel *ch) chid, ok ? "OK" : "failed"); } -/** +/* * Get a specific channel from the channel list. * * type Type of channel we are interested in. @@ -300,7 +300,7 @@ static long ctcm_check_irb_error(struct ccw_device *cdev, struct irb *irb) } -/** +/* * Check sense of a unit check. * * ch The channel, the sense code belongs to. @@ -414,7 +414,7 @@ int ctcm_ch_alloc_buffer(struct channel *ch) * Interface API for upper network layers */ -/** +/* * Open an interface. * Called from generic network layer when ifconfig up is run. * @@ -432,7 +432,7 @@ int ctcm_open(struct net_device *dev) return 0; } -/** +/* * Close an interface. * Called from generic network layer when ifconfig down is run. * @@ -451,7 +451,7 @@ int ctcm_close(struct net_device *dev) } -/** +/* * Transmit a packet. * This is a helper function for ctcm_tx(). * @@ -822,7 +822,7 @@ done: return rc; } -/** +/* * Start transmission of a packet. * Called from generic network device layer. * @@ -975,7 +975,7 @@ done: } -/** +/* * Sets MTU of an interface. * * dev Pointer to interface struct. @@ -1007,7 +1007,7 @@ static int ctcm_change_mtu(struct net_device *dev, int new_mtu) return 0; } -/** +/* * Returns interface statistics of a device. * * dev Pointer to interface struct. @@ -1144,7 +1144,7 @@ static struct net_device *ctcm_init_netdevice(struct ctcm_priv *priv) return dev; } -/** +/* * Main IRQ handler. * * cdev The ccw_device the interrupt is for. @@ -1257,7 +1257,7 @@ static const struct device_type ctcm_devtype = { .groups = ctcm_attr_groups, }; -/** +/* * Add ctcm specific attributes. * Add ctcm private data. * @@ -1293,7 +1293,7 @@ static int ctcm_probe_device(struct ccwgroup_device *cgdev) return 0; } -/** +/* * Add a new channel to the list of channels. * Keeps the channel list sorted. * @@ -1343,7 +1343,7 @@ static int add_channel(struct ccw_device *cdev, enum ctcm_channel_types type, snprintf(ch->id, CTCM_ID_SIZE, "ch-%s", dev_name(&cdev->dev)); ch->type = type; - /** + /* * "static" ccws are used in the following way: * * ccw[0..2] (Channel program for generic I/O): @@ -1471,7 +1471,7 @@ static enum ctcm_channel_types get_channel_type(struct ccw_device_id *id) return type; } -/** +/* * * Setup an interface. * @@ -1595,7 +1595,7 @@ out_err_result: return result; } -/** +/* * Shutdown an interface. * * cgdev Device to be shut down. @@ -1738,7 +1738,7 @@ static void print_banner(void) pr_info("CTCM driver initialized\n"); } -/** +/* * Initialize module. * This is called just after the module is loaded. * diff --git a/drivers/s390/net/ctcm_mpc.c b/drivers/s390/net/ctcm_mpc.c index f0436f555c62..88abfb5e8045 100644 --- a/drivers/s390/net/ctcm_mpc.c +++ b/drivers/s390/net/ctcm_mpc.c @@ -1016,7 +1016,7 @@ done: CTCM_PR_DEBUG("exit %s: ch=0x%p id=%s\n", __func__, ch, ch->id); } -/** +/* * Unpack a just received skb and hand it over to * upper layers. * special MPC version of unpack_skb. @@ -1211,7 +1211,7 @@ done: __func__, dev->name, ch, ch->id); } -/** +/* * tasklet helper for mpc's skb unpacking. * * ch The channel to work on. @@ -1320,7 +1320,7 @@ struct mpc_group *ctcmpc_init_mpc_group(struct ctcm_priv *priv) * CTCM_PROTO_MPC only */ -/** +/* * NOP action for statemachines */ static void mpc_action_nop(fsm_instance *fi, int event, void *arg) @@ -1426,7 +1426,7 @@ static void mpc_action_go_inop(fsm_instance *fi, int event, void *arg) } } -/** +/* * Handle mpc group action timeout. * MPC Group Station FSM action * CTCM_PROTO_MPC only diff --git a/drivers/s390/net/fsm.c b/drivers/s390/net/fsm.c index eb07862bd36a..98c4864932d2 100644 --- a/drivers/s390/net/fsm.c +++ b/drivers/s390/net/fsm.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0 -/** +/* * A generic FSM based on fsm used in isdn4linux * */ diff --git a/drivers/s390/net/ism_drv.c b/drivers/s390/net/ism_drv.c index 26cc943d2034..5f7e28de8b15 100644 --- a/drivers/s390/net/ism_drv.c +++ b/drivers/s390/net/ism_drv.c @@ -555,7 +555,7 @@ static int ism_probe(struct pci_dev *pdev, const struct pci_device_id *id) if (ret) goto err_disable; - ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(64)); + ret = dma_set_mask(&pdev->dev, DMA_BIT_MASK(64)); if (ret) goto err_resource; diff --git a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c index 440219bcaa2b..2a6479740600 100644 --- a/drivers/s390/net/lcs.c +++ b/drivers/s390/net/lcs.c @@ -40,18 +40,18 @@ #error Cannot compile lcs.c without some net devices switched on. #endif -/** +/* * initialization string for output */ static char version[] __initdata = "LCS driver"; -/** +/* * the root device for lcs group devices */ static struct device *lcs_root_dev; -/** +/* * Some prototypes. */ static void lcs_tasklet(unsigned long); @@ -62,14 +62,14 @@ static int lcs_send_delipm(struct lcs_card *, struct lcs_ipm_list *); #endif /* CONFIG_IP_MULTICAST */ static int lcs_recovery(void *ptr); -/** +/* * Debug Facility Stuff */ static char debug_buffer[255]; static debug_info_t *lcs_dbf_setup; static debug_info_t *lcs_dbf_trace; -/** +/* * LCS Debug Facility functions */ static void @@ -96,7 +96,7 @@ lcs_register_debug_facility(void) return 0; } -/** +/* * Allocate io buffers. */ static int @@ -123,7 +123,7 @@ lcs_alloc_channel(struct lcs_channel *channel) return 0; } -/** +/* * Free io buffers. */ static void @@ -151,7 +151,7 @@ lcs_cleanup_channel(struct lcs_channel *channel) lcs_free_channel(channel); } -/** +/* * LCS free memory for card and channels. */ static void @@ -162,7 +162,7 @@ lcs_free_card(struct lcs_card *card) kfree(card); } -/** +/* * LCS alloc memory for card and channels */ static struct lcs_card * @@ -402,7 +402,7 @@ lcs_do_start_thread(struct lcs_card *card, unsigned long thread) return rc; } -/** +/* * Initialize channels,card and state machines. */ static void @@ -451,7 +451,8 @@ static void lcs_clear_multicast_list(struct lcs_card *card) spin_unlock_irqrestore(&card->ipm_lock, flags); #endif } -/** + +/* * Cleanup channels,card and state machines. */ static void @@ -468,7 +469,7 @@ lcs_cleanup_card(struct lcs_card *card) lcs_cleanup_channel(&card->read); } -/** +/* * Start channel. */ static int @@ -517,7 +518,7 @@ lcs_clear_channel(struct lcs_channel *channel) } -/** +/* * Stop channel. */ static int @@ -545,7 +546,7 @@ lcs_stop_channel(struct lcs_channel *channel) return 0; } -/** +/* * start read and write channel */ static int @@ -565,7 +566,7 @@ lcs_start_channels(struct lcs_card *card) return rc; } -/** +/* * stop read and write channel */ static int @@ -577,7 +578,7 @@ lcs_stop_channels(struct lcs_card *card) return 0; } -/** +/* * Get empty buffer. */ static struct lcs_buffer * @@ -610,7 +611,7 @@ lcs_get_buffer(struct lcs_channel *channel) return buffer; } -/** +/* * Resume channel program if the channel is suspended. */ static int @@ -636,7 +637,7 @@ __lcs_resume_channel(struct lcs_channel *channel) } -/** +/* * Make a buffer ready for processing. */ static void __lcs_ready_buffer_bits(struct lcs_channel *channel, int index) @@ -678,7 +679,7 @@ lcs_ready_buffer(struct lcs_channel *channel, struct lcs_buffer *buffer) return rc; } -/** +/* * Mark the buffer as processed. Take care of the suspend bit * of the previous buffer. This function is called from * interrupt context, so the lock must not be taken. @@ -712,7 +713,7 @@ __lcs_processed_buffer(struct lcs_channel *channel, struct lcs_buffer *buffer) return __lcs_resume_channel(channel); } -/** +/* * Put a processed buffer back to state empty. */ static void @@ -728,7 +729,7 @@ lcs_release_buffer(struct lcs_channel *channel, struct lcs_buffer *buffer) spin_unlock_irqrestore(get_ccwdev_lock(channel->ccwdev), flags); } -/** +/* * Get buffer for a lan command. */ static struct lcs_buffer * @@ -785,7 +786,7 @@ lcs_alloc_reply(struct lcs_cmd *cmd) return reply; } -/** +/* * Notifier function for lancmd replies. Called from read irq. */ static void @@ -813,7 +814,7 @@ lcs_notify_lancmd_waiters(struct lcs_card *card, struct lcs_cmd *cmd) spin_unlock(&card->lock); } -/** +/* * Emit buffer of a lan command. */ static void @@ -877,7 +878,7 @@ lcs_send_lancmd(struct lcs_card *card, struct lcs_buffer *buffer, return rc ? -EIO : 0; } -/** +/* * LCS startup command */ static int @@ -895,7 +896,7 @@ lcs_send_startup(struct lcs_card *card, __u8 initiator) return lcs_send_lancmd(card, buffer, NULL); } -/** +/* * LCS shutdown command */ static int @@ -912,7 +913,7 @@ lcs_send_shutdown(struct lcs_card *card) return lcs_send_lancmd(card, buffer, NULL); } -/** +/* * LCS lanstat command */ static void @@ -939,7 +940,7 @@ lcs_send_lanstat(struct lcs_card *card) return lcs_send_lancmd(card, buffer, __lcs_lanstat_cb); } -/** +/* * send stoplan command */ static int @@ -958,7 +959,7 @@ lcs_send_stoplan(struct lcs_card *card, __u8 initiator) return lcs_send_lancmd(card, buffer, NULL); } -/** +/* * send startlan command */ static void @@ -986,7 +987,7 @@ lcs_send_startlan(struct lcs_card *card, __u8 initiator) } #ifdef CONFIG_IP_MULTICAST -/** +/* * send setipm command (Multicast) */ static int @@ -1010,7 +1011,7 @@ lcs_send_setipm(struct lcs_card *card,struct lcs_ipm_list *ipm_list) return lcs_send_lancmd(card, buffer, NULL); } -/** +/* * send delipm command (Multicast) */ static int @@ -1034,7 +1035,7 @@ lcs_send_delipm(struct lcs_card *card,struct lcs_ipm_list *ipm_list) return lcs_send_lancmd(card, buffer, NULL); } -/** +/* * check if multicast is supported by LCS */ static void @@ -1074,7 +1075,7 @@ lcs_check_multicast_support(struct lcs_card *card) return -EOPNOTSUPP; } -/** +/* * set or del multicast address on LCS card */ static void @@ -1129,7 +1130,7 @@ list_modified: spin_unlock_irqrestore(&card->ipm_lock, flags); } -/** +/* * get mac address for the relevant Multicast address */ static void @@ -1139,7 +1140,7 @@ lcs_get_mac_for_ipm(__be32 ipm, char *mac, struct net_device *dev) ip_eth_mc_map(ipm, mac); } -/** +/* * function called by net device to handle multicast address relevant things */ static void lcs_remove_mc_addresses(struct lcs_card *card, @@ -1260,7 +1261,7 @@ out: } #endif /* CONFIG_IP_MULTICAST */ -/** +/* * function called by net device to * handle multicast address relevant things */ @@ -1355,7 +1356,7 @@ lcs_schedule_recovery(struct lcs_card *card) schedule_work(&card->kernel_thread_starter); } -/** +/* * IRQ Handler for LCS channels */ static void @@ -1439,7 +1440,7 @@ lcs_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb) tasklet_schedule(&channel->irq_tasklet); } -/** +/* * Tasklet for IRQ handler */ static void @@ -1476,7 +1477,7 @@ lcs_tasklet(unsigned long data) wake_up(&channel->wait_q); } -/** +/* * Finish current tx buffer and make it ready for transmit. */ static void @@ -1490,7 +1491,7 @@ __lcs_emit_txbuffer(struct lcs_card *card) card->tx_emitted++; } -/** +/* * Callback for finished tx buffers. */ static void @@ -1515,7 +1516,7 @@ lcs_txbuffer_cb(struct lcs_channel *channel, struct lcs_buffer *buffer) spin_unlock(&card->lock); } -/** +/* * Packet transmit function called by network stack */ static int @@ -1593,7 +1594,7 @@ lcs_start_xmit(struct sk_buff *skb, struct net_device *dev) return rc; } -/** +/* * send startlan and lanstat command to make LCS device ready */ static int @@ -1648,7 +1649,7 @@ lcs_startlan(struct lcs_card *card) return rc; } -/** +/* * LCS detect function * setup channels and make them I/O ready */ @@ -1680,7 +1681,7 @@ lcs_detect(struct lcs_card *card) return rc; } -/** +/* * LCS Stop card */ static int @@ -1705,7 +1706,7 @@ lcs_stopcard(struct lcs_card *card) return rc; } -/** +/* * Kernel Thread helper functions for LGW initiated commands */ static void @@ -1721,7 +1722,7 @@ lcs_start_kernel_thread(struct work_struct *work) #endif } -/** +/* * Process control frames. */ static void @@ -1748,7 +1749,7 @@ lcs_get_control(struct lcs_card *card, struct lcs_cmd *cmd) lcs_notify_lancmd_waiters(card, cmd); } -/** +/* * Unpack network packet. */ static void @@ -1779,7 +1780,7 @@ lcs_get_skb(struct lcs_card *card, char *skb_data, unsigned int skb_len) netif_rx(skb); } -/** +/* * LCS main routine to get packets and lancmd replies from the buffers */ static void @@ -1829,7 +1830,7 @@ lcs_get_frames_cb(struct lcs_channel *channel, struct lcs_buffer *buffer) lcs_ready_buffer(&card->read, buffer); } -/** +/* * get network statistics for ifconfig and other user programs */ static struct net_device_stats * @@ -1842,7 +1843,7 @@ lcs_getstats(struct net_device *dev) return &card->stats; } -/** +/* * stop lcs device * This function will be called by user doing ifconfig xxx down */ @@ -1866,7 +1867,7 @@ lcs_stop_device(struct net_device *dev) return rc; } -/** +/* * start lcs device and make it runnable * This function will be called by user doing ifconfig xxx up */ @@ -1892,7 +1893,7 @@ lcs_open_device(struct net_device *dev) return rc; } -/** +/* * show function for portno called by cat or similar things */ static ssize_t @@ -1908,7 +1909,7 @@ lcs_portno_show (struct device *dev, struct device_attribute *attr, char *buf) return sprintf(buf, "%d\n", card->portno); } -/** +/* * store the value which is piped to file portno */ static ssize_t @@ -2033,7 +2034,7 @@ static const struct device_type lcs_devtype = { .groups = lcs_attr_groups, }; -/** +/* * lcs_probe_device is called on establishing a new ccwgroup_device. */ static int @@ -2077,7 +2078,7 @@ lcs_register_netdev(struct ccwgroup_device *ccwgdev) return register_netdev(card->dev); } -/** +/* * lcs_new_device will be called by setting the group device online. */ static const struct net_device_ops lcs_netdev_ops = { @@ -2161,7 +2162,7 @@ lcs_new_device(struct ccwgroup_device *ccwgdev) card->dev->ml_priv = card; card->dev->netdev_ops = &lcs_netdev_ops; card->dev->dev_port = card->portno; - memcpy(card->dev->dev_addr, card->mac, LCS_MAC_LENGTH); + eth_hw_addr_set(card->dev, card->mac); #ifdef CONFIG_IP_MULTICAST if (!lcs_check_multicast_support(card)) card->dev->netdev_ops = &lcs_mc_netdev_ops; @@ -2199,7 +2200,7 @@ out_err: return -ENODEV; } -/** +/* * lcs_shutdown_device, called when setting the group device offline. */ static int @@ -2240,7 +2241,7 @@ lcs_shutdown_device(struct ccwgroup_device *ccwgdev) return __lcs_shutdown_device(ccwgdev, 0); } -/** +/* * drive lcs recovery after startup and startlan initiated by Lan Gateway */ static int @@ -2271,7 +2272,7 @@ lcs_recovery(void *ptr) return 0; } -/** +/* * lcs_remove_device, free buffers and card */ static void @@ -2315,7 +2316,7 @@ static struct ccw_driver lcs_ccw_driver = { .int_class = IRQIO_LCS, }; -/** +/* * LCS ccwgroup driver registration */ static struct ccwgroup_driver lcs_group_driver = { @@ -2351,7 +2352,7 @@ static const struct attribute_group *lcs_drv_attr_groups[] = { NULL, }; -/** +/* * LCS Module/Kernel initialization function */ static int @@ -2389,7 +2390,7 @@ out_err: } -/** +/* * LCS module cleanup function */ static void diff --git a/drivers/s390/net/netiucv.c b/drivers/s390/net/netiucv.c index 5a0c2f07a3a2..981e7b1c6b96 100644 --- a/drivers/s390/net/netiucv.c +++ b/drivers/s390/net/netiucv.c @@ -58,7 +58,7 @@ MODULE_AUTHOR ("(C) 2001 IBM Corporation by Fritz Elfert (felfert@millenux.com)"); MODULE_DESCRIPTION ("Linux for S/390 IUCV network driver"); -/** +/* * Debug Facility stuff */ #define IUCV_DBF_SETUP_NAME "iucv_setup" @@ -107,7 +107,7 @@ DECLARE_PER_CPU(char[256], iucv_dbf_txt_buf); debug_sprintf_event(iucv_dbf_trace, level, text ); \ } while (0) -/** +/* * some more debug stuff */ #define PRINTK_HEADER " iucv: " /* for debugging */ @@ -118,7 +118,7 @@ static struct device_driver netiucv_driver = { .bus = &iucv_bus, }; -/** +/* * Per connection profiling data */ struct connection_profile { @@ -133,7 +133,7 @@ struct connection_profile { unsigned long tx_max_pending; }; -/** +/* * Representation of one iucv connection */ struct iucv_connection { @@ -154,13 +154,13 @@ struct iucv_connection { char userdata[17]; }; -/** +/* * Linked list of all connection structs. */ static LIST_HEAD(iucv_connection_list); static DEFINE_RWLOCK(iucv_connection_rwlock); -/** +/* * Representation of event-data for the * connection state machine. */ @@ -169,7 +169,7 @@ struct iucv_event { void *data; }; -/** +/* * Private part of the network device structure */ struct netiucv_priv { @@ -180,7 +180,7 @@ struct netiucv_priv { struct device *dev; }; -/** +/* * Link level header for a packet. */ struct ll_header { @@ -195,7 +195,7 @@ struct ll_header { #define NETIUCV_QUEUELEN_DEFAULT 50 #define NETIUCV_TIMEOUT_5SEC 5000 -/** +/* * Compatibility macros for busy handling * of network devices. */ @@ -223,7 +223,7 @@ static u8 iucvMagic_ebcdic[16] = { 0xF0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40 }; -/** +/* * Convert an iucv userId to its printable * form (strip whitespace at end). * @@ -262,7 +262,7 @@ static char *netiucv_printuser(struct iucv_connection *conn) return netiucv_printname(conn->userid, 8); } -/** +/* * States of the interface statemachine. */ enum dev_states { @@ -270,7 +270,7 @@ enum dev_states { DEV_STATE_STARTWAIT, DEV_STATE_STOPWAIT, DEV_STATE_RUNNING, - /** + /* * MUST be always the last element!! */ NR_DEV_STATES @@ -283,7 +283,7 @@ static const char *dev_state_names[] = { "Running", }; -/** +/* * Events of the interface statemachine. */ enum dev_events { @@ -291,7 +291,7 @@ enum dev_events { DEV_EVENT_STOP, DEV_EVENT_CONUP, DEV_EVENT_CONDOWN, - /** + /* * MUST be always the last element!! */ NR_DEV_EVENTS @@ -304,11 +304,11 @@ static const char *dev_event_names[] = { "Connection down", }; -/** +/* * Events of the connection statemachine */ enum conn_events { - /** + /* * Events, representing callbacks from * lowlevel iucv layer) */ @@ -320,23 +320,23 @@ enum conn_events { CONN_EVENT_RX, CONN_EVENT_TXDONE, - /** + /* * Events, representing errors return codes from * calls to lowlevel iucv layer */ - /** + /* * Event, representing timer expiry. */ CONN_EVENT_TIMER, - /** + /* * Events, representing commands from upper levels. */ CONN_EVENT_START, CONN_EVENT_STOP, - /** + /* * MUST be always the last element!! */ NR_CONN_EVENTS, @@ -357,55 +357,55 @@ static const char *conn_event_names[] = { "Stop", }; -/** +/* * States of the connection statemachine. */ enum conn_states { - /** + /* * Connection not assigned to any device, * initial state, invalid */ CONN_STATE_INVALID, - /** + /* * Userid assigned but not operating */ CONN_STATE_STOPPED, - /** + /* * Connection registered, * no connection request sent yet, * no connection request received */ CONN_STATE_STARTWAIT, - /** + /* * Connection registered and connection request sent, * no acknowledge and no connection request received yet. */ CONN_STATE_SETUPWAIT, - /** + /* * Connection up and running idle */ CONN_STATE_IDLE, - /** + /* * Data sent, awaiting CONN_EVENT_TXDONE */ CONN_STATE_TX, - /** + /* * Error during registration. */ CONN_STATE_REGERR, - /** + /* * Error during registration. */ CONN_STATE_CONNERR, - /** + /* * MUST be always the last element!! */ NR_CONN_STATES, @@ -424,7 +424,7 @@ static const char *conn_state_names[] = { }; -/** +/* * Debug Facility Stuff */ static debug_info_t *iucv_dbf_setup = NULL; @@ -556,7 +556,7 @@ static void netiucv_callback_connres(struct iucv_path *path, u8 *ipuser) fsm_event(conn->fsm, CONN_EVENT_CONN_RES, conn); } -/** +/* * NOP action for statemachines */ static void netiucv_action_nop(fsm_instance *fi, int event, void *arg) @@ -567,7 +567,7 @@ static void netiucv_action_nop(fsm_instance *fi, int event, void *arg) * Actions of the connection statemachine */ -/** +/* * netiucv_unpack_skb * @conn: The connection where this skb has been received. * @pskb: The received skb. @@ -993,7 +993,7 @@ static const int CONN_FSM_LEN = sizeof(conn_fsm) / sizeof(fsm_node); * Actions for interface - statemachine. */ -/** +/* * dev_action_start * @fi: An instance of an interface statemachine. * @event: The event, just happened. @@ -1012,7 +1012,7 @@ static void dev_action_start(fsm_instance *fi, int event, void *arg) fsm_event(privptr->conn->fsm, CONN_EVENT_START, privptr->conn); } -/** +/* * Shutdown connection by sending CONN_EVENT_STOP to it. * * @param fi An instance of an interface statemachine. @@ -1034,7 +1034,7 @@ dev_action_stop(fsm_instance *fi, int event, void *arg) fsm_event(privptr->conn->fsm, CONN_EVENT_STOP, &ev); } -/** +/* * Called from connection statemachine * when a connection is up and running. * @@ -1067,7 +1067,7 @@ dev_action_connup(fsm_instance *fi, int event, void *arg) } } -/** +/* * Called from connection statemachine * when a connection has been shutdown. * @@ -1107,7 +1107,7 @@ static const fsm_node dev_fsm[] = { static const int DEV_FSM_LEN = sizeof(dev_fsm) / sizeof(fsm_node); -/** +/* * Transmit a packet. * This is a helper function for netiucv_tx(). * @@ -1144,7 +1144,7 @@ static int netiucv_transmit_skb(struct iucv_connection *conn, spin_unlock_irqrestore(&conn->collect_lock, saveflags); } else { struct sk_buff *nskb = skb; - /** + /* * Copy the skb to a new allocated skb in lowmem only if the * data is located above 2G in memory or tailroom is < 2. */ @@ -1164,7 +1164,7 @@ static int netiucv_transmit_skb(struct iucv_connection *conn, } copied = 1; } - /** + /* * skb now is below 2G and has enough room. Add headers. */ header.next = nskb->len + NETIUCV_HDRLEN; @@ -1194,7 +1194,7 @@ static int netiucv_transmit_skb(struct iucv_connection *conn, if (copied) dev_kfree_skb(nskb); else { - /** + /* * Remove our headers. They get added * again on retransmit. */ @@ -1217,7 +1217,7 @@ static int netiucv_transmit_skb(struct iucv_connection *conn, * Interface API for upper network layers */ -/** +/* * Open an interface. * Called from generic network layer when ifconfig up is run. * @@ -1233,7 +1233,7 @@ static int netiucv_open(struct net_device *dev) return 0; } -/** +/* * Close an interface. * Called from generic network layer when ifconfig down is run. * @@ -1249,7 +1249,7 @@ static int netiucv_close(struct net_device *dev) return 0; } -/** +/* * Start transmission of a packet. * Called from generic network device layer. * @@ -1266,7 +1266,7 @@ static int netiucv_tx(struct sk_buff *skb, struct net_device *dev) int rc; IUCV_DBF_TEXT(trace, 4, __func__); - /** + /* * Some sanity checks ... */ if (skb == NULL) { @@ -1282,7 +1282,7 @@ static int netiucv_tx(struct sk_buff *skb, struct net_device *dev) return NETDEV_TX_OK; } - /** + /* * If connection is not running, try to restart it * and throw away packet. */ @@ -1304,7 +1304,7 @@ static int netiucv_tx(struct sk_buff *skb, struct net_device *dev) return rc ? NETDEV_TX_BUSY : NETDEV_TX_OK; } -/** +/* * netiucv_stats * @dev: Pointer to interface struct. * @@ -1745,7 +1745,7 @@ static void netiucv_unregister_device(struct device *dev) device_unregister(dev); } -/** +/* * Allocate and initialize a new connection structure. * Add it to the list of netiucv connections; */ @@ -1802,7 +1802,7 @@ out: return NULL; } -/** +/* * Release a connection structure and remove it from the * list of netiucv connections. */ @@ -1826,7 +1826,7 @@ static void netiucv_remove_connection(struct iucv_connection *conn) kfree_skb(conn->tx_buff); } -/** +/* * Release everything of a net device. */ static void netiucv_free_netdevice(struct net_device *dev) @@ -1848,7 +1848,7 @@ static void netiucv_free_netdevice(struct net_device *dev) } } -/** +/* * Initialize a net device. (Called from kernel in alloc_netdev()) */ static const struct net_device_ops netiucv_netdev_ops = { @@ -1873,7 +1873,7 @@ static void netiucv_setup_netdevice(struct net_device *dev) dev->netdev_ops = &netiucv_netdev_ops; } -/** +/* * Allocate and initialize everything of a net device. */ static struct net_device *netiucv_init_netdevice(char *username, char *userdata) diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h index 535a60b3946d..20dca4c0384a 100644 --- a/drivers/s390/net/qeth_core.h +++ b/drivers/s390/net/qeth_core.h @@ -545,7 +545,6 @@ static inline bool qeth_out_queue_is_empty(struct qeth_qdio_out_q *queue) struct qeth_qdio_info { atomic_t state; /* input */ - int no_in_queues; struct qeth_qdio_q *in_q; struct qeth_qdio_q *c_q; struct qeth_qdio_buffer_pool in_buf_pool; @@ -771,8 +770,6 @@ struct qeth_discipline { void (*remove) (struct ccwgroup_device *); int (*set_online)(struct qeth_card *card, bool carrier_ok); void (*set_offline)(struct qeth_card *card); - int (*do_ioctl)(struct net_device *dev, struct ifreq *rq, - void __user *data, int cmd); int (*control_event_handler)(struct qeth_card *card, struct qeth_ipa_cmd *cmd); }; @@ -858,7 +855,6 @@ struct qeth_card { struct napi_struct napi; struct qeth_rx rx; struct delayed_work buffer_reclaim_work; - struct work_struct close_dev_work; }; static inline bool qeth_card_hw_is_reachable(struct qeth_card *card) @@ -1088,6 +1084,7 @@ int qeth_setadpparms_set_access_ctrl(struct qeth_card *card, int qeth_do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); int qeth_siocdevprivate(struct net_device *dev, struct ifreq *rq, void __user *data, int cmd); +__printf(3, 4) void qeth_dbf_longtext(debug_info_t *id, int level, char *text, ...); int qeth_configure_cq(struct qeth_card *, enum qeth_cq); int qeth_hw_trap(struct qeth_card *, enum qeth_diags_trap_action); diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index 41ca6273b750..26c55f67289f 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -59,6 +59,7 @@ EXPORT_SYMBOL_GPL(qeth_dbf); static struct kmem_cache *qeth_core_header_cache; static struct kmem_cache *qeth_qdio_outbuf_cache; +static struct kmem_cache *qeth_qaob_cache; static struct device *qeth_core_root_dev; static struct dentry *qeth_debugfs_root; @@ -70,15 +71,6 @@ static void qeth_issue_next_read_cb(struct qeth_card *card, static int qeth_qdio_establish(struct qeth_card *); static void qeth_free_qdio_queues(struct qeth_card *card); -static void qeth_close_dev_handler(struct work_struct *work) -{ - struct qeth_card *card; - - card = container_of(work, struct qeth_card, close_dev_work); - QETH_CARD_TEXT(card, 2, "cldevhdl"); - ccwgroup_set_offline(card->gdev); -} - static const char *qeth_get_cardname(struct qeth_card *card) { if (IS_VM_NIC(card)) { @@ -202,6 +194,9 @@ static void qeth_clear_working_pool_list(struct qeth_card *card) &card->qdio.in_buf_pool.entry_list, list) list_del(&pool_entry->list); + if (!queue) + return; + for (i = 0; i < ARRAY_SIZE(queue->bufs); i++) queue->bufs[i].pool_entry = NULL; } @@ -360,8 +355,8 @@ static int qeth_cq_init(struct qeth_card *card) qdio_reset_buffers(card->qdio.c_q->qdio_bufs, QDIO_MAX_BUFFERS_PER_Q); card->qdio.c_q->next_buf_to_init = 127; - rc = do_QDIO(CARD_DDEV(card), QDIO_FLAG_SYNC_INPUT, - card->qdio.no_in_queues - 1, 0, 127, NULL); + rc = do_QDIO(CARD_DDEV(card), QDIO_FLAG_SYNC_INPUT, 1, 0, 127, + NULL); if (rc) { QETH_CARD_TEXT_(card, 2, "1err%d", rc); goto out; @@ -381,21 +376,16 @@ static int qeth_alloc_cq(struct qeth_card *card) dev_err(&card->gdev->dev, "Failed to create completion queue\n"); return -ENOMEM; } - - card->qdio.no_in_queues = 2; } else { QETH_CARD_TEXT(card, 2, "nocq"); card->qdio.c_q = NULL; - card->qdio.no_in_queues = 1; } - QETH_CARD_TEXT_(card, 2, "iqc%d", card->qdio.no_in_queues); return 0; } static void qeth_free_cq(struct qeth_card *card) { if (card->qdio.c_q) { - --card->qdio.no_in_queues; qeth_free_qdio_queue(card->qdio.c_q); card->qdio.c_q = NULL; } @@ -792,10 +782,12 @@ static struct qeth_ipa_cmd *qeth_check_ipa_data(struct qeth_card *card, case IPA_CMD_STOPLAN: if (cmd->hdr.return_code == IPA_RC_VEPA_TO_VEB_TRANSITION) { dev_err(&card->gdev->dev, - "Interface %s is down because the adjacent port is no longer in reflective relay mode\n", + "Adjacent port of interface %s is no longer in reflective relay mode, trigger recovery\n", netdev_name(card->dev)); - schedule_work(&card->close_dev_work); + /* Set offline, then probably fail to set online: */ + qeth_schedule_recovery(card); } else { + /* stay online for subsequent STARTLAN */ dev_warn(&card->gdev->dev, "The link for interface %s on CHPID 0x%X failed\n", netdev_name(card->dev), card->info.chpid); @@ -1342,7 +1334,7 @@ static void qeth_clear_output_buffer(struct qeth_qdio_out_q *queue, static void qeth_free_out_buf(struct qeth_qdio_out_buffer *buf) { if (buf->aob) - qdio_release_aob(buf->aob); + kmem_cache_free(qeth_qaob_cache, buf->aob); kmem_cache_free(qeth_qdio_outbuf_cache, buf); } @@ -1462,7 +1454,6 @@ static void qeth_init_qdio_info(struct qeth_card *card) card->qdio.default_out_queue = QETH_DEFAULT_QUEUE; /* inbound */ - card->qdio.no_in_queues = 1; card->qdio.in_buf_size = QETH_IN_BUF_SIZE_DEFAULT; if (IS_IQD(card)) card->qdio.init_pool.buf_count = QETH_IN_BUF_COUNT_HSDEFAULT; @@ -1537,7 +1528,6 @@ static void qeth_setup_card(struct qeth_card *card) INIT_LIST_HEAD(&card->ipato.entries); qeth_init_qdio_info(card); INIT_DELAYED_WORK(&card->buffer_reclaim_work, qeth_buffer_reclaim_work); - INIT_WORK(&card->close_dev_work, qeth_close_dev_handler); hash_init(card->rx_mode_addrs); hash_init(card->local_addrs4); hash_init(card->local_addrs6); @@ -1935,9 +1925,9 @@ static struct qeth_cmd_buffer *qeth_mpc_alloc_cmd(struct qeth_card *card, * @card: qeth_card structure pointer * @iob: qeth_cmd_buffer pointer * @reply_cb: callback function pointer - * @cb_card: pointer to the qeth_card structure - * @cb_reply: pointer to the qeth_reply structure - * @cb_cmd: pointer to the original iob for non-IPA + * cb_card: pointer to the qeth_card structure + * cb_reply: pointer to the qeth_reply structure + * cb_cmd: pointer to the original iob for non-IPA * commands, or to the qeth_ipa_cmd structure * for the IPA commands. * @reply_param: private pointer passed to the callback @@ -2634,7 +2624,7 @@ static void qeth_free_qdio_queues(struct qeth_card *card) qeth_free_cq(card); for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; ++j) { if (card->qdio.in_q->bufs[j].rx_skb) - dev_kfree_skb_any(card->qdio.in_q->bufs[j].rx_skb); + consume_skb(card->qdio.in_q->bufs[j].rx_skb); } qeth_free_qdio_queue(card->qdio.in_q); card->qdio.in_q = NULL; @@ -3044,7 +3034,7 @@ static int qeth_send_ipa_cmd_cb(struct qeth_card *card, return (cmd->hdr.return_code) ? -EIO : 0; } -/** +/* * qeth_send_ipa_cmd() - send an IPA command * * See qeth_send_control_data() for explanation of the arguments. @@ -3559,7 +3549,8 @@ static void qeth_flush_buffers(struct qeth_qdio_out_q *queue, int index, !qeth_iqd_is_mcast_queue(card, queue) && count == 1) { if (!buf->aob) - buf->aob = qdio_allocate_aob(); + buf->aob = kmem_cache_zalloc(qeth_qaob_cache, + GFP_ATOMIC); if (buf->aob) { struct qeth_qaob_priv1 *priv; @@ -3785,7 +3776,7 @@ static void qeth_qdio_output_handler(struct ccw_device *ccwdev, qeth_schedule_recovery(card); } -/** +/* * Note: Function assumes that we have 4 outbound queues. */ int qeth_get_priority_queue(struct qeth_card *card, struct sk_buff *skb) @@ -3882,12 +3873,14 @@ static unsigned int qeth_count_elements(struct sk_buff *skb, /** * qeth_add_hw_header() - add a HW header to an skb. + * @queue: TX queue that the skb will be placed on. * @skb: skb that the HW header should be added to. * @hdr: double pointer to a qeth_hdr. When returning with >= 0, * it contains a valid pointer to a qeth_hdr. * @hdr_len: length of the HW header. * @proto_len: length of protocol headers that need to be in same page as the * HW header. + * @elements: returns the required number of buffer elements for this skb. * * Returns the pushed length. If the header can't be pushed on * (eg. because it would cross a page boundary), it is allocated from @@ -4380,7 +4373,7 @@ static int qeth_setadpparms_change_macaddr_cb(struct qeth_card *card, !(adp_cmd->hdr.flags & QETH_SETADP_FLAGS_VIRTUAL_MAC)) return -EADDRNOTAVAIL; - ether_addr_copy(card->dev->dev_addr, adp_cmd->data.change_addr.addr); + eth_hw_addr_set(card->dev, adp_cmd->data.change_addr.addr); return 0; } @@ -5051,7 +5044,7 @@ int qeth_vm_request_mac(struct qeth_card *card) QETH_CARD_TEXT(card, 2, "badmac"); QETH_CARD_HEX(card, 2, response->mac, ETH_ALEN); } else { - ether_addr_copy(card->dev->dev_addr, response->mac); + eth_hw_addr_set(card->dev, response->mac); } out: @@ -5144,6 +5137,7 @@ static int qeth_qdio_establish(struct qeth_card *card) struct qdio_buffer **in_sbal_ptrs[QETH_MAX_IN_QUEUES]; struct qeth_qib_parms *qib_parms = NULL; struct qdio_initialize init_data; + unsigned int no_input_qs = 1; unsigned int i; int rc = 0; @@ -5158,8 +5152,10 @@ static int qeth_qdio_establish(struct qeth_card *card) } in_sbal_ptrs[0] = card->qdio.in_q->qdio_bufs; - if (card->options.cq == QETH_CQ_ENABLED) + if (card->options.cq == QETH_CQ_ENABLED) { in_sbal_ptrs[1] = card->qdio.c_q->qdio_bufs; + no_input_qs++; + } for (i = 0; i < card->qdio.no_out_queues; i++) out_sbal_ptrs[i] = card->qdio.out_qs[i]->qdio_bufs; @@ -5169,7 +5165,7 @@ static int qeth_qdio_establish(struct qeth_card *card) QDIO_QETH_QFMT; init_data.qib_param_field_format = 0; init_data.qib_param_field = (void *)qib_parms; - init_data.no_input_qs = card->qdio.no_in_queues; + init_data.no_input_qs = no_input_qs; init_data.no_output_qs = card->qdio.no_out_queues; init_data.input_handler = qeth_qdio_input_handler; init_data.output_handler = qeth_qdio_output_handler; @@ -5519,7 +5515,8 @@ static int qeth_do_reset(void *data) dev_info(&card->gdev->dev, "Device successfully recovered!\n"); } else { - ccwgroup_set_offline(card->gdev); + qeth_set_offline(card, disc, true); + ccwgroup_set_offline(card->gdev, false); dev_warn(&card->gdev->dev, "The qeth device driver failed to recover an error on the device\n"); } @@ -5608,7 +5605,7 @@ static void qeth_receive_skb(struct qeth_card *card, struct sk_buff *skb, if (uses_frags) napi_free_frags(napi); else - dev_kfree_skb_any(skb); + kfree_skb(skb); return; } @@ -5799,7 +5796,7 @@ walk_packet: if (uses_frags) napi_free_frags(napi); else - dev_kfree_skb_any(skb); + kfree_skb(skb); QETH_CARD_STAT_INC(card, rx_length_errors); } @@ -6604,10 +6601,7 @@ int qeth_siocdevprivate(struct net_device *dev, struct ifreq *rq, void __user *d rc = qeth_query_oat_command(card, data); break; default: - if (card->discipline->do_ioctl) - rc = card->discipline->do_ioctl(dev, rq, data, cmd); - else - rc = -EOPNOTSUPP; + rc = -EOPNOTSUPP; } if (rc) QETH_CARD_TEXT_(card, 2, "ioce%x", rc); @@ -7181,6 +7175,16 @@ static int __init qeth_core_init(void) rc = -ENOMEM; goto cqslab_err; } + + qeth_qaob_cache = kmem_cache_create("qeth_qaob", + sizeof(struct qaob), + sizeof(struct qaob), + 0, NULL); + if (!qeth_qaob_cache) { + rc = -ENOMEM; + goto qaob_err; + } + rc = ccw_driver_register(&qeth_ccw_driver); if (rc) goto ccw_err; @@ -7193,6 +7197,8 @@ static int __init qeth_core_init(void) ccwgroup_err: ccw_driver_unregister(&qeth_ccw_driver); ccw_err: + kmem_cache_destroy(qeth_qaob_cache); +qaob_err: kmem_cache_destroy(qeth_qdio_outbuf_cache); cqslab_err: kmem_cache_destroy(qeth_core_header_cache); @@ -7211,6 +7217,7 @@ static void __exit qeth_core_exit(void) qeth_clear_dbf_list(); ccwgroup_driver_unregister(&qeth_core_ccwgroup_driver); ccw_driver_unregister(&qeth_ccw_driver); + kmem_cache_destroy(qeth_qaob_cache); kmem_cache_destroy(qeth_qdio_outbuf_cache); kmem_cache_destroy(qeth_core_header_cache); root_device_unregister(qeth_core_root_dev); diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c index 72e84ff9fea5..0347fc184786 100644 --- a/drivers/s390/net/qeth_l2_main.c +++ b/drivers/s390/net/qeth_l2_main.c @@ -71,7 +71,7 @@ static int qeth_l2_send_setdelmac_cb(struct qeth_card *card, return qeth_l2_setdelmac_makerc(card, cmd->hdr.return_code); } -static int qeth_l2_send_setdelmac(struct qeth_card *card, __u8 *mac, +static int qeth_l2_send_setdelmac(struct qeth_card *card, const __u8 *mac, enum qeth_ipa_cmds ipacmd) { struct qeth_ipa_cmd *cmd; @@ -88,7 +88,7 @@ static int qeth_l2_send_setdelmac(struct qeth_card *card, __u8 *mac, return qeth_send_ipa_cmd(card, iob, qeth_l2_send_setdelmac_cb, NULL); } -static int qeth_l2_send_setmac(struct qeth_card *card, __u8 *mac) +static int qeth_l2_send_setmac(struct qeth_card *card, const __u8 *mac) { int rc; @@ -121,11 +121,11 @@ static int qeth_l2_write_mac(struct qeth_card *card, u8 *mac) QETH_CARD_TEXT(card, 2, "L2Wmac"); rc = qeth_l2_send_setdelmac(card, mac, cmd); if (rc == -EADDRINUSE) - QETH_DBF_MESSAGE(2, "MAC already registered on device %x\n", - CARD_DEVID(card)); + QETH_DBF_MESSAGE(2, "MAC address %012llx is already registered on device %x\n", + ether_addr_to_u64(mac), CARD_DEVID(card)); else if (rc) - QETH_DBF_MESSAGE(2, "Failed to register MAC on device %x: %d\n", - CARD_DEVID(card), rc); + QETH_DBF_MESSAGE(2, "Failed to register MAC address %012llx on device %x: %d\n", + ether_addr_to_u64(mac), CARD_DEVID(card), rc); return rc; } @@ -138,8 +138,8 @@ static int qeth_l2_remove_mac(struct qeth_card *card, u8 *mac) QETH_CARD_TEXT(card, 2, "L2Rmac"); rc = qeth_l2_send_setdelmac(card, mac, cmd); if (rc) - QETH_DBF_MESSAGE(2, "Failed to delete MAC on device %u: %d\n", - CARD_DEVID(card), rc); + QETH_DBF_MESSAGE(2, "Failed to delete MAC address %012llx on device %x: %d\n", + ether_addr_to_u64(mac), CARD_DEVID(card), rc); return rc; } @@ -377,7 +377,7 @@ static int qeth_l2_set_mac_address(struct net_device *dev, void *p) if (rc) return rc; ether_addr_copy(old_addr, dev->dev_addr); - ether_addr_copy(dev->dev_addr, addr->sa_data); + eth_hw_addr_set(dev, addr->sa_data); if (card->info.dev_addr_is_registered) qeth_l2_remove_mac(card, old_addr); @@ -661,13 +661,13 @@ static void qeth_l2_dev2br_fdb_notify(struct qeth_card *card, u8 code, card->dev, &info.info, NULL); QETH_CARD_TEXT(card, 4, "andelmac"); QETH_CARD_TEXT_(card, 4, - "mc%012lx", ether_addr_to_u64(ntfy_mac)); + "mc%012llx", ether_addr_to_u64(ntfy_mac)); } else { call_switchdev_notifiers(SWITCHDEV_FDB_ADD_TO_BRIDGE, card->dev, &info.info, NULL); QETH_CARD_TEXT(card, 4, "anaddmac"); QETH_CARD_TEXT_(card, 4, - "mc%012lx", ether_addr_to_u64(ntfy_mac)); + "mc%012llx", ether_addr_to_u64(ntfy_mac)); } } @@ -765,8 +765,8 @@ static void qeth_l2_br2dev_worker(struct work_struct *work) int err = 0; kfree(br2dev_event_work); - QETH_CARD_TEXT_(card, 4, "b2dw%04x", event); - QETH_CARD_TEXT_(card, 4, "ma%012lx", ether_addr_to_u64(addr)); + QETH_CARD_TEXT_(card, 4, "b2dw%04lx", event); + QETH_CARD_TEXT_(card, 4, "ma%012llx", ether_addr_to_u64(addr)); rcu_read_lock(); /* Verify preconditions are still valid: */ @@ -795,7 +795,7 @@ static void qeth_l2_br2dev_worker(struct work_struct *work) if (err) { QETH_CARD_TEXT(card, 2, "b2derris"); QETH_CARD_TEXT_(card, 2, - "err%02x%03d", event, + "err%02lx%03d", event, lowerdev->ifindex); } } @@ -813,7 +813,7 @@ static void qeth_l2_br2dev_worker(struct work_struct *work) break; } if (err) - QETH_CARD_TEXT_(card, 2, "b2derr%02x", event); + QETH_CARD_TEXT_(card, 2, "b2derr%02lx", event); } unlock: @@ -878,7 +878,7 @@ static int qeth_l2_switchdev_event(struct notifier_block *unused, while (lowerdev) { if (qeth_l2_must_learn(lowerdev, dstdev)) { card = lowerdev->ml_priv; - QETH_CARD_TEXT_(card, 4, "b2dqw%03x", event); + QETH_CARD_TEXT_(card, 4, "b2dqw%03lx", event); rc = qeth_l2_br2dev_queue_work(brdev, lowerdev, dstdev, event, fdb_info->addr); @@ -2307,7 +2307,6 @@ static void qeth_l2_remove_device(struct ccwgroup_device *gdev) if (gdev->state == CCWGROUP_ONLINE) qeth_set_offline(card, card->discipline, false); - cancel_work_sync(&card->close_dev_work); if (card->dev->reg_state == NETREG_REGISTERED) { priv = netdev_priv(card->dev); if (priv->brport_features & BR_LEARNING_SYNC) { @@ -2431,7 +2430,6 @@ const struct qeth_discipline qeth_l2_discipline = { .remove = qeth_l2_remove_device, .set_online = qeth_l2_set_online, .set_offline = qeth_l2_set_offline, - .do_ioctl = NULL, .control_event_handler = qeth_l2_control_event, }; EXPORT_SYMBOL_GPL(qeth_l2_discipline); diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index 3a523e700a5a..48a886f7af62 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c @@ -492,7 +492,7 @@ int qeth_l3_setrouting_v6(struct qeth_card *card) * IP address takeover related functions */ -/** +/* * qeth_l3_update_ipato() - Update 'takeover' property, for all NORMAL IPs. * * Caller must hold ip_lock. @@ -913,8 +913,7 @@ static int qeth_l3_iqd_read_initial_mac_cb(struct qeth_card *card, if (!is_valid_ether_addr(cmd->data.create_destroy_addr.mac_addr)) return -EADDRNOTAVAIL; - ether_addr_copy(card->dev->dev_addr, - cmd->data.create_destroy_addr.mac_addr); + eth_hw_addr_set(card->dev, cmd->data.create_destroy_addr.mac_addr); return 0; } @@ -1512,7 +1511,8 @@ static int qeth_l3_arp_flush_cache(struct qeth_card *card) return rc; } -static int qeth_l3_do_ioctl(struct net_device *dev, struct ifreq *rq, void __user *data, int cmd) +static int qeth_l3_ndo_siocdevprivate(struct net_device *dev, struct ifreq *rq, + void __user *data, int cmd) { struct qeth_card *card = dev->ml_priv; struct qeth_arp_cache_entry arp_entry; @@ -1553,7 +1553,7 @@ static int qeth_l3_do_ioctl(struct net_device *dev, struct ifreq *rq, void __use rc = qeth_l3_arp_flush_cache(card); break; default: - rc = -EOPNOTSUPP; + rc = qeth_siocdevprivate(dev, rq, data, cmd); } return rc; } @@ -1842,7 +1842,7 @@ static const struct net_device_ops qeth_l3_netdev_ops = { .ndo_validate_addr = eth_validate_addr, .ndo_set_rx_mode = qeth_l3_set_rx_mode, .ndo_eth_ioctl = qeth_do_ioctl, - .ndo_siocdevprivate = qeth_siocdevprivate, + .ndo_siocdevprivate = qeth_l3_ndo_siocdevprivate, .ndo_fix_features = qeth_fix_features, .ndo_set_features = qeth_set_features, .ndo_tx_timeout = qeth_tx_timeout, @@ -1858,7 +1858,7 @@ static const struct net_device_ops qeth_l3_osa_netdev_ops = { .ndo_validate_addr = eth_validate_addr, .ndo_set_rx_mode = qeth_l3_set_rx_mode, .ndo_eth_ioctl = qeth_do_ioctl, - .ndo_siocdevprivate = qeth_siocdevprivate, + .ndo_siocdevprivate = qeth_l3_ndo_siocdevprivate, .ndo_fix_features = qeth_fix_features, .ndo_set_features = qeth_set_features, .ndo_tx_timeout = qeth_tx_timeout, @@ -1969,7 +1969,6 @@ static void qeth_l3_remove_device(struct ccwgroup_device *cgdev) if (cgdev->state == CCWGROUP_ONLINE) qeth_set_offline(card, card->discipline, false); - cancel_work_sync(&card->close_dev_work); if (card->dev->reg_state == NETREG_REGISTERED) unregister_netdev(card->dev); @@ -2073,7 +2072,6 @@ const struct qeth_discipline qeth_l3_discipline = { .remove = qeth_l3_remove_device, .set_online = qeth_l3_set_online, .set_offline = qeth_l3_set_offline, - .do_ioctl = qeth_l3_do_ioctl, .control_event_handler = qeth_l3_control_event, }; EXPORT_SYMBOL_GPL(qeth_l3_discipline); |