Lines Matching full:pf

2         pf.c    (c) 1997-8  Grant R. Guenther <grant@torque.net>
12 The behaviour of the pf driver can be altered by setting
70 (default "pf").
91 pf.drive0
92 pf.drive1
93 pf.drive2
94 pf.drive3
95 pf.cluster
96 pf.nice
98 In addition, you can use the parameter pf.disable to disable
118 #define PF_NAME "pf"
248 static int pf_identify(struct pf_unit *pf);
249 static void pf_lock(struct pf_unit *pf, int func);
250 static void pf_eject(struct pf_unit *pf);
290 struct pf_unit *pf; in pf_init_units() local
294 for (unit = 0, pf = units; unit < PF_UNITS; unit++, pf++) { in pf_init_units()
297 if (blk_mq_alloc_sq_tag_set(&pf->tag_set, &pf_mq_ops, 1, in pf_init_units()
301 disk = blk_mq_alloc_disk(&pf->tag_set, pf); in pf_init_units()
303 blk_mq_free_tag_set(&pf->tag_set); in pf_init_units()
307 INIT_LIST_HEAD(&pf->rq_list); in pf_init_units()
310 pf->disk = disk; in pf_init_units()
311 pf->pi = &pf->pia; in pf_init_units()
312 pf->media_status = PF_NM; in pf_init_units()
313 pf->drive = (*drives[unit])[D_SLV]; in pf_init_units()
314 pf->lun = (*drives[unit])[D_LUN]; in pf_init_units()
315 snprintf(pf->name, PF_NAMELEN, "%s%d", name, unit); in pf_init_units()
319 strcpy(disk->disk_name, pf->name); in pf_init_units()
329 struct pf_unit *pf = bdev->bd_disk->private_data; in pf_open() local
333 pf_identify(pf); in pf_open()
336 if (pf->media_status == PF_NM) in pf_open()
340 if ((pf->media_status == PF_RO) && (mode & FMODE_WRITE)) in pf_open()
344 pf->access++; in pf_open()
345 if (pf->removable) in pf_open()
346 pf_lock(pf, 1); in pf_open()
354 struct pf_unit *pf = bdev->bd_disk->private_data; in pf_getgeo() local
355 sector_t capacity = get_capacity(pf->disk); in pf_getgeo()
372 struct pf_unit *pf = bdev->bd_disk->private_data; in pf_ioctl() local
377 if (pf->access != 1) in pf_ioctl()
380 pf_eject(pf); in pf_ioctl()
388 struct pf_unit *pf = disk->private_data; in pf_release() local
391 if (pf->access <= 0) { in pf_release()
397 pf->access--; in pf_release()
399 if (!pf->access && pf->removable) in pf_release()
400 pf_lock(pf, 0); in pf_release()
410 static inline int status_reg(struct pf_unit *pf) in status_reg() argument
412 return pi_read_regr(pf->pi, 1, 6); in status_reg()
415 static inline int read_reg(struct pf_unit *pf, int reg) in read_reg() argument
417 return pi_read_regr(pf->pi, 0, reg); in read_reg()
420 static inline void write_reg(struct pf_unit *pf, int reg, int val) in write_reg() argument
422 pi_write_regr(pf->pi, 0, reg, val); in write_reg()
425 static int pf_wait(struct pf_unit *pf, int go, int stop, char *fun, char *msg) in pf_wait() argument
430 while ((((r = status_reg(pf)) & go) || (stop && (!(r & stop)))) in pf_wait()
435 s = read_reg(pf, 7); in pf_wait()
436 e = read_reg(pf, 1); in pf_wait()
437 p = read_reg(pf, 2); in pf_wait()
443 pf->name, fun, msg, r, s, e, j, p); in pf_wait()
449 static int pf_command(struct pf_unit *pf, char *cmd, int dlen, char *fun) in pf_command() argument
451 pi_connect(pf->pi); in pf_command()
453 write_reg(pf, 6, 0xa0+0x10*pf->drive); in pf_command()
455 if (pf_wait(pf, STAT_BUSY | STAT_DRQ, 0, fun, "before command")) { in pf_command()
456 pi_disconnect(pf->pi); in pf_command()
460 write_reg(pf, 4, dlen % 256); in pf_command()
461 write_reg(pf, 5, dlen / 256); in pf_command()
462 write_reg(pf, 7, 0xa0); /* ATAPI packet command */ in pf_command()
464 if (pf_wait(pf, STAT_BUSY, STAT_DRQ, fun, "command DRQ")) { in pf_command()
465 pi_disconnect(pf->pi); in pf_command()
469 if (read_reg(pf, 2) != 1) { in pf_command()
470 printk("%s: %s: command phase error\n", pf->name, fun); in pf_command()
471 pi_disconnect(pf->pi); in pf_command()
475 pi_write_block(pf->pi, cmd, 12); in pf_command()
480 static int pf_completion(struct pf_unit *pf, char *buf, char *fun) in pf_completion() argument
484 r = pf_wait(pf, STAT_BUSY, STAT_DRQ | STAT_READY | STAT_ERR, in pf_completion()
487 if ((read_reg(pf, 2) & 2) && (read_reg(pf, 7) & STAT_DRQ)) { in pf_completion()
488 n = (((read_reg(pf, 4) + 256 * read_reg(pf, 5)) + in pf_completion()
490 pi_read_block(pf->pi, buf, n); in pf_completion()
493 s = pf_wait(pf, STAT_BUSY, STAT_READY | STAT_ERR, fun, "data done"); in pf_completion()
495 pi_disconnect(pf->pi); in pf_completion()
500 static void pf_req_sense(struct pf_unit *pf, int quiet) in pf_req_sense() argument
503 { ATAPI_REQ_SENSE, pf->lun << 5, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0 }; in pf_req_sense()
507 r = pf_command(pf, rs_cmd, 16, "Request sense"); in pf_req_sense()
510 pf_completion(pf, buf, "Request sense"); in pf_req_sense()
514 pf->name, buf[2] & 0xf, buf[12], buf[13]); in pf_req_sense()
517 static int pf_atapi(struct pf_unit *pf, char *cmd, int dlen, char *buf, char *fun) in pf_atapi() argument
521 r = pf_command(pf, cmd, dlen, fun); in pf_atapi()
524 r = pf_completion(pf, buf, fun); in pf_atapi()
526 pf_req_sense(pf, !fun); in pf_atapi()
531 static void pf_lock(struct pf_unit *pf, int func) in pf_lock() argument
533 char lo_cmd[12] = { ATAPI_LOCK, pf->lun << 5, 0, 0, func, 0, 0, 0, 0, 0, 0, 0 }; in pf_lock()
535 pf_atapi(pf, lo_cmd, 0, pf_scratch, func ? "lock" : "unlock"); in pf_lock()
538 static void pf_eject(struct pf_unit *pf) in pf_eject() argument
540 char ej_cmd[12] = { ATAPI_DOOR, pf->lun << 5, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0 }; in pf_eject()
542 pf_lock(pf, 0); in pf_eject()
543 pf_atapi(pf, ej_cmd, 0, pf_scratch, "eject"); in pf_eject()
558 static int pf_reset(struct pf_unit *pf) in pf_reset() argument
563 pi_connect(pf->pi); in pf_reset()
564 write_reg(pf, 6, 0xa0+0x10*pf->drive); in pf_reset()
565 write_reg(pf, 7, 8); in pf_reset()
570 while ((k++ < PF_RESET_TMO) && (status_reg(pf) & STAT_BUSY)) in pf_reset()
575 flg &= (read_reg(pf, i + 1) == expect[i]); in pf_reset()
578 printk("%s: Reset (%d) signature = ", pf->name, k); in pf_reset()
580 printk("%3x", read_reg(pf, i + 1)); in pf_reset()
586 pi_disconnect(pf->pi); in pf_reset()
590 static void pf_mode_sense(struct pf_unit *pf) in pf_mode_sense() argument
593 { ATAPI_MODE_SENSE, pf->lun << 5, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0 }; in pf_mode_sense()
596 pf_atapi(pf, ms_cmd, 8, buf, "mode sense"); in pf_mode_sense()
597 pf->media_status = PF_RW; in pf_mode_sense()
599 pf->media_status = PF_RO; in pf_mode_sense()
626 static void pf_get_capacity(struct pf_unit *pf) in pf_get_capacity() argument
628 char rc_cmd[12] = { ATAPI_CAPACITY, pf->lun << 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; in pf_get_capacity()
632 if (pf_atapi(pf, rc_cmd, 8, buf, "get capacity")) { in pf_get_capacity()
633 pf->media_status = PF_NM; in pf_get_capacity()
636 set_capacity(pf->disk, xl(buf, 0) + 1); in pf_get_capacity()
639 set_capacity(pf->disk, 0); in pf_get_capacity()
643 pf->name, pf->drive, pf->lun, bs); in pf_get_capacity()
647 static int pf_identify(struct pf_unit *pf) in pf_identify() argument
653 { ATAPI_IDENTIFY, pf->lun << 5, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0 }; in pf_identify()
656 s = pf_atapi(pf, id_cmd, 36, buf, "identify"); in pf_identify()
664 pf->name, pf->drive, pf->lun, dt); in pf_identify()
671 pf->removable = (buf[1] & 0x80); in pf_identify()
673 pf_mode_sense(pf); in pf_identify()
674 pf_mode_sense(pf); in pf_identify()
675 pf_mode_sense(pf); in pf_identify()
677 pf_get_capacity(pf); in pf_identify()
680 pf->name, mf, id, ms[pf->drive], pf->lun, dt); in pf_identify()
681 if (pf->removable) in pf_identify()
683 if (pf->media_status == PF_NM) in pf_identify()
686 if (pf->media_status == PF_RO) in pf_identify()
689 (unsigned long long)get_capacity(pf->disk)); in pf_identify()
697 static int pf_probe(struct pf_unit *pf) in pf_probe() argument
699 if (pf->drive == -1) { in pf_probe()
700 for (pf->drive = 0; pf->drive <= 1; pf->drive++) in pf_probe()
701 if (!pf_reset(pf)) { in pf_probe()
702 if (pf->lun != -1) in pf_probe()
703 return pf_identify(pf); in pf_probe()
705 for (pf->lun = 0; pf->lun < 8; pf->lun++) in pf_probe()
706 if (!pf_identify(pf)) in pf_probe()
710 if (pf_reset(pf)) in pf_probe()
712 if (pf->lun != -1) in pf_probe()
713 return pf_identify(pf); in pf_probe()
714 for (pf->lun = 0; pf->lun < 8; pf->lun++) in pf_probe()
715 if (!pf_identify(pf)) in pf_probe()
723 struct pf_unit *pf = units; in pf_detect() local
736 if (pi_init(pf->pi, 1, -1, -1, -1, -1, -1, pf_scratch, PI_PF, in pf_detect()
737 verbose, pf->name)) { in pf_detect()
738 if (!pf_probe(pf) && pf->disk) { in pf_detect()
739 pf->present = 1; in pf_detect()
742 pi_release(pf->pi); in pf_detect()
746 for (unit = 0; unit < PF_UNITS; unit++, pf++) { in pf_detect()
750 if (pi_init(pf->pi, 0, conf[D_PRT], conf[D_MOD], in pf_detect()
752 pf_scratch, PI_PF, verbose, pf->name)) { in pf_detect()
753 if (pf->disk && !pf_probe(pf)) { in pf_detect()
754 pf->present = 1; in pf_detect()
757 pi_release(pf->pi); in pf_detect()
764 for (pf = units, unit = 0; unit < PF_UNITS; pf++, unit++) { in pf_detect()
765 if (!pf->disk) in pf_detect()
767 blk_cleanup_disk(pf->disk); in pf_detect()
768 blk_mq_free_tag_set(&pf->tag_set); in pf_detect()
776 static int pf_start(struct pf_unit *pf, int cmd, int b, int c) in pf_start() argument
779 char io_cmd[12] = { cmd, pf->lun << 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; in pf_start()
789 i = pf_command(pf, io_cmd, c * 512, "start i/o"); in pf_start()
805 struct pf_unit *pf; in set_next_request() local
809 pf = &units[pf_queue]; in set_next_request()
812 if (pf->present && !list_empty(&pf->rq_list)) { in set_next_request()
813 pf_req = list_first_entry(&pf->rq_list, struct request, in set_next_request()
871 struct pf_unit *pf = hctx->queue->queuedata; in pf_queue_rq() local
874 list_add_tail(&bd->rq->queuelist, &pf->rq_list); in pf_queue_rq()
1019 struct pf_unit *pf; in pf_init() local
1032 for (pf = units, unit = 0; unit < PF_UNITS; pf++, unit++) { in pf_init()
1033 if (!pf->disk) in pf_init()
1035 blk_cleanup_queue(pf->disk->queue); in pf_init()
1036 blk_mq_free_tag_set(&pf->tag_set); in pf_init()
1037 put_disk(pf->disk); in pf_init()
1042 for (pf = units, unit = 0; unit < PF_UNITS; pf++, unit++) { in pf_init()
1043 struct gendisk *disk = pf->disk; in pf_init()
1045 if (!pf->present) in pf_init()
1047 disk->private_data = pf; in pf_init()
1055 struct pf_unit *pf; in pf_exit() local
1058 for (pf = units, unit = 0; unit < PF_UNITS; pf++, unit++) { in pf_exit()
1059 if (!pf->disk) in pf_exit()
1062 if (pf->present) in pf_exit()
1063 del_gendisk(pf->disk); in pf_exit()
1065 blk_cleanup_queue(pf->disk->queue); in pf_exit()
1066 blk_mq_free_tag_set(&pf->tag_set); in pf_exit()
1067 put_disk(pf->disk); in pf_exit()
1069 if (pf->present) in pf_exit()
1070 pi_release(pf->pi); in pf_exit()