Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
at v2.6.17-rc2 1026 lines 24 kB view raw
1/* 2 pt.c (c) 1998 Grant R. Guenther <grant@torque.net> 3 Under the terms of the GNU General Public License. 4 5 This is the high-level driver for parallel port ATAPI tape 6 drives based on chips supported by the paride module. 7 8 The driver implements both rewinding and non-rewinding 9 devices, filemarks, and the rewind ioctl. It allocates 10 a small internal "bounce buffer" for each open device, but 11 otherwise expects buffering and blocking to be done at the 12 user level. As with most block-structured tapes, short 13 writes are padded to full tape blocks, so reading back a file 14 may return more data than was actually written. 15 16 By default, the driver will autoprobe for a single parallel 17 port ATAPI tape drive, but if their individual parameters are 18 specified, the driver can handle up to 4 drives. 19 20 The rewinding devices are named /dev/pt0, /dev/pt1, ... 21 while the non-rewinding devices are /dev/npt0, /dev/npt1, etc. 22 23 The behaviour of the pt driver can be altered by setting 24 some parameters from the insmod command line. The following 25 parameters are adjustable: 26 27 drive0 These four arguments can be arrays of 28 drive1 1-6 integers as follows: 29 drive2 30 drive3 <prt>,<pro>,<uni>,<mod>,<slv>,<dly> 31 32 Where, 33 34 <prt> is the base of the parallel port address for 35 the corresponding drive. (required) 36 37 <pro> is the protocol number for the adapter that 38 supports this drive. These numbers are 39 logged by 'paride' when the protocol modules 40 are initialised. (0 if not given) 41 42 <uni> for those adapters that support chained 43 devices, this is the unit selector for the 44 chain of devices on the given port. It should 45 be zero for devices that don't support chaining. 46 (0 if not given) 47 48 <mod> this can be -1 to choose the best mode, or one 49 of the mode numbers supported by the adapter. 50 (-1 if not given) 51 52 <slv> ATAPI devices can be jumpered to master or slave. 53 Set this to 0 to choose the master drive, 1 to 54 choose the slave, -1 (the default) to choose the 55 first drive found. 56 57 <dly> some parallel ports require the driver to 58 go more slowly. -1 sets a default value that 59 should work with the chosen protocol. Otherwise, 60 set this to a small integer, the larger it is 61 the slower the port i/o. In some cases, setting 62 this to zero will speed up the device. (default -1) 63 64 major You may use this parameter to overide the 65 default major number (96) that this driver 66 will use. Be sure to change the device 67 name as well. 68 69 name This parameter is a character string that 70 contains the name the kernel will use for this 71 device (in /proc output, for instance). 72 (default "pt"). 73 74 verbose This parameter controls the amount of logging 75 that the driver will do. Set it to 0 for 76 normal operation, 1 to see autoprobe progress 77 messages, or 2 to see additional debugging 78 output. (default 0) 79 80 If this driver is built into the kernel, you can use 81 the following command line parameters, with the same values 82 as the corresponding module parameters listed above: 83 84 pt.drive0 85 pt.drive1 86 pt.drive2 87 pt.drive3 88 89 In addition, you can use the parameter pt.disable to disable 90 the driver entirely. 91 92*/ 93 94/* Changes: 95 96 1.01 GRG 1998.05.06 Round up transfer size, fix ready_wait, 97 loosed interpretation of ATAPI standard 98 for clearing error status. 99 Eliminate sti(); 100 1.02 GRG 1998.06.16 Eliminate an Ugh. 101 1.03 GRG 1998.08.15 Adjusted PT_TMO, use HZ in loop timing, 102 extra debugging 103 1.04 GRG 1998.09.24 Repair minor coding error, added jumbo support 104 105*/ 106 107#define PT_VERSION "1.04" 108#define PT_MAJOR 96 109#define PT_NAME "pt" 110#define PT_UNITS 4 111 112/* Here are things one can override from the insmod command. 113 Most are autoprobed by paride unless set here. Verbose is on 114 by default. 115 116*/ 117 118static int verbose = 0; 119static int major = PT_MAJOR; 120static char *name = PT_NAME; 121static int disable = 0; 122 123static int drive0[6] = { 0, 0, 0, -1, -1, -1 }; 124static int drive1[6] = { 0, 0, 0, -1, -1, -1 }; 125static int drive2[6] = { 0, 0, 0, -1, -1, -1 }; 126static int drive3[6] = { 0, 0, 0, -1, -1, -1 }; 127 128static int (*drives[4])[6] = {&drive0, &drive1, &drive2, &drive3}; 129 130#define D_PRT 0 131#define D_PRO 1 132#define D_UNI 2 133#define D_MOD 3 134#define D_SLV 4 135#define D_DLY 5 136 137#define DU (*drives[unit]) 138 139/* end of parameters */ 140 141#include <linux/module.h> 142#include <linux/init.h> 143#include <linux/fs.h> 144#include <linux/devfs_fs_kernel.h> 145#include <linux/delay.h> 146#include <linux/slab.h> 147#include <linux/mtio.h> 148#include <linux/device.h> 149#include <linux/sched.h> /* current, TASK_*, schedule_timeout() */ 150 151#include <asm/uaccess.h> 152 153module_param(verbose, bool, 0); 154module_param(major, int, 0); 155module_param(name, charp, 0); 156module_param_array(drive0, int, NULL, 0); 157module_param_array(drive1, int, NULL, 0); 158module_param_array(drive2, int, NULL, 0); 159module_param_array(drive3, int, NULL, 0); 160 161#include "paride.h" 162 163#define PT_MAX_RETRIES 5 164#define PT_TMO 3000 /* interrupt timeout in jiffies */ 165#define PT_SPIN_DEL 50 /* spin delay in micro-seconds */ 166#define PT_RESET_TMO 30 /* 30 seconds */ 167#define PT_READY_TMO 60 /* 60 seconds */ 168#define PT_REWIND_TMO 1200 /* 20 minutes */ 169 170#define PT_SPIN ((1000000/(HZ*PT_SPIN_DEL))*PT_TMO) 171 172#define STAT_ERR 0x00001 173#define STAT_INDEX 0x00002 174#define STAT_ECC 0x00004 175#define STAT_DRQ 0x00008 176#define STAT_SEEK 0x00010 177#define STAT_WRERR 0x00020 178#define STAT_READY 0x00040 179#define STAT_BUSY 0x00080 180#define STAT_SENSE 0x1f000 181 182#define ATAPI_TEST_READY 0x00 183#define ATAPI_REWIND 0x01 184#define ATAPI_REQ_SENSE 0x03 185#define ATAPI_READ_6 0x08 186#define ATAPI_WRITE_6 0x0a 187#define ATAPI_WFM 0x10 188#define ATAPI_IDENTIFY 0x12 189#define ATAPI_MODE_SENSE 0x1a 190#define ATAPI_LOG_SENSE 0x4d 191 192static int pt_open(struct inode *inode, struct file *file); 193static int pt_ioctl(struct inode *inode, struct file *file, 194 unsigned int cmd, unsigned long arg); 195static int pt_release(struct inode *inode, struct file *file); 196static ssize_t pt_read(struct file *filp, char __user *buf, 197 size_t count, loff_t * ppos); 198static ssize_t pt_write(struct file *filp, const char __user *buf, 199 size_t count, loff_t * ppos); 200static int pt_detect(void); 201 202/* bits in tape->flags */ 203 204#define PT_MEDIA 1 205#define PT_WRITE_OK 2 206#define PT_REWIND 4 207#define PT_WRITING 8 208#define PT_READING 16 209#define PT_EOF 32 210 211#define PT_NAMELEN 8 212#define PT_BUFSIZE 16384 213 214struct pt_unit { 215 struct pi_adapter pia; /* interface to paride layer */ 216 struct pi_adapter *pi; 217 int flags; /* various state flags */ 218 int last_sense; /* result of last request sense */ 219 int drive; /* drive */ 220 atomic_t available; /* 1 if access is available 0 otherwise */ 221 int bs; /* block size */ 222 int capacity; /* Size of tape in KB */ 223 int present; /* device present ? */ 224 char *bufptr; 225 char name[PT_NAMELEN]; /* pf0, pf1, ... */ 226}; 227 228static int pt_identify(struct pt_unit *tape); 229 230static struct pt_unit pt[PT_UNITS]; 231 232static char pt_scratch[512]; /* scratch block buffer */ 233 234/* kernel glue structures */ 235 236static struct file_operations pt_fops = { 237 .owner = THIS_MODULE, 238 .read = pt_read, 239 .write = pt_write, 240 .ioctl = pt_ioctl, 241 .open = pt_open, 242 .release = pt_release, 243}; 244 245/* sysfs class support */ 246static struct class *pt_class; 247 248static inline int status_reg(struct pi_adapter *pi) 249{ 250 return pi_read_regr(pi, 1, 6); 251} 252 253static inline int read_reg(struct pi_adapter *pi, int reg) 254{ 255 return pi_read_regr(pi, 0, reg); 256} 257 258static inline void write_reg(struct pi_adapter *pi, int reg, int val) 259{ 260 pi_write_regr(pi, 0, reg, val); 261} 262 263static inline u8 DRIVE(struct pt_unit *tape) 264{ 265 return 0xa0+0x10*tape->drive; 266} 267 268static int pt_wait(struct pt_unit *tape, int go, int stop, char *fun, char *msg) 269{ 270 int j, r, e, s, p; 271 struct pi_adapter *pi = tape->pi; 272 273 j = 0; 274 while ((((r = status_reg(pi)) & go) || (stop && (!(r & stop)))) 275 && (j++ < PT_SPIN)) 276 udelay(PT_SPIN_DEL); 277 278 if ((r & (STAT_ERR & stop)) || (j >= PT_SPIN)) { 279 s = read_reg(pi, 7); 280 e = read_reg(pi, 1); 281 p = read_reg(pi, 2); 282 if (j >= PT_SPIN) 283 e |= 0x100; 284 if (fun) 285 printk("%s: %s %s: alt=0x%x stat=0x%x err=0x%x" 286 " loop=%d phase=%d\n", 287 tape->name, fun, msg, r, s, e, j, p); 288 return (e << 8) + s; 289 } 290 return 0; 291} 292 293static int pt_command(struct pt_unit *tape, char *cmd, int dlen, char *fun) 294{ 295 struct pi_adapter *pi = tape->pi; 296 pi_connect(pi); 297 298 write_reg(pi, 6, DRIVE(tape)); 299 300 if (pt_wait(tape, STAT_BUSY | STAT_DRQ, 0, fun, "before command")) { 301 pi_disconnect(pi); 302 return -1; 303 } 304 305 write_reg(pi, 4, dlen % 256); 306 write_reg(pi, 5, dlen / 256); 307 write_reg(pi, 7, 0xa0); /* ATAPI packet command */ 308 309 if (pt_wait(tape, STAT_BUSY, STAT_DRQ, fun, "command DRQ")) { 310 pi_disconnect(pi); 311 return -1; 312 } 313 314 if (read_reg(pi, 2) != 1) { 315 printk("%s: %s: command phase error\n", tape->name, fun); 316 pi_disconnect(pi); 317 return -1; 318 } 319 320 pi_write_block(pi, cmd, 12); 321 322 return 0; 323} 324 325static int pt_completion(struct pt_unit *tape, char *buf, char *fun) 326{ 327 struct pi_adapter *pi = tape->pi; 328 int r, s, n, p; 329 330 r = pt_wait(tape, STAT_BUSY, STAT_DRQ | STAT_READY | STAT_ERR, 331 fun, "completion"); 332 333 if (read_reg(pi, 7) & STAT_DRQ) { 334 n = (((read_reg(pi, 4) + 256 * read_reg(pi, 5)) + 335 3) & 0xfffc); 336 p = read_reg(pi, 2) & 3; 337 if (p == 0) 338 pi_write_block(pi, buf, n); 339 if (p == 2) 340 pi_read_block(pi, buf, n); 341 } 342 343 s = pt_wait(tape, STAT_BUSY, STAT_READY | STAT_ERR, fun, "data done"); 344 345 pi_disconnect(pi); 346 347 return (r ? r : s); 348} 349 350static void pt_req_sense(struct pt_unit *tape, int quiet) 351{ 352 char rs_cmd[12] = { ATAPI_REQ_SENSE, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0 }; 353 char buf[16]; 354 int r; 355 356 r = pt_command(tape, rs_cmd, 16, "Request sense"); 357 mdelay(1); 358 if (!r) 359 pt_completion(tape, buf, "Request sense"); 360 361 tape->last_sense = -1; 362 if (!r) { 363 if (!quiet) 364 printk("%s: Sense key: %x, ASC: %x, ASQ: %x\n", 365 tape->name, buf[2] & 0xf, buf[12], buf[13]); 366 tape->last_sense = (buf[2] & 0xf) | ((buf[12] & 0xff) << 8) 367 | ((buf[13] & 0xff) << 16); 368 } 369} 370 371static int pt_atapi(struct pt_unit *tape, char *cmd, int dlen, char *buf, char *fun) 372{ 373 int r; 374 375 r = pt_command(tape, cmd, dlen, fun); 376 mdelay(1); 377 if (!r) 378 r = pt_completion(tape, buf, fun); 379 if (r) 380 pt_req_sense(tape, !fun); 381 382 return r; 383} 384 385static void pt_sleep(int cs) 386{ 387 schedule_timeout_interruptible(cs); 388} 389 390static int pt_poll_dsc(struct pt_unit *tape, int pause, int tmo, char *msg) 391{ 392 struct pi_adapter *pi = tape->pi; 393 int k, e, s; 394 395 k = 0; 396 e = 0; 397 s = 0; 398 while (k < tmo) { 399 pt_sleep(pause); 400 k++; 401 pi_connect(pi); 402 write_reg(pi, 6, DRIVE(tape)); 403 s = read_reg(pi, 7); 404 e = read_reg(pi, 1); 405 pi_disconnect(pi); 406 if (s & (STAT_ERR | STAT_SEEK)) 407 break; 408 } 409 if ((k >= tmo) || (s & STAT_ERR)) { 410 if (k >= tmo) 411 printk("%s: %s DSC timeout\n", tape->name, msg); 412 else 413 printk("%s: %s stat=0x%x err=0x%x\n", tape->name, msg, s, 414 e); 415 pt_req_sense(tape, 0); 416 return 0; 417 } 418 return 1; 419} 420 421static void pt_media_access_cmd(struct pt_unit *tape, int tmo, char *cmd, char *fun) 422{ 423 if (pt_command(tape, cmd, 0, fun)) { 424 pt_req_sense(tape, 0); 425 return; 426 } 427 pi_disconnect(tape->pi); 428 pt_poll_dsc(tape, HZ, tmo, fun); 429} 430 431static void pt_rewind(struct pt_unit *tape) 432{ 433 char rw_cmd[12] = { ATAPI_REWIND, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; 434 435 pt_media_access_cmd(tape, PT_REWIND_TMO, rw_cmd, "rewind"); 436} 437 438static void pt_write_fm(struct pt_unit *tape) 439{ 440 char wm_cmd[12] = { ATAPI_WFM, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 }; 441 442 pt_media_access_cmd(tape, PT_TMO, wm_cmd, "write filemark"); 443} 444 445#define DBMSG(msg) ((verbose>1)?(msg):NULL) 446 447static int pt_reset(struct pt_unit *tape) 448{ 449 struct pi_adapter *pi = tape->pi; 450 int i, k, flg; 451 int expect[5] = { 1, 1, 1, 0x14, 0xeb }; 452 453 pi_connect(pi); 454 write_reg(pi, 6, DRIVE(tape)); 455 write_reg(pi, 7, 8); 456 457 pt_sleep(20 * HZ / 1000); 458 459 k = 0; 460 while ((k++ < PT_RESET_TMO) && (status_reg(pi) & STAT_BUSY)) 461 pt_sleep(HZ / 10); 462 463 flg = 1; 464 for (i = 0; i < 5; i++) 465 flg &= (read_reg(pi, i + 1) == expect[i]); 466 467 if (verbose) { 468 printk("%s: Reset (%d) signature = ", tape->name, k); 469 for (i = 0; i < 5; i++) 470 printk("%3x", read_reg(pi, i + 1)); 471 if (!flg) 472 printk(" (incorrect)"); 473 printk("\n"); 474 } 475 476 pi_disconnect(pi); 477 return flg - 1; 478} 479 480static int pt_ready_wait(struct pt_unit *tape, int tmo) 481{ 482 char tr_cmd[12] = { ATAPI_TEST_READY, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; 483 int k, p; 484 485 k = 0; 486 while (k < tmo) { 487 tape->last_sense = 0; 488 pt_atapi(tape, tr_cmd, 0, NULL, DBMSG("test unit ready")); 489 p = tape->last_sense; 490 if (!p) 491 return 0; 492 if (!(((p & 0xffff) == 0x0402) || ((p & 0xff) == 6))) 493 return p; 494 k++; 495 pt_sleep(HZ); 496 } 497 return 0x000020; /* timeout */ 498} 499 500static void xs(char *buf, char *targ, int offs, int len) 501{ 502 int j, k, l; 503 504 j = 0; 505 l = 0; 506 for (k = 0; k < len; k++) 507 if ((buf[k + offs] != 0x20) || (buf[k + offs] != l)) 508 l = targ[j++] = buf[k + offs]; 509 if (l == 0x20) 510 j--; 511 targ[j] = 0; 512} 513 514static int xn(char *buf, int offs, int size) 515{ 516 int v, k; 517 518 v = 0; 519 for (k = 0; k < size; k++) 520 v = v * 256 + (buf[k + offs] & 0xff); 521 return v; 522} 523 524static int pt_identify(struct pt_unit *tape) 525{ 526 int dt, s; 527 char *ms[2] = { "master", "slave" }; 528 char mf[10], id[18]; 529 char id_cmd[12] = { ATAPI_IDENTIFY, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0 }; 530 char ms_cmd[12] = 531 { ATAPI_MODE_SENSE, 0, 0x2a, 0, 36, 0, 0, 0, 0, 0, 0, 0 }; 532 char ls_cmd[12] = 533 { ATAPI_LOG_SENSE, 0, 0x71, 0, 0, 0, 0, 0, 36, 0, 0, 0 }; 534 char buf[36]; 535 536 s = pt_atapi(tape, id_cmd, 36, buf, "identify"); 537 if (s) 538 return -1; 539 540 dt = buf[0] & 0x1f; 541 if (dt != 1) { 542 if (verbose) 543 printk("%s: Drive %d, unsupported type %d\n", 544 tape->name, tape->drive, dt); 545 return -1; 546 } 547 548 xs(buf, mf, 8, 8); 549 xs(buf, id, 16, 16); 550 551 tape->flags = 0; 552 tape->capacity = 0; 553 tape->bs = 0; 554 555 if (!pt_ready_wait(tape, PT_READY_TMO)) 556 tape->flags |= PT_MEDIA; 557 558 if (!pt_atapi(tape, ms_cmd, 36, buf, "mode sense")) { 559 if (!(buf[2] & 0x80)) 560 tape->flags |= PT_WRITE_OK; 561 tape->bs = xn(buf, 10, 2); 562 } 563 564 if (!pt_atapi(tape, ls_cmd, 36, buf, "log sense")) 565 tape->capacity = xn(buf, 24, 4); 566 567 printk("%s: %s %s, %s", tape->name, mf, id, ms[tape->drive]); 568 if (!(tape->flags & PT_MEDIA)) 569 printk(", no media\n"); 570 else { 571 if (!(tape->flags & PT_WRITE_OK)) 572 printk(", RO"); 573 printk(", blocksize %d, %d MB\n", tape->bs, tape->capacity / 1024); 574 } 575 576 return 0; 577} 578 579 580/* 581 * returns 0, with id set if drive is detected 582 * -1, if drive detection failed 583 */ 584static int pt_probe(struct pt_unit *tape) 585{ 586 if (tape->drive == -1) { 587 for (tape->drive = 0; tape->drive <= 1; tape->drive++) 588 if (!pt_reset(tape)) 589 return pt_identify(tape); 590 } else { 591 if (!pt_reset(tape)) 592 return pt_identify(tape); 593 } 594 return -1; 595} 596 597static int pt_detect(void) 598{ 599 struct pt_unit *tape; 600 int specified = 0, found = 0; 601 int unit; 602 603 printk("%s: %s version %s, major %d\n", name, name, PT_VERSION, major); 604 605 specified = 0; 606 for (unit = 0; unit < PT_UNITS; unit++) { 607 struct pt_unit *tape = &pt[unit]; 608 tape->pi = &tape->pia; 609 atomic_set(&tape->available, 1); 610 tape->flags = 0; 611 tape->last_sense = 0; 612 tape->present = 0; 613 tape->bufptr = NULL; 614 tape->drive = DU[D_SLV]; 615 snprintf(tape->name, PT_NAMELEN, "%s%d", name, unit); 616 if (!DU[D_PRT]) 617 continue; 618 specified++; 619 if (pi_init(tape->pi, 0, DU[D_PRT], DU[D_MOD], DU[D_UNI], 620 DU[D_PRO], DU[D_DLY], pt_scratch, PI_PT, 621 verbose, tape->name)) { 622 if (!pt_probe(tape)) { 623 tape->present = 1; 624 found++; 625 } else 626 pi_release(tape->pi); 627 } 628 } 629 if (specified == 0) { 630 tape = pt; 631 if (pi_init(tape->pi, 1, -1, -1, -1, -1, -1, pt_scratch, 632 PI_PT, verbose, tape->name)) { 633 if (!pt_probe(tape)) { 634 tape->present = 1; 635 found++; 636 } else 637 pi_release(tape->pi); 638 } 639 640 } 641 if (found) 642 return 0; 643 644 printk("%s: No ATAPI tape drive detected\n", name); 645 return -1; 646} 647 648static int pt_open(struct inode *inode, struct file *file) 649{ 650 int unit = iminor(inode) & 0x7F; 651 struct pt_unit *tape = pt + unit; 652 int err; 653 654 if (unit >= PT_UNITS || (!tape->present)) 655 return -ENODEV; 656 657 err = -EBUSY; 658 if (!atomic_dec_and_test(&tape->available)) 659 goto out; 660 661 pt_identify(tape); 662 663 err = -ENODEV; 664 if (!tape->flags & PT_MEDIA) 665 goto out; 666 667 err = -EROFS; 668 if ((!tape->flags & PT_WRITE_OK) && (file->f_mode & 2)) 669 goto out; 670 671 if (!(iminor(inode) & 128)) 672 tape->flags |= PT_REWIND; 673 674 err = -ENOMEM; 675 tape->bufptr = kmalloc(PT_BUFSIZE, GFP_KERNEL); 676 if (tape->bufptr == NULL) { 677 printk("%s: buffer allocation failed\n", tape->name); 678 goto out; 679 } 680 681 file->private_data = tape; 682 return 0; 683 684out: 685 atomic_inc(&tape->available); 686 return err; 687} 688 689static int pt_ioctl(struct inode *inode, struct file *file, 690 unsigned int cmd, unsigned long arg) 691{ 692 struct pt_unit *tape = file->private_data; 693 struct mtop __user *p = (void __user *)arg; 694 struct mtop mtop; 695 696 switch (cmd) { 697 case MTIOCTOP: 698 if (copy_from_user(&mtop, p, sizeof(struct mtop))) 699 return -EFAULT; 700 701 switch (mtop.mt_op) { 702 703 case MTREW: 704 pt_rewind(tape); 705 return 0; 706 707 case MTWEOF: 708 pt_write_fm(tape); 709 return 0; 710 711 default: 712 printk("%s: Unimplemented mt_op %d\n", tape->name, 713 mtop.mt_op); 714 return -EINVAL; 715 } 716 717 default: 718 printk("%s: Unimplemented ioctl 0x%x\n", tape->name, cmd); 719 return -EINVAL; 720 721 } 722} 723 724static int 725pt_release(struct inode *inode, struct file *file) 726{ 727 struct pt_unit *tape = file->private_data; 728 729 if (atomic_read(&tape->available) > 1) 730 return -EINVAL; 731 732 if (tape->flags & PT_WRITING) 733 pt_write_fm(tape); 734 735 if (tape->flags & PT_REWIND) 736 pt_rewind(tape); 737 738 kfree(tape->bufptr); 739 tape->bufptr = NULL; 740 741 atomic_inc(&tape->available); 742 743 return 0; 744 745} 746 747static ssize_t pt_read(struct file *filp, char __user *buf, size_t count, loff_t * ppos) 748{ 749 struct pt_unit *tape = filp->private_data; 750 struct pi_adapter *pi = tape->pi; 751 char rd_cmd[12] = { ATAPI_READ_6, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; 752 int k, n, r, p, s, t, b; 753 754 if (!(tape->flags & (PT_READING | PT_WRITING))) { 755 tape->flags |= PT_READING; 756 if (pt_atapi(tape, rd_cmd, 0, NULL, "start read-ahead")) 757 return -EIO; 758 } else if (tape->flags & PT_WRITING) 759 return -EIO; 760 761 if (tape->flags & PT_EOF) 762 return 0; 763 764 t = 0; 765 766 while (count > 0) { 767 768 if (!pt_poll_dsc(tape, HZ / 100, PT_TMO, "read")) 769 return -EIO; 770 771 n = count; 772 if (n > 32768) 773 n = 32768; /* max per command */ 774 b = (n - 1 + tape->bs) / tape->bs; 775 n = b * tape->bs; /* rounded up to even block */ 776 777 rd_cmd[4] = b; 778 779 r = pt_command(tape, rd_cmd, n, "read"); 780 781 mdelay(1); 782 783 if (r) { 784 pt_req_sense(tape, 0); 785 return -EIO; 786 } 787 788 while (1) { 789 790 r = pt_wait(tape, STAT_BUSY, 791 STAT_DRQ | STAT_ERR | STAT_READY, 792 DBMSG("read DRQ"), ""); 793 794 if (r & STAT_SENSE) { 795 pi_disconnect(pi); 796 pt_req_sense(tape, 0); 797 return -EIO; 798 } 799 800 if (r) 801 tape->flags |= PT_EOF; 802 803 s = read_reg(pi, 7); 804 805 if (!(s & STAT_DRQ)) 806 break; 807 808 n = (read_reg(pi, 4) + 256 * read_reg(pi, 5)); 809 p = (read_reg(pi, 2) & 3); 810 if (p != 2) { 811 pi_disconnect(pi); 812 printk("%s: Phase error on read: %d\n", tape->name, 813 p); 814 return -EIO; 815 } 816 817 while (n > 0) { 818 k = n; 819 if (k > PT_BUFSIZE) 820 k = PT_BUFSIZE; 821 pi_read_block(pi, tape->bufptr, k); 822 n -= k; 823 b = k; 824 if (b > count) 825 b = count; 826 if (copy_to_user(buf + t, tape->bufptr, b)) { 827 pi_disconnect(pi); 828 return -EFAULT; 829 } 830 t += b; 831 count -= b; 832 } 833 834 } 835 pi_disconnect(pi); 836 if (tape->flags & PT_EOF) 837 break; 838 } 839 840 return t; 841 842} 843 844static ssize_t pt_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos) 845{ 846 struct pt_unit *tape = filp->private_data; 847 struct pi_adapter *pi = tape->pi; 848 char wr_cmd[12] = { ATAPI_WRITE_6, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; 849 int k, n, r, p, s, t, b; 850 851 if (!(tape->flags & PT_WRITE_OK)) 852 return -EROFS; 853 854 if (!(tape->flags & (PT_READING | PT_WRITING))) { 855 tape->flags |= PT_WRITING; 856 if (pt_atapi 857 (tape, wr_cmd, 0, NULL, "start buffer-available mode")) 858 return -EIO; 859 } else if (tape->flags & PT_READING) 860 return -EIO; 861 862 if (tape->flags & PT_EOF) 863 return -ENOSPC; 864 865 t = 0; 866 867 while (count > 0) { 868 869 if (!pt_poll_dsc(tape, HZ / 100, PT_TMO, "write")) 870 return -EIO; 871 872 n = count; 873 if (n > 32768) 874 n = 32768; /* max per command */ 875 b = (n - 1 + tape->bs) / tape->bs; 876 n = b * tape->bs; /* rounded up to even block */ 877 878 wr_cmd[4] = b; 879 880 r = pt_command(tape, wr_cmd, n, "write"); 881 882 mdelay(1); 883 884 if (r) { /* error delivering command only */ 885 pt_req_sense(tape, 0); 886 return -EIO; 887 } 888 889 while (1) { 890 891 r = pt_wait(tape, STAT_BUSY, 892 STAT_DRQ | STAT_ERR | STAT_READY, 893 DBMSG("write DRQ"), NULL); 894 895 if (r & STAT_SENSE) { 896 pi_disconnect(pi); 897 pt_req_sense(tape, 0); 898 return -EIO; 899 } 900 901 if (r) 902 tape->flags |= PT_EOF; 903 904 s = read_reg(pi, 7); 905 906 if (!(s & STAT_DRQ)) 907 break; 908 909 n = (read_reg(pi, 4) + 256 * read_reg(pi, 5)); 910 p = (read_reg(pi, 2) & 3); 911 if (p != 0) { 912 pi_disconnect(pi); 913 printk("%s: Phase error on write: %d \n", 914 tape->name, p); 915 return -EIO; 916 } 917 918 while (n > 0) { 919 k = n; 920 if (k > PT_BUFSIZE) 921 k = PT_BUFSIZE; 922 b = k; 923 if (b > count) 924 b = count; 925 if (copy_from_user(tape->bufptr, buf + t, b)) { 926 pi_disconnect(pi); 927 return -EFAULT; 928 } 929 pi_write_block(pi, tape->bufptr, k); 930 t += b; 931 count -= b; 932 n -= k; 933 } 934 935 } 936 pi_disconnect(pi); 937 if (tape->flags & PT_EOF) 938 break; 939 } 940 941 return t; 942} 943 944static int __init pt_init(void) 945{ 946 int unit; 947 int err; 948 949 if (disable) { 950 err = -1; 951 goto out; 952 } 953 954 if (pt_detect()) { 955 err = -1; 956 goto out; 957 } 958 959 err = register_chrdev(major, name, &pt_fops); 960 if (err < 0) { 961 printk("pt_init: unable to get major number %d\n", major); 962 for (unit = 0; unit < PT_UNITS; unit++) 963 if (pt[unit].present) 964 pi_release(pt[unit].pi); 965 goto out; 966 } 967 major = err; 968 pt_class = class_create(THIS_MODULE, "pt"); 969 if (IS_ERR(pt_class)) { 970 err = PTR_ERR(pt_class); 971 goto out_chrdev; 972 } 973 974 devfs_mk_dir("pt"); 975 for (unit = 0; unit < PT_UNITS; unit++) 976 if (pt[unit].present) { 977 class_device_create(pt_class, NULL, MKDEV(major, unit), 978 NULL, "pt%d", unit); 979 err = devfs_mk_cdev(MKDEV(major, unit), 980 S_IFCHR | S_IRUSR | S_IWUSR, 981 "pt/%d", unit); 982 if (err) { 983 class_device_destroy(pt_class, MKDEV(major, unit)); 984 goto out_class; 985 } 986 class_device_create(pt_class, NULL, MKDEV(major, unit + 128), 987 NULL, "pt%dn", unit); 988 err = devfs_mk_cdev(MKDEV(major, unit + 128), 989 S_IFCHR | S_IRUSR | S_IWUSR, 990 "pt/%dn", unit); 991 if (err) { 992 class_device_destroy(pt_class, MKDEV(major, unit + 128)); 993 goto out_class; 994 } 995 } 996 goto out; 997 998out_class: 999 class_destroy(pt_class); 1000out_chrdev: 1001 unregister_chrdev(major, "pt"); 1002out: 1003 return err; 1004} 1005 1006static void __exit pt_exit(void) 1007{ 1008 int unit; 1009 for (unit = 0; unit < PT_UNITS; unit++) 1010 if (pt[unit].present) { 1011 class_device_destroy(pt_class, MKDEV(major, unit)); 1012 devfs_remove("pt/%d", unit); 1013 class_device_destroy(pt_class, MKDEV(major, unit + 128)); 1014 devfs_remove("pt/%dn", unit); 1015 } 1016 class_destroy(pt_class); 1017 devfs_remove("pt"); 1018 unregister_chrdev(major, name); 1019 for (unit = 0; unit < PT_UNITS; unit++) 1020 if (pt[unit].present) 1021 pi_release(pt[unit].pi); 1022} 1023 1024MODULE_LICENSE("GPL"); 1025module_init(pt_init) 1026module_exit(pt_exit)