aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/char/tape_3590.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/s390/char/tape_3590.c')
-rw-r--r--drivers/s390/char/tape_3590.c124
1 files changed, 88 insertions, 36 deletions
diff --git a/drivers/s390/char/tape_3590.c b/drivers/s390/char/tape_3590.c
index fc993acf99b6..a7d570728882 100644
--- a/drivers/s390/char/tape_3590.c
+++ b/drivers/s390/char/tape_3590.c
@@ -24,6 +24,8 @@
24#include "tape_std.h" 24#include "tape_std.h"
25#include "tape_3590.h" 25#include "tape_3590.h"
26 26
27static struct workqueue_struct *tape_3590_wq;
28
27/* 29/*
28 * Pointer to debug area. 30 * Pointer to debug area.
29 */ 31 */
@@ -31,7 +33,7 @@ debug_info_t *TAPE_DBF_AREA = NULL;
31EXPORT_SYMBOL(TAPE_DBF_AREA); 33EXPORT_SYMBOL(TAPE_DBF_AREA);
32 34
33/******************************************************************* 35/*******************************************************************
34 * Error Recovery fuctions: 36 * Error Recovery functions:
35 * - Read Opposite: implemented 37 * - Read Opposite: implemented
36 * - Read Device (buffered) log: BRA 38 * - Read Device (buffered) log: BRA
37 * - Read Library log: BRA 39 * - Read Library log: BRA
@@ -327,17 +329,17 @@ out:
327/* 329/*
328 * Enable encryption 330 * Enable encryption
329 */ 331 */
330static int tape_3592_enable_crypt(struct tape_device *device) 332static struct tape_request *__tape_3592_enable_crypt(struct tape_device *device)
331{ 333{
332 struct tape_request *request; 334 struct tape_request *request;
333 char *data; 335 char *data;
334 336
335 DBF_EVENT(6, "tape_3592_enable_crypt\n"); 337 DBF_EVENT(6, "tape_3592_enable_crypt\n");
336 if (!crypt_supported(device)) 338 if (!crypt_supported(device))
337 return -ENOSYS; 339 return ERR_PTR(-ENOSYS);
338 request = tape_alloc_request(2, 72); 340 request = tape_alloc_request(2, 72);
339 if (IS_ERR(request)) 341 if (IS_ERR(request))
340 return PTR_ERR(request); 342 return request;
341 data = request->cpdata; 343 data = request->cpdata;
342 memset(data,0,72); 344 memset(data,0,72);
343 345
@@ -352,23 +354,42 @@ static int tape_3592_enable_crypt(struct tape_device *device)
352 request->op = TO_CRYPT_ON; 354 request->op = TO_CRYPT_ON;
353 tape_ccw_cc(request->cpaddr, MODE_SET_CB, 36, data); 355 tape_ccw_cc(request->cpaddr, MODE_SET_CB, 36, data);
354 tape_ccw_end(request->cpaddr + 1, MODE_SET_CB, 36, data + 36); 356 tape_ccw_end(request->cpaddr + 1, MODE_SET_CB, 36, data + 36);
357 return request;
358}
359
360static int tape_3592_enable_crypt(struct tape_device *device)
361{
362 struct tape_request *request;
363
364 request = __tape_3592_enable_crypt(device);
365 if (IS_ERR(request))
366 return PTR_ERR(request);
355 return tape_do_io_free(device, request); 367 return tape_do_io_free(device, request);
356} 368}
357 369
370static void tape_3592_enable_crypt_async(struct tape_device *device)
371{
372 struct tape_request *request;
373
374 request = __tape_3592_enable_crypt(device);
375 if (!IS_ERR(request))
376 tape_do_io_async_free(device, request);
377}
378
358/* 379/*
359 * Disable encryption 380 * Disable encryption
360 */ 381 */
361static int tape_3592_disable_crypt(struct tape_device *device) 382static struct tape_request *__tape_3592_disable_crypt(struct tape_device *device)
362{ 383{
363 struct tape_request *request; 384 struct tape_request *request;
364 char *data; 385 char *data;
365 386
366 DBF_EVENT(6, "tape_3592_disable_crypt\n"); 387 DBF_EVENT(6, "tape_3592_disable_crypt\n");
367 if (!crypt_supported(device)) 388 if (!crypt_supported(device))
368 return -ENOSYS; 389 return ERR_PTR(-ENOSYS);
369 request = tape_alloc_request(2, 72); 390 request = tape_alloc_request(2, 72);
370 if (IS_ERR(request)) 391 if (IS_ERR(request))
371 return PTR_ERR(request); 392 return request;
372 data = request->cpdata; 393 data = request->cpdata;
373 memset(data,0,72); 394 memset(data,0,72);
374 395
@@ -381,9 +402,28 @@ static int tape_3592_disable_crypt(struct tape_device *device)
381 tape_ccw_cc(request->cpaddr, MODE_SET_CB, 36, data); 402 tape_ccw_cc(request->cpaddr, MODE_SET_CB, 36, data);
382 tape_ccw_end(request->cpaddr + 1, MODE_SET_CB, 36, data + 36); 403 tape_ccw_end(request->cpaddr + 1, MODE_SET_CB, 36, data + 36);
383 404
405 return request;
406}
407
408static int tape_3592_disable_crypt(struct tape_device *device)
409{
410 struct tape_request *request;
411
412 request = __tape_3592_disable_crypt(device);
413 if (IS_ERR(request))
414 return PTR_ERR(request);
384 return tape_do_io_free(device, request); 415 return tape_do_io_free(device, request);
385} 416}
386 417
418static void tape_3592_disable_crypt_async(struct tape_device *device)
419{
420 struct tape_request *request;
421
422 request = __tape_3592_disable_crypt(device);
423 if (!IS_ERR(request))
424 tape_do_io_async_free(device, request);
425}
426
387/* 427/*
388 * IOCTL: Set encryption status 428 * IOCTL: Set encryption status
389 */ 429 */
@@ -455,8 +495,7 @@ tape_3590_ioctl(struct tape_device *device, unsigned int cmd, unsigned long arg)
455/* 495/*
456 * SENSE Medium: Get Sense data about medium state 496 * SENSE Medium: Get Sense data about medium state
457 */ 497 */
458static int 498static int tape_3590_sense_medium(struct tape_device *device)
459tape_3590_sense_medium(struct tape_device *device)
460{ 499{
461 struct tape_request *request; 500 struct tape_request *request;
462 501
@@ -468,6 +507,18 @@ tape_3590_sense_medium(struct tape_device *device)
468 return tape_do_io_free(device, request); 507 return tape_do_io_free(device, request);
469} 508}
470 509
510static void tape_3590_sense_medium_async(struct tape_device *device)
511{
512 struct tape_request *request;
513
514 request = tape_alloc_request(1, 128);
515 if (IS_ERR(request))
516 return;
517 request->op = TO_MSEN;
518 tape_ccw_end(request->cpaddr, MEDIUM_SENSE, 128, request->cpdata);
519 tape_do_io_async_free(device, request);
520}
521
471/* 522/*
472 * MTTELL: Tell block. Return the number of block relative to current file. 523 * MTTELL: Tell block. Return the number of block relative to current file.
473 */ 524 */
@@ -544,15 +595,14 @@ tape_3590_read_opposite(struct tape_device *device,
544 * 2. The attention msg is written to the "read subsystem data" buffer. 595 * 2. The attention msg is written to the "read subsystem data" buffer.
545 * In this case we probably should print it to the console. 596 * In this case we probably should print it to the console.
546 */ 597 */
547static int 598static void tape_3590_read_attmsg_async(struct tape_device *device)
548tape_3590_read_attmsg(struct tape_device *device)
549{ 599{
550 struct tape_request *request; 600 struct tape_request *request;
551 char *buf; 601 char *buf;
552 602
553 request = tape_alloc_request(3, 4096); 603 request = tape_alloc_request(3, 4096);
554 if (IS_ERR(request)) 604 if (IS_ERR(request))
555 return PTR_ERR(request); 605 return;
556 request->op = TO_READ_ATTMSG; 606 request->op = TO_READ_ATTMSG;
557 buf = request->cpdata; 607 buf = request->cpdata;
558 buf[0] = PREP_RD_SS_DATA; 608 buf[0] = PREP_RD_SS_DATA;
@@ -560,12 +610,15 @@ tape_3590_read_attmsg(struct tape_device *device)
560 tape_ccw_cc(request->cpaddr, PERFORM_SS_FUNC, 12, buf); 610 tape_ccw_cc(request->cpaddr, PERFORM_SS_FUNC, 12, buf);
561 tape_ccw_cc(request->cpaddr + 1, READ_SS_DATA, 4096 - 12, buf + 12); 611 tape_ccw_cc(request->cpaddr + 1, READ_SS_DATA, 4096 - 12, buf + 12);
562 tape_ccw_end(request->cpaddr + 2, NOP, 0, NULL); 612 tape_ccw_end(request->cpaddr + 2, NOP, 0, NULL);
563 return tape_do_io_free(device, request); 613 tape_do_io_async_free(device, request);
564} 614}
565 615
566/* 616/*
567 * These functions are used to schedule follow-up actions from within an 617 * These functions are used to schedule follow-up actions from within an
568 * interrupt context (like unsolicited interrupts). 618 * interrupt context (like unsolicited interrupts).
619 * Note: the work handler is called by the system work queue. The tape
620 * commands started by the handler need to be asynchrounous, otherwise
621 * a deadlock can occur e.g. in case of a deferred cc=1 (see __tape_do_irq).
569 */ 622 */
570struct work_handler_data { 623struct work_handler_data {
571 struct tape_device *device; 624 struct tape_device *device;
@@ -581,16 +634,16 @@ tape_3590_work_handler(struct work_struct *work)
581 634
582 switch (p->op) { 635 switch (p->op) {
583 case TO_MSEN: 636 case TO_MSEN:
584 tape_3590_sense_medium(p->device); 637 tape_3590_sense_medium_async(p->device);
585 break; 638 break;
586 case TO_READ_ATTMSG: 639 case TO_READ_ATTMSG:
587 tape_3590_read_attmsg(p->device); 640 tape_3590_read_attmsg_async(p->device);
588 break; 641 break;
589 case TO_CRYPT_ON: 642 case TO_CRYPT_ON:
590 tape_3592_enable_crypt(p->device); 643 tape_3592_enable_crypt_async(p->device);
591 break; 644 break;
592 case TO_CRYPT_OFF: 645 case TO_CRYPT_OFF:
593 tape_3592_disable_crypt(p->device); 646 tape_3592_disable_crypt_async(p->device);
594 break; 647 break;
595 default: 648 default:
596 DBF_EVENT(3, "T3590: work handler undefined for " 649 DBF_EVENT(3, "T3590: work handler undefined for "
@@ -613,7 +666,7 @@ tape_3590_schedule_work(struct tape_device *device, enum tape_op op)
613 p->device = tape_get_device(device); 666 p->device = tape_get_device(device);
614 p->op = op; 667 p->op = op;
615 668
616 schedule_work(&p->work); 669 queue_work(tape_3590_wq, &p->work);
617 return 0; 670 return 0;
618} 671}
619 672
@@ -743,10 +796,8 @@ static void tape_3590_med_state_set(struct tape_device *device,
743static int 796static int
744tape_3590_done(struct tape_device *device, struct tape_request *request) 797tape_3590_done(struct tape_device *device, struct tape_request *request)
745{ 798{
746 struct tape_3590_disc_data *disc_data;
747 799
748 DBF_EVENT(6, "%s done\n", tape_op_verbose[request->op]); 800 DBF_EVENT(6, "%s done\n", tape_op_verbose[request->op]);
749 disc_data = device->discdata;
750 801
751 switch (request->op) { 802 switch (request->op) {
752 case TO_BSB: 803 case TO_BSB:
@@ -798,7 +849,7 @@ tape_3590_done(struct tape_device *device, struct tape_request *request)
798} 849}
799 850
800/* 851/*
801 * This fuction is called, when error recovery was successfull 852 * This function is called, when error recovery was successful
802 */ 853 */
803static inline int 854static inline int
804tape_3590_erp_succeded(struct tape_device *device, struct tape_request *request) 855tape_3590_erp_succeded(struct tape_device *device, struct tape_request *request)
@@ -809,7 +860,7 @@ tape_3590_erp_succeded(struct tape_device *device, struct tape_request *request)
809} 860}
810 861
811/* 862/*
812 * This fuction is called, when error recovery was not successfull 863 * This function is called, when error recovery was not successful
813 */ 864 */
814static inline int 865static inline int
815tape_3590_erp_failed(struct tape_device *device, struct tape_request *request, 866tape_3590_erp_failed(struct tape_device *device, struct tape_request *request,
@@ -1341,17 +1392,12 @@ tape_3590_print_era_msg(struct tape_device *device, struct irb *irb)
1341static int tape_3590_crypt_error(struct tape_device *device, 1392static int tape_3590_crypt_error(struct tape_device *device,
1342 struct tape_request *request, struct irb *irb) 1393 struct tape_request *request, struct irb *irb)
1343{ 1394{
1344 u8 cu_rc, ekm_rc1; 1395 u8 cu_rc;
1345 u16 ekm_rc2; 1396 u16 ekm_rc2;
1346 u32 drv_rc;
1347 const char *bus_id;
1348 char *sense; 1397 char *sense;
1349 1398
1350 sense = ((struct tape_3590_sense *) irb->ecw)->fmt.data; 1399 sense = ((struct tape_3590_sense *) irb->ecw)->fmt.data;
1351 bus_id = dev_name(&device->cdev->dev);
1352 cu_rc = sense[0]; 1400 cu_rc = sense[0];
1353 drv_rc = *((u32*) &sense[5]) & 0xffffff;
1354 ekm_rc1 = sense[9];
1355 ekm_rc2 = *((u16*) &sense[10]); 1401 ekm_rc2 = *((u16*) &sense[10]);
1356 if ((cu_rc == 0) && (ekm_rc2 == 0xee31)) 1402 if ((cu_rc == 0) && (ekm_rc2 == 0xee31))
1357 /* key not defined on EKM */ 1403 /* key not defined on EKM */
@@ -1376,7 +1422,6 @@ tape_3590_unit_check(struct tape_device *device, struct tape_request *request,
1376 struct irb *irb) 1422 struct irb *irb)
1377{ 1423{
1378 struct tape_3590_sense *sense; 1424 struct tape_3590_sense *sense;
1379 int rc;
1380 1425
1381#ifdef CONFIG_S390_TAPE_BLOCK 1426#ifdef CONFIG_S390_TAPE_BLOCK
1382 if (request->op == TO_BLOCK) { 1427 if (request->op == TO_BLOCK) {
@@ -1401,7 +1446,6 @@ tape_3590_unit_check(struct tape_device *device, struct tape_request *request,
1401 * - "break": basic error recovery is done 1446 * - "break": basic error recovery is done
1402 * - "goto out:": just print error message if available 1447 * - "goto out:": just print error message if available
1403 */ 1448 */
1404 rc = -EIO;
1405 switch (sense->rc_rqc) { 1449 switch (sense->rc_rqc) {
1406 1450
1407 case 0x1110: 1451 case 0x1110:
@@ -1629,7 +1673,7 @@ fail_kmalloc:
1629static void 1673static void
1630tape_3590_cleanup_device(struct tape_device *device) 1674tape_3590_cleanup_device(struct tape_device *device)
1631{ 1675{
1632 flush_scheduled_work(); 1676 flush_workqueue(tape_3590_wq);
1633 tape_std_unassign(device); 1677 tape_std_unassign(device);
1634 1678
1635 kfree(device->discdata); 1679 kfree(device->discdata);
@@ -1708,8 +1752,10 @@ tape_3590_online(struct ccw_device *cdev)
1708} 1752}
1709 1753
1710static struct ccw_driver tape_3590_driver = { 1754static struct ccw_driver tape_3590_driver = {
1711 .name = "tape_3590", 1755 .driver = {
1712 .owner = THIS_MODULE, 1756 .name = "tape_3590",
1757 .owner = THIS_MODULE,
1758 },
1713 .ids = tape_3590_ids, 1759 .ids = tape_3590_ids,
1714 .probe = tape_generic_probe, 1760 .probe = tape_generic_probe,
1715 .remove = tape_generic_remove, 1761 .remove = tape_generic_remove,
@@ -1733,11 +1779,17 @@ tape_3590_init(void)
1733#endif 1779#endif
1734 1780
1735 DBF_EVENT(3, "3590 init\n"); 1781 DBF_EVENT(3, "3590 init\n");
1782
1783 tape_3590_wq = alloc_workqueue("tape_3590", 0, 0);
1784 if (!tape_3590_wq)
1785 return -ENOMEM;
1786
1736 /* Register driver for 3590 tapes. */ 1787 /* Register driver for 3590 tapes. */
1737 rc = ccw_driver_register(&tape_3590_driver); 1788 rc = ccw_driver_register(&tape_3590_driver);
1738 if (rc) 1789 if (rc) {
1790 destroy_workqueue(tape_3590_wq);
1739 DBF_EVENT(3, "3590 init failed\n"); 1791 DBF_EVENT(3, "3590 init failed\n");
1740 else 1792 } else
1741 DBF_EVENT(3, "3590 registered\n"); 1793 DBF_EVENT(3, "3590 registered\n");
1742 return rc; 1794 return rc;
1743} 1795}
@@ -1746,7 +1798,7 @@ static void
1746tape_3590_exit(void) 1798tape_3590_exit(void)
1747{ 1799{
1748 ccw_driver_unregister(&tape_3590_driver); 1800 ccw_driver_unregister(&tape_3590_driver);
1749 1801 destroy_workqueue(tape_3590_wq);
1750 debug_unregister(TAPE_DBF_AREA); 1802 debug_unregister(TAPE_DBF_AREA);
1751} 1803}
1752 1804