vpoio.c (184130) | vpoio.c (185003) |
---|---|
1/*- 2 * Copyright (c) 1998, 1999 Nicolas Souchu 3 * Copyright (c) 2000 Alcove - Nicolas Souchu 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: --- 14 unchanged lines hidden (view full) --- 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 * 27 * 28 */ 29 30#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 1998, 1999 Nicolas Souchu 3 * Copyright (c) 2000 Alcove - Nicolas Souchu 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: --- 14 unchanged lines hidden (view full) --- 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 * 27 * 28 */ 29 30#include <sys/cdefs.h> |
31__FBSDID("$FreeBSD: head/sys/dev/ppbus/vpoio.c 184130 2008-10-21 18:30:10Z jhb $"); | 31__FBSDID("$FreeBSD: head/sys/dev/ppbus/vpoio.c 185003 2008-11-16 17:42:02Z jhb $"); |
32 33#ifdef _KERNEL 34#include <sys/param.h> 35#include <sys/systm.h> 36#include <sys/module.h> 37#include <sys/bus.h> 38#include <sys/malloc.h> 39 --- 173 unchanged lines hidden (view full) --- 213}; 214 215/* 216 * This is the sub-microsequence for MS_PUT in both NIBBLE and PS2 modes 217 */ 218static struct ppb_microseq spp_outbyte_submicroseq[] = { 219 220/* loop: */ | 32 33#ifdef _KERNEL 34#include <sys/param.h> 35#include <sys/systm.h> 36#include <sys/module.h> 37#include <sys/bus.h> 38#include <sys/malloc.h> 39 --- 173 unchanged lines hidden (view full) --- 213}; 214 215/* 216 * This is the sub-microsequence for MS_PUT in both NIBBLE and PS2 modes 217 */ 218static struct ppb_microseq spp_outbyte_submicroseq[] = { 219 220/* loop: */ |
221 MS_RASSERT_P(1, MS_REG_DTR), | 221 MS_RASSERT_P(1, MS_REG_DTR), |
222 MS_CASS(H_nAUTO | H_nSELIN | H_INIT | H_STROBE), 223 MS_CASS( H_AUTO | H_nSELIN | H_INIT | H_STROBE), 224 MS_DELAY(VP0_PULSE), 225 MS_DBRA(-5 /* loop */), 226 227 /* return from the put call */ 228 MS_RET(0) 229}; 230 231/* EPP 1.7 microsequences, ptr and len set at runtime */ 232static struct ppb_microseq epp17_outstr_body[] = { 233 MS_CASS(H_AUTO | H_SELIN | H_INIT | H_STROBE), 234 235/* loop: */ | 222 MS_CASS(H_nAUTO | H_nSELIN | H_INIT | H_STROBE), 223 MS_CASS( H_AUTO | H_nSELIN | H_INIT | H_STROBE), 224 MS_DELAY(VP0_PULSE), 225 MS_DBRA(-5 /* loop */), 226 227 /* return from the put call */ 228 MS_RET(0) 229}; 230 231/* EPP 1.7 microsequences, ptr and len set at runtime */ 232static struct ppb_microseq epp17_outstr_body[] = { 233 MS_CASS(H_AUTO | H_SELIN | H_INIT | H_STROBE), 234 235/* loop: */ |
236 MS_RASSERT_P(1, MS_REG_EPP_D), | 236 MS_RASSERT_P(1, MS_REG_EPP_D), |
237 MS_BRSET(TIMEOUT, 3 /* error */), /* EPP timeout? */ 238 MS_DBRA(-3 /* loop */), 239 240 MS_CASS(H_AUTO | H_nSELIN | H_INIT | H_STROBE), 241 MS_RET(0), 242/* error: */ 243 MS_CASS(H_AUTO | H_nSELIN | H_INIT | H_STROBE), 244 MS_RET(1) 245}; 246 247static struct ppb_microseq epp17_instr_body[] = { 248 MS_CASS(PCD | H_AUTO | H_SELIN | H_INIT | H_STROBE), 249 250/* loop: */ | 237 MS_BRSET(TIMEOUT, 3 /* error */), /* EPP timeout? */ 238 MS_DBRA(-3 /* loop */), 239 240 MS_CASS(H_AUTO | H_nSELIN | H_INIT | H_STROBE), 241 MS_RET(0), 242/* error: */ 243 MS_CASS(H_AUTO | H_nSELIN | H_INIT | H_STROBE), 244 MS_RET(1) 245}; 246 247static struct ppb_microseq epp17_instr_body[] = { 248 MS_CASS(PCD | H_AUTO | H_SELIN | H_INIT | H_STROBE), 249 250/* loop: */ |
251 MS_RFETCH_P(1, MS_REG_EPP_D, MS_FETCH_ALL), | 251 MS_RFETCH_P(1, MS_REG_EPP_D, MS_FETCH_ALL), |
252 MS_BRSET(TIMEOUT, 3 /* error */), /* EPP timeout? */ 253 MS_DBRA(-3 /* loop */), 254 255 MS_CASS(PCD | H_AUTO | H_nSELIN | H_INIT | H_STROBE), 256 MS_RET(0), 257/* error: */ 258 MS_CASS(PCD | H_AUTO | H_nSELIN | H_INIT | H_STROBE), 259 MS_RET(1) --- 32 unchanged lines hidden (view full) --- 292 int error; 293 int ret; 294 295 if ((error = ppb_request_bus(ppbus, vpo->vpo_dev, how))) { 296 297#ifdef VP0_DEBUG 298 printf("%s: can't request bus!\n", __func__); 299#endif | 252 MS_BRSET(TIMEOUT, 3 /* error */), /* EPP timeout? */ 253 MS_DBRA(-3 /* loop */), 254 255 MS_CASS(PCD | H_AUTO | H_nSELIN | H_INIT | H_STROBE), 256 MS_RET(0), 257/* error: */ 258 MS_CASS(PCD | H_AUTO | H_nSELIN | H_INIT | H_STROBE), 259 MS_RET(1) --- 32 unchanged lines hidden (view full) --- 292 int error; 293 int ret; 294 295 if ((error = ppb_request_bus(ppbus, vpo->vpo_dev, how))) { 296 297#ifdef VP0_DEBUG 298 printf("%s: can't request bus!\n", __func__); 299#endif |
300 return error; | 300 return (error); |
301 } 302 303 if (PPB_IN_EPP_MODE(ppbus)) 304 ppb_MS_microseq(ppbus, vpo->vpo_dev, connect_epp_microseq, &ret); 305 else 306 ppb_MS_microseq(ppbus, vpo->vpo_dev, connect_spp_microseq, &ret); 307 308 return (0); 309} 310 311/* 312 * vpoio_reset() 313 * 314 * SCSI reset signal, the drive must be in disk mode 315 */ 316static void | 301 } 302 303 if (PPB_IN_EPP_MODE(ppbus)) 304 ppb_MS_microseq(ppbus, vpo->vpo_dev, connect_epp_microseq, &ret); 305 else 306 ppb_MS_microseq(ppbus, vpo->vpo_dev, connect_spp_microseq, &ret); 307 308 return (0); 309} 310 311/* 312 * vpoio_reset() 313 * 314 * SCSI reset signal, the drive must be in disk mode 315 */ 316static void |
317vpoio_reset (struct vpoio_data *vpo) | 317vpoio_reset(struct vpoio_data *vpo) |
318{ 319 device_t ppbus = device_get_parent(vpo->vpo_dev); 320 int ret; 321 322 struct ppb_microseq reset_microseq[] = { 323 324 #define INITIATOR MS_PARAM(0, 1, MS_TYP_INT) 325 --- 32 unchanged lines hidden (view full) --- 358static int 359vpoio_detect(struct vpoio_data *vpo) 360{ 361 device_t ppbus = device_get_parent(vpo->vpo_dev); 362 int error, ret; 363 364 /* allocate the bus, then apply microsequences */ 365 if ((error = ppb_request_bus(ppbus, vpo->vpo_dev, PPB_DONTWAIT))) | 318{ 319 device_t ppbus = device_get_parent(vpo->vpo_dev); 320 int ret; 321 322 struct ppb_microseq reset_microseq[] = { 323 324 #define INITIATOR MS_PARAM(0, 1, MS_TYP_INT) 325 --- 32 unchanged lines hidden (view full) --- 358static int 359vpoio_detect(struct vpoio_data *vpo) 360{ 361 device_t ppbus = device_get_parent(vpo->vpo_dev); 362 int error, ret; 363 364 /* allocate the bus, then apply microsequences */ 365 if ((error = ppb_request_bus(ppbus, vpo->vpo_dev, PPB_DONTWAIT))) |
366 return (error); | 366 return (error); |
367 368 /* Force disconnection */ 369 ppb_MS_microseq(ppbus, vpo->vpo_dev, disconnect_microseq, &ret); 370 371 /* Try to enter EPP mode, then connect to the drive in EPP mode */ 372 if (ppb_set_mode(ppbus, PPB_EPP) != -1) { 373 /* call manually the microseq instead of using the appropriate function 374 * since we already requested the ppbus */ --- 36 unchanged lines hidden (view full) --- 411 vpo->vpo_mode_found = VP0_MODE_EPP; 412 } 413 414 /* send SCSI reset signal */ 415 vpoio_reset(vpo); 416 417 ppb_MS_microseq(ppbus, vpo->vpo_dev, disconnect_microseq, &ret); 418 | 367 368 /* Force disconnection */ 369 ppb_MS_microseq(ppbus, vpo->vpo_dev, disconnect_microseq, &ret); 370 371 /* Try to enter EPP mode, then connect to the drive in EPP mode */ 372 if (ppb_set_mode(ppbus, PPB_EPP) != -1) { 373 /* call manually the microseq instead of using the appropriate function 374 * since we already requested the ppbus */ --- 36 unchanged lines hidden (view full) --- 411 vpo->vpo_mode_found = VP0_MODE_EPP; 412 } 413 414 /* send SCSI reset signal */ 415 vpoio_reset(vpo); 416 417 ppb_MS_microseq(ppbus, vpo->vpo_dev, disconnect_microseq, &ret); 418 |
419 /* ensure we are disconnected or daisy chained peripheral | 419 /* ensure we are disconnected or daisy chained peripheral |
420 * may cause serious problem to the disk */ 421 if (vpoio_in_disk_mode(vpo)) { 422 if (bootverbose) 423 device_printf(vpo->vpo_dev, 424 "can't disconnect from the drive\n"); 425 goto error; 426 } 427 --- 66 unchanged lines hidden (view full) --- 494/* error: */ MS_RET(1), 495/* ready: */ MS_RET(0) 496 }; 497 498 /* initialize the select microsequence */ 499 ppb_MS_init_msq(select_microseq, 2, 500 SELECT_TARGET, 1 << target, 501 SELECT_INITIATOR, 1 << initiator); | 420 * may cause serious problem to the disk */ 421 if (vpoio_in_disk_mode(vpo)) { 422 if (bootverbose) 423 device_printf(vpo->vpo_dev, 424 "can't disconnect from the drive\n"); 425 goto error; 426 } 427 --- 66 unchanged lines hidden (view full) --- 494/* error: */ MS_RET(1), 495/* ready: */ MS_RET(0) 496 }; 497 498 /* initialize the select microsequence */ 499 ppb_MS_init_msq(select_microseq, 2, 500 SELECT_TARGET, 1 << target, 501 SELECT_INITIATOR, 1 << initiator); |
502 | 502 |
503 ppb_MS_microseq(ppbus, vpo->vpo_dev, select_microseq, &ret); 504 505 if (ret) 506 return (VP0_ESELECT_TIMEOUT); 507 508 return (0); 509} 510 --- 29 unchanged lines hidden (view full) --- 540 541 ppb_MS_init_msq(wait_microseq, 2, 542 WAIT_RET, (void *)&ret, 543 WAIT_TMO, tmo); 544 545 ppb_MS_microseq(ppbus, vpo->vpo_dev, wait_microseq, &err); 546 547 if (err) | 503 ppb_MS_microseq(ppbus, vpo->vpo_dev, select_microseq, &ret); 504 505 if (ret) 506 return (VP0_ESELECT_TIMEOUT); 507 508 return (0); 509} 510 --- 29 unchanged lines hidden (view full) --- 540 541 ppb_MS_init_msq(wait_microseq, 2, 542 WAIT_RET, (void *)&ret, 543 WAIT_TMO, tmo); 544 545 ppb_MS_microseq(ppbus, vpo->vpo_dev, wait_microseq, &err); 546 547 if (err) |
548 return (0); /* command timed out */ | 548 return (0); /* command timed out */ |
549 550 return(ret); 551} 552 553/* 554 * vpoio_probe() 555 * 556 * Low level probe of vpo device --- 24 unchanged lines hidden (view full) --- 581 * vpoio_attach() 582 * 583 * Low level attachment of vpo device 584 * 585 */ 586int 587vpoio_attach(struct vpoio_data *vpo) 588{ | 549 550 return(ret); 551} 552 553/* 554 * vpoio_probe() 555 * 556 * Low level probe of vpo device --- 24 unchanged lines hidden (view full) --- 581 * vpoio_attach() 582 * 583 * Low level attachment of vpo device 584 * 585 */ 586int 587vpoio_attach(struct vpoio_data *vpo) 588{ |
589 DECLARE_NIBBLE_INBYTE_SUBMICROSEQ; | 589 DECLARE_NIBBLE_INBYTE_SUBMICROSEQ; |
590 device_t ppbus = device_get_parent(vpo->vpo_dev); 591 int error = 0; 592 593 vpo->vpo_nibble_inbyte_msq = (struct ppb_microseq *)malloc( 594 sizeof(nibble_inbyte_submicroseq), M_DEVBUF, M_NOWAIT); 595 596 if (!vpo->vpo_nibble_inbyte_msq) 597 return (ENXIO); 598 599 bcopy((void *)nibble_inbyte_submicroseq, 600 (void *)vpo->vpo_nibble_inbyte_msq, 601 sizeof(nibble_inbyte_submicroseq)); 602 603 ppb_MS_init_msq(vpo->vpo_nibble_inbyte_msq, 4, 604 INB_NIBBLE_H, (void *)&(vpo)->vpo_nibble.h, 605 INB_NIBBLE_L, (void *)&(vpo)->vpo_nibble.l, 606 INB_NIBBLE_F, nibble_inbyte_hook, | 590 device_t ppbus = device_get_parent(vpo->vpo_dev); 591 int error = 0; 592 593 vpo->vpo_nibble_inbyte_msq = (struct ppb_microseq *)malloc( 594 sizeof(nibble_inbyte_submicroseq), M_DEVBUF, M_NOWAIT); 595 596 if (!vpo->vpo_nibble_inbyte_msq) 597 return (ENXIO); 598 599 bcopy((void *)nibble_inbyte_submicroseq, 600 (void *)vpo->vpo_nibble_inbyte_msq, 601 sizeof(nibble_inbyte_submicroseq)); 602 603 ppb_MS_init_msq(vpo->vpo_nibble_inbyte_msq, 4, 604 INB_NIBBLE_H, (void *)&(vpo)->vpo_nibble.h, 605 INB_NIBBLE_L, (void *)&(vpo)->vpo_nibble.l, 606 INB_NIBBLE_F, nibble_inbyte_hook, |
607 INB_NIBBLE_P, (void *)&(vpo)->vpo_nibble); | 607 INB_NIBBLE_P, (void *)&(vpo)->vpo_nibble); |
608 609 /* 610 * Initialize mode dependent in/out microsequences 611 */ 612 if ((error = ppb_request_bus(ppbus, vpo->vpo_dev, PPB_WAIT))) 613 goto error; 614 615 /* ppbus sets automatically the last mode entered during detection */ --- 51 unchanged lines hidden (view full) --- 667} 668 669/* 670 * vpoio_do_scsi() 671 * 672 * Send an SCSI command 673 * 674 */ | 608 609 /* 610 * Initialize mode dependent in/out microsequences 611 */ 612 if ((error = ppb_request_bus(ppbus, vpo->vpo_dev, PPB_WAIT))) 613 goto error; 614 615 /* ppbus sets automatically the last mode entered during detection */ --- 51 unchanged lines hidden (view full) --- 667} 668 669/* 670 * vpoio_do_scsi() 671 * 672 * Send an SCSI command 673 * 674 */ |
675int | 675int |
676vpoio_do_scsi(struct vpoio_data *vpo, int host, int target, char *command, 677 int clen, char *buffer, int blen, int *result, int *count, 678 int *ret) 679{ 680 device_t ppbus = device_get_parent(vpo->vpo_dev); 681 register char r; 682 char l, h = 0; 683 int len, error = 0; --- 6 unchanged lines hidden (view full) --- 690 * Should we allow this call to be interruptible? 691 * The only way to report the interruption is to return 692 * EIO do upper SCSI code :^( 693 */ 694 if ((error = vpoio_connect(vpo, PPB_WAIT|PPB_INTR))) 695 return (error); 696 697 if (!vpoio_in_disk_mode(vpo)) { | 676vpoio_do_scsi(struct vpoio_data *vpo, int host, int target, char *command, 677 int clen, char *buffer, int blen, int *result, int *count, 678 int *ret) 679{ 680 device_t ppbus = device_get_parent(vpo->vpo_dev); 681 register char r; 682 char l, h = 0; 683 int len, error = 0; --- 6 unchanged lines hidden (view full) --- 690 * Should we allow this call to be interruptible? 691 * The only way to report the interruption is to return 692 * EIO do upper SCSI code :^( 693 */ 694 if ((error = vpoio_connect(vpo, PPB_WAIT|PPB_INTR))) 695 return (error); 696 697 if (!vpoio_in_disk_mode(vpo)) { |
698 *ret = VP0_ECONNECT; goto error; | 698 *ret = VP0_ECONNECT; 699 goto error; |
699 } 700 701 if ((*ret = vpoio_select(vpo,host,target))) 702 goto error; 703 704 /* 705 * Send the command ... 706 * --- 7 unchanged lines hidden (view full) --- 714 goto error; 715 } 716 if (vpoio_outstr(vpo, &command[k], 1)) { 717 *ret = VP0_EPPDATA_TIMEOUT; 718 goto error; 719 } 720 } 721 | 700 } 701 702 if ((*ret = vpoio_select(vpo,host,target))) 703 goto error; 704 705 /* 706 * Send the command ... 707 * --- 7 unchanged lines hidden (view full) --- 715 goto error; 716 } 717 if (vpoio_outstr(vpo, &command[k], 1)) { 718 *ret = VP0_EPPDATA_TIMEOUT; 719 goto error; 720 } 721 } 722 |
722 /* 723 * Completion ... | 723 /* 724 * Completion ... |
724 */ 725 726 *count = 0; 727 for (;;) { 728 729 if (!(r = vpoio_wait(vpo, VP0_LOW_SPINTMO))) { | 725 */ 726 727 *count = 0; 728 for (;;) { 729 730 if (!(r = vpoio_wait(vpo, VP0_LOW_SPINTMO))) { |
730 *ret = VP0_ESTATUS_TIMEOUT; goto error; | 731 *ret = VP0_ESTATUS_TIMEOUT; 732 goto error; |
731 } 732 733 /* stop when the ZIP wants to send status */ 734 if (r == (char)0xf0) 735 break; 736 737 if (*count >= blen) { 738 *ret = VP0_EDATA_OVERFLOW; --- 19 unchanged lines hidden (view full) --- 758 *ret = error; 759 goto error; 760 } 761 762 *count += len; 763 } 764 765 if (vpoio_instr(vpo, &l, 1)) { | 733 } 734 735 /* stop when the ZIP wants to send status */ 736 if (r == (char)0xf0) 737 break; 738 739 if (*count >= blen) { 740 *ret = VP0_EDATA_OVERFLOW; --- 19 unchanged lines hidden (view full) --- 760 *ret = error; 761 goto error; 762 } 763 764 *count += len; 765 } 766 767 if (vpoio_instr(vpo, &l, 1)) { |
766 *ret = VP0_EOTHER; goto error; | 768 *ret = VP0_EOTHER; 769 goto error; |
767 } 768 769 /* check if the ZIP wants to send more status */ 770 if (vpoio_wait(vpo, VP0_FAST_SPINTMO) == (char)0xf0) 771 if (vpoio_instr(vpo, &h, 1)) { | 770 } 771 772 /* check if the ZIP wants to send more status */ 773 if (vpoio_wait(vpo, VP0_FAST_SPINTMO) == (char)0xf0) 774 if (vpoio_instr(vpo, &h, 1)) { |
772 *ret = VP0_EOTHER+2; goto error; | 775 *ret = VP0_EOTHER + 2; 776 goto error; |
773 } 774 775 *result = ((int) h << 8) | ((int) l & 0xff); 776 777error: 778 /* return to printer state, release the ppbus */ 779 vpoio_disconnect(vpo); 780 return (0); 781} | 777 } 778 779 *result = ((int) h << 8) | ((int) l & 0xff); 780 781error: 782 /* return to printer state, release the ppbus */ 783 vpoio_disconnect(vpo); 784 return (0); 785} |