diff --git a/drivers/s390/char/tape.h b/drivers/s390/char/tape.h index bb4ff537729deb53fbcb629b7e47278643fd406a..3b52f5c1dbefc2d1b388d74c8d46842a72ee28a3 100644 --- a/drivers/s390/char/tape.h +++ b/drivers/s390/char/tape.h @@ -103,6 +103,7 @@ enum tape_op { TO_CRYPT_OFF, /* Disable encrpytion */ TO_KEKL_SET, /* Set KEK label */ TO_KEKL_QUERY, /* Query KEK label */ + TO_RDC, /* Read device characteristics */ TO_SIZE, /* #entries in tape_op_t */ }; diff --git a/drivers/s390/char/tape_3590.c b/drivers/s390/char/tape_3590.c index 50f5edab83d7fcc79672ceff0c75cc701fd4b7a0..7e2b2ab492641a53aea103845ffe9f1b8c1a6ad8 100644 --- a/drivers/s390/char/tape_3590.c +++ b/drivers/s390/char/tape_3590.c @@ -788,6 +788,7 @@ tape_3590_done(struct tape_device *device, struct tape_request *request) case TO_SIZE: case TO_KEKL_SET: case TO_KEKL_QUERY: + case TO_RDC: break; } return TAPE_IO_SUCCESS; @@ -1549,6 +1550,26 @@ tape_3590_irq(struct tape_device *device, struct tape_request *request, return TAPE_IO_STOP; } + +static int tape_3590_read_dev_chars(struct tape_device *device, + struct tape_3590_rdc_data *rdc_data) +{ + int rc; + struct tape_request *request; + + request = tape_alloc_request(1, sizeof(*rdc_data)); + if (IS_ERR(request)) + return PTR_ERR(request); + request->op = TO_RDC; + tape_ccw_end(request->cpaddr, CCW_CMD_RDC, sizeof(*rdc_data), + request->cpdata); + rc = tape_do_io(device, request); + if (rc == 0) + memcpy(rdc_data, request->cpdata, sizeof(*rdc_data)); + tape_free_request(request); + return rc; +} + /* * Setup device function */ @@ -1557,7 +1578,7 @@ tape_3590_setup_device(struct tape_device *device) { int rc; struct tape_3590_disc_data *data; - char *rdc_data; + struct tape_3590_rdc_data *rdc_data; DBF_EVENT(6, "3590 device setup\n"); data = kzalloc(sizeof(struct tape_3590_disc_data), GFP_KERNEL | GFP_DMA); @@ -1566,12 +1587,12 @@ tape_3590_setup_device(struct tape_device *device) data->read_back_op = READ_PREVIOUS; device->discdata = data; - rdc_data = kmalloc(64, GFP_KERNEL | GFP_DMA); + rdc_data = kmalloc(sizeof(*rdc_data), GFP_KERNEL | GFP_DMA); if (!rdc_data) { rc = -ENOMEM; goto fail_kmalloc; } - rc = read_dev_chars(device->cdev, (void**)&rdc_data, 64); + rc = tape_3590_read_dev_chars(device, rdc_data); if (rc) { DBF_LH(3, "Read device characteristics failed!\n"); goto fail_kmalloc; @@ -1579,7 +1600,7 @@ tape_3590_setup_device(struct tape_device *device) rc = tape_std_assign(device); if (rc) goto fail_rdc_data; - if (rdc_data[31] == 0x13) { + if (rdc_data->data[31] == 0x13) { PRINT_INFO("Device has crypto support\n"); data->crypt_info.capability |= TAPE390_CRYPT_SUPPORTED_MASK; tape_3592_disable_crypt(device); diff --git a/drivers/s390/char/tape_3590.h b/drivers/s390/char/tape_3590.h index aa5138807af1d07801d99183e766e08fefda9104..4534055f1376aa3bceb0fdbc7505401fad64877c 100644 --- a/drivers/s390/char/tape_3590.h +++ b/drivers/s390/char/tape_3590.h @@ -129,6 +129,10 @@ struct tape_3590_med_sense { char pad2[116]; } __attribute__ ((packed)); +struct tape_3590_rdc_data { + char data[64]; +} __attribute__ ((packed)); + /* Datastructures for 3592 encryption support */ struct tape3592_kekl { diff --git a/drivers/s390/char/tape_core.c b/drivers/s390/char/tape_core.c index e2a8a1a04bab46750240326cfce6ca4f634eca2c..2fae6338ee1c146fd09e9c2824129cfaa1e9d9d8 100644 --- a/drivers/s390/char/tape_core.c +++ b/drivers/s390/char/tape_core.c @@ -73,7 +73,7 @@ const char *tape_op_verbose[TO_SIZE] = [TO_DIS] = "DIS", [TO_ASSIGN] = "ASS", [TO_UNASSIGN] = "UAS", [TO_CRYPT_ON] = "CON", [TO_CRYPT_OFF] = "COF", [TO_KEKL_SET] = "KLS", - [TO_KEKL_QUERY] = "KLQ", + [TO_KEKL_QUERY] = "KLQ",[TO_RDC] = "RDC", }; static int @@ -911,6 +911,7 @@ __tape_start_request(struct tape_device *device, struct tape_request *request) case TO_ASSIGN: case TO_UNASSIGN: case TO_READ_ATTMSG: + case TO_RDC: if (device->tape_state == TS_INIT) break; if (device->tape_state == TS_UNUSED)