mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-29 03:01:39 -04:00
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux: (31 commits)
[S390] disassembler: mark exception causing instructions
[S390] Enable exception traces by default
[S390] return address of compat signals
[S390] sysctl: get rid of dead declaration
[S390] dasd: fix fixpoint divide exception in define_extent
[S390] dasd: add sanity check to detect path connection error
[S390] qdio: fix kernel panic for zfcp 31-bit
[S390] Add s390x description to Documentation/kdump/kdump.txt
[S390] Add VMCOREINFO_SYMBOL(high_memory) to vmcoreinfo
[S390] dasd: fix expiration handling for recovery requests
[S390] outstanding interrupts vs. smp_send_stop
[S390] ipc: call generic sys_ipc demultiplexer
[S390] zcrypt: Fix error return codes.
[S390] zcrypt: Rework length parameter checking.
[S390] cleanup trap handling
[S390] Remove Kerntypes leftovers
[S390] topology: increase poll frequency if change is anticipated
[S390] entry[64].S improvements
[S390] make arch/s390 subdirectories depend on config option
[S390] kvm: move cmf host id constant out of lowcore
...
Fix up conflicts in arch/s390/kernel/{smp.c,topology.c} due to the
sysdev removal clashing with "topology: get rid of ifdefs" which moved
some of that code around.
This commit is contained in:
commit
72f318897e
49 changed files with 1986 additions and 2019 deletions
|
|
@ -1718,7 +1718,7 @@ dasd_3990_erp_action_1B_32(struct dasd_ccw_req * default_erp, char *sense)
|
|||
erp->startdev = device;
|
||||
erp->memdev = device;
|
||||
erp->magic = default_erp->magic;
|
||||
erp->expires = 0;
|
||||
erp->expires = default_erp->expires;
|
||||
erp->retries = 256;
|
||||
erp->buildclk = get_clock();
|
||||
erp->status = DASD_CQR_FILLED;
|
||||
|
|
@ -2363,7 +2363,7 @@ static struct dasd_ccw_req *dasd_3990_erp_add_erp(struct dasd_ccw_req *cqr)
|
|||
erp->memdev = device;
|
||||
erp->block = cqr->block;
|
||||
erp->magic = cqr->magic;
|
||||
erp->expires = 0;
|
||||
erp->expires = cqr->expires;
|
||||
erp->retries = 256;
|
||||
erp->buildclk = get_clock();
|
||||
erp->status = DASD_CQR_FILLED;
|
||||
|
|
|
|||
|
|
@ -705,6 +705,16 @@ struct dasd_device *dasd_alias_get_start_dev(struct dasd_device *base_device)
|
|||
if (lcu->pav == NO_PAV ||
|
||||
lcu->flags & (NEED_UAC_UPDATE | UPDATE_PENDING))
|
||||
return NULL;
|
||||
if (unlikely(!(private->features.feature[8] & 0x01))) {
|
||||
/*
|
||||
* PAV enabled but prefix not, very unlikely
|
||||
* seems to be a lost pathgroup
|
||||
* use base device to do IO
|
||||
*/
|
||||
DBF_DEV_EVENT(DBF_ERR, base_device, "%s",
|
||||
"Prefix not enabled with PAV enabled\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&lcu->lock, flags);
|
||||
alias_device = group->next;
|
||||
|
|
|
|||
|
|
@ -752,24 +752,13 @@ dasd_eckd_cdl_reclen(int recid)
|
|||
return sizes_trk0[recid];
|
||||
return LABEL_SIZE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate device unique id that specifies the physical device.
|
||||
*/
|
||||
static int dasd_eckd_generate_uid(struct dasd_device *device)
|
||||
/* create unique id from private structure. */
|
||||
static void create_uid(struct dasd_eckd_private *private)
|
||||
{
|
||||
struct dasd_eckd_private *private;
|
||||
struct dasd_uid *uid;
|
||||
int count;
|
||||
unsigned long flags;
|
||||
struct dasd_uid *uid;
|
||||
|
||||
private = (struct dasd_eckd_private *) device->private;
|
||||
if (!private)
|
||||
return -ENODEV;
|
||||
if (!private->ned || !private->gneq)
|
||||
return -ENODEV;
|
||||
uid = &private->uid;
|
||||
spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
|
||||
memset(uid, 0, sizeof(struct dasd_uid));
|
||||
memcpy(uid->vendor, private->ned->HDA_manufacturer,
|
||||
sizeof(uid->vendor) - 1);
|
||||
|
|
@ -792,6 +781,23 @@ static int dasd_eckd_generate_uid(struct dasd_device *device)
|
|||
private->vdsneq->uit[count]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate device unique id that specifies the physical device.
|
||||
*/
|
||||
static int dasd_eckd_generate_uid(struct dasd_device *device)
|
||||
{
|
||||
struct dasd_eckd_private *private;
|
||||
unsigned long flags;
|
||||
|
||||
private = (struct dasd_eckd_private *) device->private;
|
||||
if (!private)
|
||||
return -ENODEV;
|
||||
if (!private->ned || !private->gneq)
|
||||
return -ENODEV;
|
||||
spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
|
||||
create_uid(private);
|
||||
spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -811,6 +817,21 @@ static int dasd_eckd_get_uid(struct dasd_device *device, struct dasd_uid *uid)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* compare device UID with data of a given dasd_eckd_private structure
|
||||
* return 0 for match
|
||||
*/
|
||||
static int dasd_eckd_compare_path_uid(struct dasd_device *device,
|
||||
struct dasd_eckd_private *private)
|
||||
{
|
||||
struct dasd_uid device_uid;
|
||||
|
||||
create_uid(private);
|
||||
dasd_eckd_get_uid(device, &device_uid);
|
||||
|
||||
return memcmp(&device_uid, &private->uid, sizeof(struct dasd_uid));
|
||||
}
|
||||
|
||||
static void dasd_eckd_fill_rcd_cqr(struct dasd_device *device,
|
||||
struct dasd_ccw_req *cqr,
|
||||
__u8 *rcd_buffer,
|
||||
|
|
@ -1005,59 +1026,120 @@ static int dasd_eckd_read_conf(struct dasd_device *device)
|
|||
int conf_len, conf_data_saved;
|
||||
int rc;
|
||||
__u8 lpm, opm;
|
||||
struct dasd_eckd_private *private;
|
||||
struct dasd_eckd_private *private, path_private;
|
||||
struct dasd_path *path_data;
|
||||
struct dasd_uid *uid;
|
||||
char print_path_uid[60], print_device_uid[60];
|
||||
|
||||
private = (struct dasd_eckd_private *) device->private;
|
||||
path_data = &device->path_data;
|
||||
opm = ccw_device_get_path_mask(device->cdev);
|
||||
lpm = 0x80;
|
||||
conf_data_saved = 0;
|
||||
/* get configuration data per operational path */
|
||||
for (lpm = 0x80; lpm; lpm>>= 1) {
|
||||
if (lpm & opm) {
|
||||
rc = dasd_eckd_read_conf_lpm(device, &conf_data,
|
||||
&conf_len, lpm);
|
||||
if (rc && rc != -EOPNOTSUPP) { /* -EOPNOTSUPP is ok */
|
||||
DBF_EVENT_DEVID(DBF_WARNING, device->cdev,
|
||||
"Read configuration data returned "
|
||||
"error %d", rc);
|
||||
return rc;
|
||||
}
|
||||
if (conf_data == NULL) {
|
||||
DBF_EVENT_DEVID(DBF_WARNING, device->cdev, "%s",
|
||||
"No configuration data "
|
||||
"retrieved");
|
||||
/* no further analysis possible */
|
||||
path_data->opm |= lpm;
|
||||
continue; /* no error */
|
||||
}
|
||||
/* save first valid configuration data */
|
||||
if (!conf_data_saved) {
|
||||
kfree(private->conf_data);
|
||||
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;
|
||||
kfree(conf_data);
|
||||
continue;
|
||||
}
|
||||
conf_data_saved++;
|
||||
}
|
||||
switch (dasd_eckd_path_access(conf_data, conf_len)) {
|
||||
case 0x02:
|
||||
path_data->npm |= lpm;
|
||||
break;
|
||||
case 0x03:
|
||||
path_data->ppm |= lpm;
|
||||
break;
|
||||
}
|
||||
path_data->opm |= lpm;
|
||||
if (conf_data != private->conf_data)
|
||||
kfree(conf_data);
|
||||
if (!(lpm & opm))
|
||||
continue;
|
||||
rc = dasd_eckd_read_conf_lpm(device, &conf_data,
|
||||
&conf_len, lpm);
|
||||
if (rc && rc != -EOPNOTSUPP) { /* -EOPNOTSUPP is ok */
|
||||
DBF_EVENT_DEVID(DBF_WARNING, device->cdev,
|
||||
"Read configuration data returned "
|
||||
"error %d", rc);
|
||||
return rc;
|
||||
}
|
||||
if (conf_data == NULL) {
|
||||
DBF_EVENT_DEVID(DBF_WARNING, device->cdev, "%s",
|
||||
"No configuration data "
|
||||
"retrieved");
|
||||
/* no further analysis possible */
|
||||
path_data->opm |= lpm;
|
||||
continue; /* no error */
|
||||
}
|
||||
/* save first valid configuration data */
|
||||
if (!conf_data_saved) {
|
||||
kfree(private->conf_data);
|
||||
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;
|
||||
kfree(conf_data);
|
||||
continue;
|
||||
}
|
||||
/*
|
||||
* build device UID that other path data
|
||||
* can be compared to it
|
||||
*/
|
||||
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);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
path_private.conf_data = NULL;
|
||||
path_private.conf_len = 0;
|
||||
}
|
||||
switch (dasd_eckd_path_access(conf_data, conf_len)) {
|
||||
case 0x02:
|
||||
path_data->npm |= lpm;
|
||||
break;
|
||||
case 0x03:
|
||||
path_data->ppm |= lpm;
|
||||
break;
|
||||
}
|
||||
path_data->opm |= lpm;
|
||||
|
||||
if (conf_data != private->conf_data)
|
||||
kfree(conf_data);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1090,12 +1172,61 @@ static int verify_fcx_max_data(struct dasd_device *device, __u8 lpm)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int rebuild_device_uid(struct dasd_device *device,
|
||||
struct path_verification_work_data *data)
|
||||
{
|
||||
struct dasd_eckd_private *private;
|
||||
struct dasd_path *path_data;
|
||||
__u8 lpm, opm;
|
||||
int rc;
|
||||
|
||||
rc = -ENODEV;
|
||||
private = (struct dasd_eckd_private *) device->private;
|
||||
path_data = &device->path_data;
|
||||
opm = device->path_data.opm;
|
||||
|
||||
for (lpm = 0x80; lpm; lpm >>= 1) {
|
||||
if (!(lpm & opm))
|
||||
continue;
|
||||
memset(&data->rcd_buffer, 0, sizeof(data->rcd_buffer));
|
||||
memset(&data->cqr, 0, sizeof(data->cqr));
|
||||
data->cqr.cpaddr = &data->ccw;
|
||||
rc = dasd_eckd_read_conf_immediately(device, &data->cqr,
|
||||
data->rcd_buffer,
|
||||
lpm);
|
||||
|
||||
if (rc) {
|
||||
if (rc == -EOPNOTSUPP) /* -EOPNOTSUPP is ok */
|
||||
continue;
|
||||
DBF_EVENT_DEVID(DBF_WARNING, device->cdev,
|
||||
"Read configuration data "
|
||||
"returned error %d", rc);
|
||||
break;
|
||||
}
|
||||
memcpy(private->conf_data, data->rcd_buffer,
|
||||
DASD_ECKD_RCD_DATA_SIZE);
|
||||
if (dasd_eckd_identify_conf_parts(private)) {
|
||||
rc = -ENODEV;
|
||||
} else /* first valid path is enough */
|
||||
break;
|
||||
}
|
||||
|
||||
if (!rc)
|
||||
rc = dasd_eckd_generate_uid(device);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void do_path_verification_work(struct work_struct *work)
|
||||
{
|
||||
struct path_verification_work_data *data;
|
||||
struct dasd_device *device;
|
||||
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;
|
||||
unsigned long flags;
|
||||
char print_uid[60];
|
||||
int rc;
|
||||
|
||||
data = container_of(work, struct path_verification_work_data, worker);
|
||||
|
|
@ -1112,64 +1243,129 @@ static void do_path_verification_work(struct work_struct *work)
|
|||
ppm = 0;
|
||||
epm = 0;
|
||||
for (lpm = 0x80; lpm; lpm >>= 1) {
|
||||
if (lpm & data->tbvpm) {
|
||||
memset(data->rcd_buffer, 0, sizeof(data->rcd_buffer));
|
||||
memset(&data->cqr, 0, sizeof(data->cqr));
|
||||
data->cqr.cpaddr = &data->ccw;
|
||||
rc = dasd_eckd_read_conf_immediately(device, &data->cqr,
|
||||
data->rcd_buffer,
|
||||
lpm);
|
||||
if (!rc) {
|
||||
switch (dasd_eckd_path_access(data->rcd_buffer,
|
||||
DASD_ECKD_RCD_DATA_SIZE)) {
|
||||
case 0x02:
|
||||
npm |= lpm;
|
||||
break;
|
||||
case 0x03:
|
||||
ppm |= lpm;
|
||||
break;
|
||||
}
|
||||
opm |= lpm;
|
||||
} else if (rc == -EOPNOTSUPP) {
|
||||
DBF_EVENT_DEVID(DBF_WARNING, device->cdev, "%s",
|
||||
"path verification: No configuration "
|
||||
"data retrieved");
|
||||
opm |= lpm;
|
||||
} else if (rc == -EAGAIN) {
|
||||
DBF_EVENT_DEVID(DBF_WARNING, device->cdev, "%s",
|
||||
if (!(lpm & data->tbvpm))
|
||||
continue;
|
||||
memset(&data->rcd_buffer, 0, sizeof(data->rcd_buffer));
|
||||
memset(&data->cqr, 0, sizeof(data->cqr));
|
||||
data->cqr.cpaddr = &data->ccw;
|
||||
rc = dasd_eckd_read_conf_immediately(device, &data->cqr,
|
||||
data->rcd_buffer,
|
||||
lpm);
|
||||
if (!rc) {
|
||||
switch (dasd_eckd_path_access(data->rcd_buffer,
|
||||
DASD_ECKD_RCD_DATA_SIZE)
|
||||
) {
|
||||
case 0x02:
|
||||
npm |= lpm;
|
||||
break;
|
||||
case 0x03:
|
||||
ppm |= lpm;
|
||||
break;
|
||||
}
|
||||
opm |= lpm;
|
||||
} else if (rc == -EOPNOTSUPP) {
|
||||
DBF_EVENT_DEVID(DBF_WARNING, device->cdev, "%s",
|
||||
"path verification: No configuration "
|
||||
"data retrieved");
|
||||
opm |= lpm;
|
||||
} else if (rc == -EAGAIN) {
|
||||
DBF_EVENT_DEVID(DBF_WARNING, device->cdev, "%s",
|
||||
"path verification: device is stopped,"
|
||||
" try again later");
|
||||
epm |= lpm;
|
||||
} else {
|
||||
dev_warn(&device->cdev->dev,
|
||||
"Reading device feature codes failed "
|
||||
"(rc=%d) for new path %x\n", rc, lpm);
|
||||
continue;
|
||||
}
|
||||
if (verify_fcx_max_data(device, lpm)) {
|
||||
epm |= lpm;
|
||||
} else {
|
||||
dev_warn(&device->cdev->dev,
|
||||
"Reading device feature codes failed "
|
||||
"(rc=%d) for new path %x\n", rc, lpm);
|
||||
continue;
|
||||
}
|
||||
if (verify_fcx_max_data(device, lpm)) {
|
||||
opm &= ~lpm;
|
||||
npm &= ~lpm;
|
||||
ppm &= ~lpm;
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* save conf_data for comparison after
|
||||
* rebuild_device_uid may have changed
|
||||
* the original data
|
||||
*/
|
||||
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;
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* compare path UID with device UID only if at least
|
||||
* one valid path is left
|
||||
* in other case the device UID may have changed and
|
||||
* the first working path UID will be used as device UID
|
||||
*/
|
||||
if (device->path_data.opm &&
|
||||
dasd_eckd_compare_path_uid(device, &path_private)) {
|
||||
/*
|
||||
* the comparison was not successful
|
||||
* rebuild the device UID with at least one
|
||||
* known path in case a z/VM hyperswap command
|
||||
* has changed the device
|
||||
*
|
||||
* after this compare again
|
||||
*
|
||||
* if either the rebuild or the recompare fails
|
||||
* the path can not be used
|
||||
*/
|
||||
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);
|
||||
dev_err(&device->cdev->dev,
|
||||
"The newly added channel path %02X "
|
||||
"will not be used because it leads "
|
||||
"to a different device %s\n",
|
||||
lpm, print_uid);
|
||||
opm &= ~lpm;
|
||||
npm &= ~lpm;
|
||||
ppm &= ~lpm;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* There is a small chance that a path is lost again between
|
||||
* above path verification and the following modification of
|
||||
* the device opm mask. We could avoid that race here by using
|
||||
* yet another path mask, but we rather deal with this unlikely
|
||||
* situation in dasd_start_IO.
|
||||
*/
|
||||
spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
|
||||
if (!device->path_data.opm && opm) {
|
||||
device->path_data.opm = opm;
|
||||
dasd_generic_path_operational(device);
|
||||
} else
|
||||
device->path_data.opm |= opm;
|
||||
device->path_data.npm |= npm;
|
||||
device->path_data.ppm |= ppm;
|
||||
device->path_data.tbvpm |= epm;
|
||||
spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags);
|
||||
}
|
||||
/*
|
||||
* There is a small chance that a path is lost again between
|
||||
* above path verification and the following modification of
|
||||
* the device opm mask. We could avoid that race here by using
|
||||
* yet another path mask, but we rather deal with this unlikely
|
||||
* situation in dasd_start_IO.
|
||||
*/
|
||||
spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
|
||||
if (!device->path_data.opm && opm) {
|
||||
device->path_data.opm = opm;
|
||||
dasd_generic_path_operational(device);
|
||||
} else
|
||||
device->path_data.opm |= opm;
|
||||
device->path_data.npm |= npm;
|
||||
device->path_data.ppm |= ppm;
|
||||
device->path_data.tbvpm |= epm;
|
||||
spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags);
|
||||
|
||||
dasd_put_device(device);
|
||||
if (data->isglobal)
|
||||
|
|
@ -1441,11 +1637,6 @@ dasd_eckd_check_characteristics(struct dasd_device *device)
|
|||
device->default_expires = value;
|
||||
}
|
||||
|
||||
/* Generate device unique id */
|
||||
rc = dasd_eckd_generate_uid(device);
|
||||
if (rc)
|
||||
goto out_err1;
|
||||
|
||||
dasd_eckd_get_uid(device, &temp_uid);
|
||||
if (temp_uid.type == UA_BASE_DEVICE) {
|
||||
block = dasd_alloc_block();
|
||||
|
|
@ -2206,7 +2397,7 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_cmd_single(
|
|||
sizeof(struct PFX_eckd_data));
|
||||
} else {
|
||||
if (define_extent(ccw++, cqr->data, first_trk,
|
||||
last_trk, cmd, startdev) == -EAGAIN) {
|
||||
last_trk, cmd, basedev) == -EAGAIN) {
|
||||
/* Clock not in sync and XRC is enabled.
|
||||
* Try again later.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -22,12 +22,9 @@
|
|||
static struct kmem_cache *qdio_q_cache;
|
||||
static struct kmem_cache *qdio_aob_cache;
|
||||
|
||||
struct qaob *qdio_allocate_aob()
|
||||
struct qaob *qdio_allocate_aob(void)
|
||||
{
|
||||
struct qaob *aob;
|
||||
|
||||
aob = kmem_cache_zalloc(qdio_aob_cache, GFP_ATOMIC);
|
||||
return aob;
|
||||
return kmem_cache_zalloc(qdio_aob_cache, GFP_ATOMIC);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(qdio_allocate_aob);
|
||||
|
||||
|
|
@ -180,7 +177,8 @@ static void setup_queues(struct qdio_irq *irq_ptr,
|
|||
setup_queues_misc(q, irq_ptr, qdio_init->input_handler, i);
|
||||
|
||||
q->is_input_q = 1;
|
||||
q->u.in.queue_start_poll = qdio_init->queue_start_poll[i];
|
||||
q->u.in.queue_start_poll = qdio_init->queue_start_poll_array ?
|
||||
qdio_init->queue_start_poll_array[i] : NULL;
|
||||
|
||||
setup_storage_lists(q, irq_ptr, input_sbal_array, i);
|
||||
input_sbal_array += QDIO_MAX_BUFFERS_PER_Q;
|
||||
|
|
|
|||
|
|
@ -56,11 +56,6 @@
|
|||
#define PCIXCC_MAX_ICA_RESPONSE_SIZE 0x77c /* max size type86 v2 reply */
|
||||
|
||||
#define PCIXCC_MAX_XCRB_MESSAGE_SIZE (12*1024)
|
||||
#define PCIXCC_MAX_XCRB_RESPONSE_SIZE PCIXCC_MAX_XCRB_MESSAGE_SIZE
|
||||
#define PCIXCC_MAX_XCRB_DATA_SIZE (11*1024)
|
||||
#define PCIXCC_MAX_XCRB_REPLY_SIZE (5*1024)
|
||||
|
||||
#define PCIXCC_MAX_RESPONSE_SIZE PCIXCC_MAX_XCRB_RESPONSE_SIZE
|
||||
|
||||
#define PCIXCC_CLEANUP_TIME (15*HZ)
|
||||
|
||||
|
|
@ -265,7 +260,7 @@ static int ICACRT_msg_to_type6CRT_msgX(struct zcrypt_device *zdev,
|
|||
* @ap_msg: pointer to AP message
|
||||
* @xcRB: pointer to user input data
|
||||
*
|
||||
* Returns 0 on success or -EFAULT.
|
||||
* Returns 0 on success or -EFAULT, -EINVAL.
|
||||
*/
|
||||
struct type86_fmt2_msg {
|
||||
struct type86_hdr hdr;
|
||||
|
|
@ -295,19 +290,12 @@ static int XCRB_msg_to_type6CPRB_msgX(struct zcrypt_device *zdev,
|
|||
CEIL4(xcRB->request_control_blk_length) +
|
||||
xcRB->request_data_length;
|
||||
if (ap_msg->length > PCIXCC_MAX_XCRB_MESSAGE_SIZE)
|
||||
return -EFAULT;
|
||||
if (CEIL4(xcRB->reply_control_blk_length) > PCIXCC_MAX_XCRB_REPLY_SIZE)
|
||||
return -EFAULT;
|
||||
if (CEIL4(xcRB->reply_data_length) > PCIXCC_MAX_XCRB_DATA_SIZE)
|
||||
return -EFAULT;
|
||||
replylen = CEIL4(xcRB->reply_control_blk_length) +
|
||||
CEIL4(xcRB->reply_data_length) +
|
||||
sizeof(struct type86_fmt2_msg);
|
||||
if (replylen > PCIXCC_MAX_XCRB_RESPONSE_SIZE) {
|
||||
xcRB->reply_control_blk_length = PCIXCC_MAX_XCRB_RESPONSE_SIZE -
|
||||
(sizeof(struct type86_fmt2_msg) +
|
||||
CEIL4(xcRB->reply_data_length));
|
||||
}
|
||||
return -EINVAL;
|
||||
replylen = sizeof(struct type86_fmt2_msg) +
|
||||
CEIL4(xcRB->reply_control_blk_length) +
|
||||
xcRB->reply_data_length;
|
||||
if (replylen > PCIXCC_MAX_XCRB_MESSAGE_SIZE)
|
||||
return -EINVAL;
|
||||
|
||||
/* prepare type6 header */
|
||||
msg->hdr = static_type6_hdrX;
|
||||
|
|
@ -326,7 +314,7 @@ static int XCRB_msg_to_type6CPRB_msgX(struct zcrypt_device *zdev,
|
|||
return -EFAULT;
|
||||
if (msg->cprbx.cprb_len + sizeof(msg->hdr.function_code) >
|
||||
xcRB->request_control_blk_length)
|
||||
return -EFAULT;
|
||||
return -EINVAL;
|
||||
function_code = ((unsigned char *)&msg->cprbx) + msg->cprbx.cprb_len;
|
||||
memcpy(msg->hdr.function_code, function_code, sizeof(msg->hdr.function_code));
|
||||
|
||||
|
|
@ -678,7 +666,7 @@ static void zcrypt_pcixcc_receive(struct ap_device *ap_dev,
|
|||
break;
|
||||
case PCIXCC_RESPONSE_TYPE_XCRB:
|
||||
length = t86r->fmt2.offset2 + t86r->fmt2.count2;
|
||||
length = min(PCIXCC_MAX_XCRB_RESPONSE_SIZE, length);
|
||||
length = min(PCIXCC_MAX_XCRB_MESSAGE_SIZE, length);
|
||||
memcpy(msg->message, reply->message, length);
|
||||
break;
|
||||
default:
|
||||
|
|
@ -1043,7 +1031,7 @@ static int zcrypt_pcixcc_probe(struct ap_device *ap_dev)
|
|||
struct zcrypt_device *zdev;
|
||||
int rc = 0;
|
||||
|
||||
zdev = zcrypt_device_alloc(PCIXCC_MAX_RESPONSE_SIZE);
|
||||
zdev = zcrypt_device_alloc(PCIXCC_MAX_XCRB_MESSAGE_SIZE);
|
||||
if (!zdev)
|
||||
return -ENOMEM;
|
||||
zdev->ap_dev = ap_dev;
|
||||
|
|
|
|||
|
|
@ -4552,7 +4552,7 @@ static int qeth_qdio_establish(struct qeth_card *card)
|
|||
init_data.no_output_qs = card->qdio.no_out_queues;
|
||||
init_data.input_handler = card->discipline.input_handler;
|
||||
init_data.output_handler = card->discipline.output_handler;
|
||||
init_data.queue_start_poll = queue_start_poll;
|
||||
init_data.queue_start_poll_array = queue_start_poll;
|
||||
init_data.int_parm = (unsigned long) card;
|
||||
init_data.input_sbal_addr_array = (void **) in_sbal_ptrs;
|
||||
init_data.output_sbal_addr_array = (void **) out_sbal_ptrs;
|
||||
|
|
|
|||
Loading…
Reference in a new issue