1 // SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) 2 /* 3 * sisusb - usb kernel driver for SiS315(E) based USB2VGA dongles 4 * 5 * Main part 6 * 7 * Copyright (C) 2005 by Thomas Winischhofer, Vienna, Austria 8 * 9 * If distributed as part of the Linux kernel, this code is licensed under the 10 * terms of the GPL v2. 11 * 12 * Otherwise, the following license terms apply: 13 * 14 * * Redistribution and use in source and binary forms, with or without 15 * * modification, are permitted provided that the following conditions 16 * * are met: 17 * * 1) Redistributions of source code must retain the above copyright 18 * * notice, this list of conditions and the following disclaimer. 19 * * 2) Redistributions in binary form must reproduce the above copyright 20 * * notice, this list of conditions and the following disclaimer in the 21 * * documentation and/or other materials provided with the distribution. 22 * * 3) The name of the author may not be used to endorse or promote products 23 * * derived from this software without specific psisusbr written permission. 24 * * 25 * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED OR 26 * * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 27 * * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 28 * * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 29 * * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 30 * * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 31 * * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 32 * * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 33 * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 34 * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 * 36 * Author: Thomas Winischhofer <thomas@winischhofer.net> 37 * 38 */ 39 40 #include <linux/mutex.h> 41 #include <linux/module.h> 42 #include <linux/kernel.h> 43 #include <linux/signal.h> 44 #include <linux/errno.h> 45 #include <linux/poll.h> 46 #include <linux/init.h> 47 #include <linux/slab.h> 48 #include <linux/spinlock.h> 49 #include <linux/kref.h> 50 #include <linux/usb.h> 51 #include <linux/vmalloc.h> 52 53 #include "sisusb.h" 54 55 #define SISUSB_DONTSYNC 56 57 /* Forward declarations / clean-up routines */ 58 59 static struct usb_driver sisusb_driver; 60 61 static void sisusb_free_buffers(struct sisusb_usb_data *sisusb) 62 { 63 int i; 64 65 for (i = 0; i < NUMOBUFS; i++) { 66 kfree(sisusb->obuf[i]); 67 sisusb->obuf[i] = NULL; 68 } 69 kfree(sisusb->ibuf); 70 sisusb->ibuf = NULL; 71 } 72 73 static void sisusb_free_urbs(struct sisusb_usb_data *sisusb) 74 { 75 int i; 76 77 for (i = 0; i < NUMOBUFS; i++) { 78 usb_free_urb(sisusb->sisurbout[i]); 79 sisusb->sisurbout[i] = NULL; 80 } 81 usb_free_urb(sisusb->sisurbin); 82 sisusb->sisurbin = NULL; 83 } 84 85 /* Level 0: USB transport layer */ 86 87 /* 1. out-bulks */ 88 89 /* out-urb management */ 90 91 /* Return 1 if all free, 0 otherwise */ 92 static int sisusb_all_free(struct sisusb_usb_data *sisusb) 93 { 94 int i; 95 96 for (i = 0; i < sisusb->numobufs; i++) { 97 98 if (sisusb->urbstatus[i] & SU_URB_BUSY) 99 return 0; 100 101 } 102 103 return 1; 104 } 105 106 /* Kill all busy URBs */ 107 static void sisusb_kill_all_busy(struct sisusb_usb_data *sisusb) 108 { 109 int i; 110 111 if (sisusb_all_free(sisusb)) 112 return; 113 114 for (i = 0; i < sisusb->numobufs; i++) { 115 116 if (sisusb->urbstatus[i] & SU_URB_BUSY) 117 usb_kill_urb(sisusb->sisurbout[i]); 118 119 } 120 } 121 122 /* Return 1 if ok, 0 if error (not all complete within timeout) */ 123 static int sisusb_wait_all_out_complete(struct sisusb_usb_data *sisusb) 124 { 125 int timeout = 5 * HZ, i = 1; 126 127 wait_event_timeout(sisusb->wait_q, (i = sisusb_all_free(sisusb)), 128 timeout); 129 130 return i; 131 } 132 133 static int sisusb_outurb_available(struct sisusb_usb_data *sisusb) 134 { 135 int i; 136 137 for (i = 0; i < sisusb->numobufs; i++) { 138 139 if ((sisusb->urbstatus[i] & (SU_URB_BUSY|SU_URB_ALLOC)) == 0) 140 return i; 141 142 } 143 144 return -1; 145 } 146 147 static int sisusb_get_free_outbuf(struct sisusb_usb_data *sisusb) 148 { 149 int i, timeout = 5 * HZ; 150 151 wait_event_timeout(sisusb->wait_q, 152 ((i = sisusb_outurb_available(sisusb)) >= 0), timeout); 153 154 return i; 155 } 156 157 static int sisusb_alloc_outbuf(struct sisusb_usb_data *sisusb) 158 { 159 int i; 160 161 i = sisusb_outurb_available(sisusb); 162 163 if (i >= 0) 164 sisusb->urbstatus[i] |= SU_URB_ALLOC; 165 166 return i; 167 } 168 169 static void sisusb_free_outbuf(struct sisusb_usb_data *sisusb, int index) 170 { 171 if ((index >= 0) && (index < sisusb->numobufs)) 172 sisusb->urbstatus[index] &= ~SU_URB_ALLOC; 173 } 174 175 /* completion callback */ 176 177 static void sisusb_bulk_completeout(struct urb *urb) 178 { 179 struct sisusb_urb_context *context = urb->context; 180 struct sisusb_usb_data *sisusb; 181 182 if (!context) 183 return; 184 185 sisusb = context->sisusb; 186 187 if (!sisusb || !sisusb->sisusb_dev || !sisusb->present) 188 return; 189 190 #ifndef SISUSB_DONTSYNC 191 if (context->actual_length) 192 *(context->actual_length) += urb->actual_length; 193 #endif 194 195 sisusb->urbstatus[context->urbindex] &= ~SU_URB_BUSY; 196 wake_up(&sisusb->wait_q); 197 } 198 199 static int sisusb_bulkout_msg(struct sisusb_usb_data *sisusb, int index, 200 unsigned int pipe, void *data, int len, int *actual_length, 201 int timeout, unsigned int tflags) 202 { 203 struct urb *urb = sisusb->sisurbout[index]; 204 int retval, byteswritten = 0; 205 206 /* Set up URB */ 207 urb->transfer_flags = 0; 208 209 usb_fill_bulk_urb(urb, sisusb->sisusb_dev, pipe, data, len, 210 sisusb_bulk_completeout, 211 &sisusb->urbout_context[index]); 212 213 urb->transfer_flags |= tflags; 214 urb->actual_length = 0; 215 216 /* Set up context */ 217 sisusb->urbout_context[index].actual_length = (timeout) ? 218 NULL : actual_length; 219 220 /* Declare this urb/buffer in use */ 221 sisusb->urbstatus[index] |= SU_URB_BUSY; 222 223 /* Submit URB */ 224 retval = usb_submit_urb(urb, GFP_KERNEL); 225 226 /* If OK, and if timeout > 0, wait for completion */ 227 if ((retval == 0) && timeout) { 228 wait_event_timeout(sisusb->wait_q, 229 (!(sisusb->urbstatus[index] & SU_URB_BUSY)), 230 timeout); 231 if (sisusb->urbstatus[index] & SU_URB_BUSY) { 232 /* URB timed out... kill it and report error */ 233 usb_kill_urb(urb); 234 retval = -ETIMEDOUT; 235 } else { 236 /* Otherwise, report urb status */ 237 retval = urb->status; 238 byteswritten = urb->actual_length; 239 } 240 } 241 242 if (actual_length) 243 *actual_length = byteswritten; 244 245 return retval; 246 } 247 248 /* 2. in-bulks */ 249 250 /* completion callback */ 251 252 static void sisusb_bulk_completein(struct urb *urb) 253 { 254 struct sisusb_usb_data *sisusb = urb->context; 255 256 if (!sisusb || !sisusb->sisusb_dev || !sisusb->present) 257 return; 258 259 sisusb->completein = 1; 260 wake_up(&sisusb->wait_q); 261 } 262 263 static int sisusb_bulkin_msg(struct sisusb_usb_data *sisusb, 264 unsigned int pipe, void *data, int len, 265 int *actual_length, int timeout, unsigned int tflags) 266 { 267 struct urb *urb = sisusb->sisurbin; 268 int retval, readbytes = 0; 269 270 urb->transfer_flags = 0; 271 272 usb_fill_bulk_urb(urb, sisusb->sisusb_dev, pipe, data, len, 273 sisusb_bulk_completein, sisusb); 274 275 urb->transfer_flags |= tflags; 276 urb->actual_length = 0; 277 278 sisusb->completein = 0; 279 retval = usb_submit_urb(urb, GFP_KERNEL); 280 if (retval == 0) { 281 wait_event_timeout(sisusb->wait_q, sisusb->completein, timeout); 282 if (!sisusb->completein) { 283 /* URB timed out... kill it and report error */ 284 usb_kill_urb(urb); 285 retval = -ETIMEDOUT; 286 } else { 287 /* URB completed within timeout */ 288 retval = urb->status; 289 readbytes = urb->actual_length; 290 } 291 } 292 293 if (actual_length) 294 *actual_length = readbytes; 295 296 return retval; 297 } 298 299 300 /* Level 1: */ 301 302 /* Send a bulk message of variable size 303 * 304 * To copy the data from userspace, give pointer to "userbuffer", 305 * to copy from (non-DMA) kernel memory, give "kernbuffer". If 306 * both of these are NULL, it is assumed, that the transfer 307 * buffer "sisusb->obuf[index]" is set up with the data to send. 308 * Index is ignored if either kernbuffer or userbuffer is set. 309 * If async is nonzero, URBs will be sent without waiting for 310 * completion of the previous URB. 311 * 312 * (return 0 on success) 313 */ 314 315 static int sisusb_send_bulk_msg(struct sisusb_usb_data *sisusb, int ep, int len, 316 char *kernbuffer, const char __user *userbuffer, int index, 317 ssize_t *bytes_written, unsigned int tflags, int async) 318 { 319 int result = 0, retry, count = len; 320 int passsize, thispass, transferred_len = 0; 321 int fromuser = (userbuffer != NULL) ? 1 : 0; 322 int fromkern = (kernbuffer != NULL) ? 1 : 0; 323 unsigned int pipe; 324 char *buffer; 325 326 (*bytes_written) = 0; 327 328 /* Sanity check */ 329 if (!sisusb || !sisusb->present || !sisusb->sisusb_dev) 330 return -ENODEV; 331 332 /* If we copy data from kernel or userspace, force the 333 * allocation of a buffer/urb. If we have the data in 334 * the transfer buffer[index] already, reuse the buffer/URB 335 * if the length is > buffer size. (So, transmitting 336 * large data amounts directly from the transfer buffer 337 * treats the buffer as a ring buffer. However, we need 338 * to sync in this case.) 339 */ 340 if (fromuser || fromkern) 341 index = -1; 342 else if (len > sisusb->obufsize) 343 async = 0; 344 345 pipe = usb_sndbulkpipe(sisusb->sisusb_dev, ep); 346 347 do { 348 passsize = thispass = (sisusb->obufsize < count) ? 349 sisusb->obufsize : count; 350 351 if (index < 0) 352 index = sisusb_get_free_outbuf(sisusb); 353 354 if (index < 0) 355 return -EIO; 356 357 buffer = sisusb->obuf[index]; 358 359 if (fromuser) { 360 361 if (copy_from_user(buffer, userbuffer, passsize)) 362 return -EFAULT; 363 364 userbuffer += passsize; 365 366 } else if (fromkern) { 367 368 memcpy(buffer, kernbuffer, passsize); 369 kernbuffer += passsize; 370 371 } 372 373 retry = 5; 374 while (thispass) { 375 376 if (!sisusb->sisusb_dev) 377 return -ENODEV; 378 379 result = sisusb_bulkout_msg(sisusb, index, pipe, 380 buffer, thispass, &transferred_len, 381 async ? 0 : 5 * HZ, tflags); 382 383 if (result == -ETIMEDOUT) { 384 385 /* Will not happen if async */ 386 if (!retry--) 387 return -ETIME; 388 389 continue; 390 } 391 392 if ((result == 0) && !async && transferred_len) { 393 394 thispass -= transferred_len; 395 buffer += transferred_len; 396 397 } else 398 break; 399 } 400 401 if (result) 402 return result; 403 404 (*bytes_written) += passsize; 405 count -= passsize; 406 407 /* Force new allocation in next iteration */ 408 if (fromuser || fromkern) 409 index = -1; 410 411 } while (count > 0); 412 413 if (async) { 414 #ifdef SISUSB_DONTSYNC 415 (*bytes_written) = len; 416 /* Some URBs/buffers might be busy */ 417 #else 418 sisusb_wait_all_out_complete(sisusb); 419 (*bytes_written) = transferred_len; 420 /* All URBs and all buffers are available */ 421 #endif 422 } 423 424 return ((*bytes_written) == len) ? 0 : -EIO; 425 } 426 427 /* Receive a bulk message of variable size 428 * 429 * To copy the data to userspace, give pointer to "userbuffer", 430 * to copy to kernel memory, give "kernbuffer". One of them 431 * MUST be set. (There is no technique for letting the caller 432 * read directly from the ibuf.) 433 * 434 */ 435 436 static int sisusb_recv_bulk_msg(struct sisusb_usb_data *sisusb, int ep, int len, 437 void *kernbuffer, char __user *userbuffer, ssize_t *bytes_read, 438 unsigned int tflags) 439 { 440 int result = 0, retry, count = len; 441 int bufsize, thispass, transferred_len; 442 unsigned int pipe; 443 char *buffer; 444 445 (*bytes_read) = 0; 446 447 /* Sanity check */ 448 if (!sisusb || !sisusb->present || !sisusb->sisusb_dev) 449 return -ENODEV; 450 451 pipe = usb_rcvbulkpipe(sisusb->sisusb_dev, ep); 452 buffer = sisusb->ibuf; 453 bufsize = sisusb->ibufsize; 454 455 retry = 5; 456 457 #ifdef SISUSB_DONTSYNC 458 if (!(sisusb_wait_all_out_complete(sisusb))) 459 return -EIO; 460 #endif 461 462 while (count > 0) { 463 464 if (!sisusb->sisusb_dev) 465 return -ENODEV; 466 467 thispass = (bufsize < count) ? bufsize : count; 468 469 result = sisusb_bulkin_msg(sisusb, pipe, buffer, thispass, 470 &transferred_len, 5 * HZ, tflags); 471 472 if (transferred_len) 473 thispass = transferred_len; 474 475 else if (result == -ETIMEDOUT) { 476 477 if (!retry--) 478 return -ETIME; 479 480 continue; 481 482 } else 483 return -EIO; 484 485 486 if (thispass) { 487 488 (*bytes_read) += thispass; 489 count -= thispass; 490 491 if (userbuffer) { 492 493 if (copy_to_user(userbuffer, buffer, thispass)) 494 return -EFAULT; 495 496 userbuffer += thispass; 497 498 } else { 499 500 memcpy(kernbuffer, buffer, thispass); 501 kernbuffer += thispass; 502 503 } 504 505 } 506 507 } 508 509 return ((*bytes_read) == len) ? 0 : -EIO; 510 } 511 512 static int sisusb_send_packet(struct sisusb_usb_data *sisusb, int len, 513 struct sisusb_packet *packet) 514 { 515 int ret; 516 ssize_t bytes_transferred = 0; 517 __le32 tmp; 518 519 if (len == 6) 520 packet->data = 0; 521 522 #ifdef SISUSB_DONTSYNC 523 if (!(sisusb_wait_all_out_complete(sisusb))) 524 return 1; 525 #endif 526 527 /* Eventually correct endianness */ 528 SISUSB_CORRECT_ENDIANNESS_PACKET(packet); 529 530 /* 1. send the packet */ 531 ret = sisusb_send_bulk_msg(sisusb, SISUSB_EP_GFX_OUT, len, 532 (char *)packet, NULL, 0, &bytes_transferred, 0, 0); 533 534 if ((ret == 0) && (len == 6)) { 535 536 /* 2. if packet len == 6, it means we read, so wait for 32bit 537 * return value and write it to packet->data 538 */ 539 ret = sisusb_recv_bulk_msg(sisusb, SISUSB_EP_GFX_IN, 4, 540 (char *)&tmp, NULL, &bytes_transferred, 0); 541 542 packet->data = le32_to_cpu(tmp); 543 } 544 545 return ret; 546 } 547 548 static int sisusb_send_bridge_packet(struct sisusb_usb_data *sisusb, int len, 549 struct sisusb_packet *packet, unsigned int tflags) 550 { 551 int ret; 552 ssize_t bytes_transferred = 0; 553 __le32 tmp; 554 555 if (len == 6) 556 packet->data = 0; 557 558 #ifdef SISUSB_DONTSYNC 559 if (!(sisusb_wait_all_out_complete(sisusb))) 560 return 1; 561 #endif 562 563 /* Eventually correct endianness */ 564 SISUSB_CORRECT_ENDIANNESS_PACKET(packet); 565 566 /* 1. send the packet */ 567 ret = sisusb_send_bulk_msg(sisusb, SISUSB_EP_BRIDGE_OUT, len, 568 (char *)packet, NULL, 0, &bytes_transferred, tflags, 0); 569 570 if ((ret == 0) && (len == 6)) { 571 572 /* 2. if packet len == 6, it means we read, so wait for 32bit 573 * return value and write it to packet->data 574 */ 575 ret = sisusb_recv_bulk_msg(sisusb, SISUSB_EP_BRIDGE_IN, 4, 576 (char *)&tmp, NULL, &bytes_transferred, 0); 577 578 packet->data = le32_to_cpu(tmp); 579 } 580 581 return ret; 582 } 583 584 /* access video memory and mmio (return 0 on success) */ 585 586 /* Low level */ 587 588 /* The following routines assume being used to transfer byte, word, 589 * long etc. 590 * This means that 591 * - the write routines expect "data" in machine endianness format. 592 * The data will be converted to leXX in sisusb_xxx_packet. 593 * - the read routines can expect read data in machine-endianess. 594 */ 595 596 static int sisusb_write_memio_byte(struct sisusb_usb_data *sisusb, int type, 597 u32 addr, u8 data) 598 { 599 struct sisusb_packet packet; 600 601 packet.header = (1 << (addr & 3)) | (type << 6); 602 packet.address = addr & ~3; 603 packet.data = data << ((addr & 3) << 3); 604 return sisusb_send_packet(sisusb, 10, &packet); 605 } 606 607 static int sisusb_write_memio_word(struct sisusb_usb_data *sisusb, int type, 608 u32 addr, u16 data) 609 { 610 struct sisusb_packet packet; 611 int ret = 0; 612 613 packet.address = addr & ~3; 614 615 switch (addr & 3) { 616 case 0: 617 packet.header = (type << 6) | 0x0003; 618 packet.data = (u32)data; 619 ret = sisusb_send_packet(sisusb, 10, &packet); 620 break; 621 case 1: 622 packet.header = (type << 6) | 0x0006; 623 packet.data = (u32)data << 8; 624 ret = sisusb_send_packet(sisusb, 10, &packet); 625 break; 626 case 2: 627 packet.header = (type << 6) | 0x000c; 628 packet.data = (u32)data << 16; 629 ret = sisusb_send_packet(sisusb, 10, &packet); 630 break; 631 case 3: 632 packet.header = (type << 6) | 0x0008; 633 packet.data = (u32)data << 24; 634 ret = sisusb_send_packet(sisusb, 10, &packet); 635 packet.header = (type << 6) | 0x0001; 636 packet.address = (addr & ~3) + 4; 637 packet.data = (u32)data >> 8; 638 ret |= sisusb_send_packet(sisusb, 10, &packet); 639 } 640 641 return ret; 642 } 643 644 static int sisusb_write_memio_24bit(struct sisusb_usb_data *sisusb, int type, 645 u32 addr, u32 data) 646 { 647 struct sisusb_packet packet; 648 int ret = 0; 649 650 packet.address = addr & ~3; 651 652 switch (addr & 3) { 653 case 0: 654 packet.header = (type << 6) | 0x0007; 655 packet.data = data & 0x00ffffff; 656 ret = sisusb_send_packet(sisusb, 10, &packet); 657 break; 658 case 1: 659 packet.header = (type << 6) | 0x000e; 660 packet.data = data << 8; 661 ret = sisusb_send_packet(sisusb, 10, &packet); 662 break; 663 case 2: 664 packet.header = (type << 6) | 0x000c; 665 packet.data = data << 16; 666 ret = sisusb_send_packet(sisusb, 10, &packet); 667 packet.header = (type << 6) | 0x0001; 668 packet.address = (addr & ~3) + 4; 669 packet.data = (data >> 16) & 0x00ff; 670 ret |= sisusb_send_packet(sisusb, 10, &packet); 671 break; 672 case 3: 673 packet.header = (type << 6) | 0x0008; 674 packet.data = data << 24; 675 ret = sisusb_send_packet(sisusb, 10, &packet); 676 packet.header = (type << 6) | 0x0003; 677 packet.address = (addr & ~3) + 4; 678 packet.data = (data >> 8) & 0xffff; 679 ret |= sisusb_send_packet(sisusb, 10, &packet); 680 } 681 682 return ret; 683 } 684 685 static int sisusb_write_memio_long(struct sisusb_usb_data *sisusb, int type, 686 u32 addr, u32 data) 687 { 688 struct sisusb_packet packet; 689 int ret = 0; 690 691 packet.address = addr & ~3; 692 693 switch (addr & 3) { 694 case 0: 695 packet.header = (type << 6) | 0x000f; 696 packet.data = data; 697 ret = sisusb_send_packet(sisusb, 10, &packet); 698 break; 699 case 1: 700 packet.header = (type << 6) | 0x000e; 701 packet.data = data << 8; 702 ret = sisusb_send_packet(sisusb, 10, &packet); 703 packet.header = (type << 6) | 0x0001; 704 packet.address = (addr & ~3) + 4; 705 packet.data = data >> 24; 706 ret |= sisusb_send_packet(sisusb, 10, &packet); 707 break; 708 case 2: 709 packet.header = (type << 6) | 0x000c; 710 packet.data = data << 16; 711 ret = sisusb_send_packet(sisusb, 10, &packet); 712 packet.header = (type << 6) | 0x0003; 713 packet.address = (addr & ~3) + 4; 714 packet.data = data >> 16; 715 ret |= sisusb_send_packet(sisusb, 10, &packet); 716 break; 717 case 3: 718 packet.header = (type << 6) | 0x0008; 719 packet.data = data << 24; 720 ret = sisusb_send_packet(sisusb, 10, &packet); 721 packet.header = (type << 6) | 0x0007; 722 packet.address = (addr & ~3) + 4; 723 packet.data = data >> 8; 724 ret |= sisusb_send_packet(sisusb, 10, &packet); 725 } 726 727 return ret; 728 } 729 730 /* The xxx_bulk routines copy a buffer of variable size. They treat the 731 * buffer as chars, therefore lsb/msb has to be corrected if using the 732 * byte/word/long/etc routines for speed-up 733 * 734 * If data is from userland, set "userbuffer" (and clear "kernbuffer"), 735 * if data is in kernel space, set "kernbuffer" (and clear "userbuffer"); 736 * if neither "kernbuffer" nor "userbuffer" are given, it is assumed 737 * that the data already is in the transfer buffer "sisusb->obuf[index]". 738 */ 739 740 static int sisusb_write_mem_bulk(struct sisusb_usb_data *sisusb, u32 addr, 741 char *kernbuffer, int length, const char __user *userbuffer, 742 int index, ssize_t *bytes_written) 743 { 744 struct sisusb_packet packet; 745 int ret = 0; 746 static int msgcount; 747 u8 swap8, fromkern = kernbuffer ? 1 : 0; 748 u16 swap16; 749 u32 swap32, flag = (length >> 28) & 1; 750 u8 buf[4]; 751 752 /* if neither kernbuffer not userbuffer are given, assume 753 * data in obuf 754 */ 755 if (!fromkern && !userbuffer) 756 kernbuffer = sisusb->obuf[index]; 757 758 (*bytes_written = 0); 759 760 length &= 0x00ffffff; 761 762 while (length) { 763 switch (length) { 764 case 1: 765 if (userbuffer) { 766 if (get_user(swap8, (u8 __user *)userbuffer)) 767 return -EFAULT; 768 } else 769 swap8 = kernbuffer[0]; 770 771 ret = sisusb_write_memio_byte(sisusb, SISUSB_TYPE_MEM, 772 addr, swap8); 773 774 if (!ret) 775 (*bytes_written)++; 776 777 return ret; 778 779 case 2: 780 if (userbuffer) { 781 if (get_user(swap16, (u16 __user *)userbuffer)) 782 return -EFAULT; 783 } else 784 swap16 = *((u16 *)kernbuffer); 785 786 ret = sisusb_write_memio_word(sisusb, SISUSB_TYPE_MEM, 787 addr, swap16); 788 789 if (!ret) 790 (*bytes_written) += 2; 791 792 return ret; 793 794 case 3: 795 if (userbuffer) { 796 if (copy_from_user(&buf, userbuffer, 3)) 797 return -EFAULT; 798 #ifdef __BIG_ENDIAN 799 swap32 = (buf[0] << 16) | 800 (buf[1] << 8) | 801 buf[2]; 802 #else 803 swap32 = (buf[2] << 16) | 804 (buf[1] << 8) | 805 buf[0]; 806 #endif 807 } else 808 #ifdef __BIG_ENDIAN 809 swap32 = (kernbuffer[0] << 16) | 810 (kernbuffer[1] << 8) | 811 kernbuffer[2]; 812 #else 813 swap32 = (kernbuffer[2] << 16) | 814 (kernbuffer[1] << 8) | 815 kernbuffer[0]; 816 #endif 817 818 ret = sisusb_write_memio_24bit(sisusb, SISUSB_TYPE_MEM, 819 addr, swap32); 820 821 if (!ret) 822 (*bytes_written) += 3; 823 824 return ret; 825 826 case 4: 827 if (userbuffer) { 828 if (get_user(swap32, (u32 __user *)userbuffer)) 829 return -EFAULT; 830 } else 831 swap32 = *((u32 *)kernbuffer); 832 833 ret = sisusb_write_memio_long(sisusb, SISUSB_TYPE_MEM, 834 addr, swap32); 835 if (!ret) 836 (*bytes_written) += 4; 837 838 return ret; 839 840 default: 841 if ((length & ~3) > 0x10000) { 842 843 packet.header = 0x001f; 844 packet.address = 0x000001d4; 845 packet.data = addr; 846 ret = sisusb_send_bridge_packet(sisusb, 10, 847 &packet, 0); 848 packet.header = 0x001f; 849 packet.address = 0x000001d0; 850 packet.data = (length & ~3); 851 ret |= sisusb_send_bridge_packet(sisusb, 10, 852 &packet, 0); 853 packet.header = 0x001f; 854 packet.address = 0x000001c0; 855 packet.data = flag | 0x16; 856 ret |= sisusb_send_bridge_packet(sisusb, 10, 857 &packet, 0); 858 if (userbuffer) { 859 ret |= sisusb_send_bulk_msg(sisusb, 860 SISUSB_EP_GFX_LBULK_OUT, 861 (length & ~3), 862 NULL, userbuffer, 0, 863 bytes_written, 0, 1); 864 userbuffer += (*bytes_written); 865 } else if (fromkern) { 866 ret |= sisusb_send_bulk_msg(sisusb, 867 SISUSB_EP_GFX_LBULK_OUT, 868 (length & ~3), 869 kernbuffer, NULL, 0, 870 bytes_written, 0, 1); 871 kernbuffer += (*bytes_written); 872 } else { 873 ret |= sisusb_send_bulk_msg(sisusb, 874 SISUSB_EP_GFX_LBULK_OUT, 875 (length & ~3), 876 NULL, NULL, index, 877 bytes_written, 0, 1); 878 kernbuffer += ((*bytes_written) & 879 (sisusb->obufsize-1)); 880 } 881 882 } else { 883 884 packet.header = 0x001f; 885 packet.address = 0x00000194; 886 packet.data = addr; 887 ret = sisusb_send_bridge_packet(sisusb, 10, 888 &packet, 0); 889 packet.header = 0x001f; 890 packet.address = 0x00000190; 891 packet.data = (length & ~3); 892 ret |= sisusb_send_bridge_packet(sisusb, 10, 893 &packet, 0); 894 if (sisusb->flagb0 != 0x16) { 895 packet.header = 0x001f; 896 packet.address = 0x00000180; 897 packet.data = flag | 0x16; 898 ret |= sisusb_send_bridge_packet(sisusb, 899 10, &packet, 0); 900 sisusb->flagb0 = 0x16; 901 } 902 if (userbuffer) { 903 ret |= sisusb_send_bulk_msg(sisusb, 904 SISUSB_EP_GFX_BULK_OUT, 905 (length & ~3), 906 NULL, userbuffer, 0, 907 bytes_written, 0, 1); 908 userbuffer += (*bytes_written); 909 } else if (fromkern) { 910 ret |= sisusb_send_bulk_msg(sisusb, 911 SISUSB_EP_GFX_BULK_OUT, 912 (length & ~3), 913 kernbuffer, NULL, 0, 914 bytes_written, 0, 1); 915 kernbuffer += (*bytes_written); 916 } else { 917 ret |= sisusb_send_bulk_msg(sisusb, 918 SISUSB_EP_GFX_BULK_OUT, 919 (length & ~3), 920 NULL, NULL, index, 921 bytes_written, 0, 1); 922 kernbuffer += ((*bytes_written) & 923 (sisusb->obufsize-1)); 924 } 925 } 926 if (ret) { 927 msgcount++; 928 if (msgcount < 500) 929 dev_err(&sisusb->sisusb_dev->dev, 930 "Wrote %zd of %d bytes, error %d\n", 931 *bytes_written, length, 932 ret); 933 else if (msgcount == 500) 934 dev_err(&sisusb->sisusb_dev->dev, 935 "Too many errors, logging stopped\n"); 936 } 937 addr += (*bytes_written); 938 length -= (*bytes_written); 939 } 940 941 if (ret) 942 break; 943 944 } 945 946 return ret ? -EIO : 0; 947 } 948 949 /* Remember: Read data in packet is in machine-endianess! So for 950 * byte, word, 24bit, long no endian correction is necessary. 951 */ 952 953 static int sisusb_read_memio_byte(struct sisusb_usb_data *sisusb, int type, 954 u32 addr, u8 *data) 955 { 956 struct sisusb_packet packet; 957 int ret; 958 959 CLEARPACKET(&packet); 960 packet.header = (1 << (addr & 3)) | (type << 6); 961 packet.address = addr & ~3; 962 ret = sisusb_send_packet(sisusb, 6, &packet); 963 *data = (u8)(packet.data >> ((addr & 3) << 3)); 964 return ret; 965 } 966 967 static int sisusb_read_memio_word(struct sisusb_usb_data *sisusb, int type, 968 u32 addr, u16 *data) 969 { 970 struct sisusb_packet packet; 971 int ret = 0; 972 973 CLEARPACKET(&packet); 974 975 packet.address = addr & ~3; 976 977 switch (addr & 3) { 978 case 0: 979 packet.header = (type << 6) | 0x0003; 980 ret = sisusb_send_packet(sisusb, 6, &packet); 981 *data = (u16)(packet.data); 982 break; 983 case 1: 984 packet.header = (type << 6) | 0x0006; 985 ret = sisusb_send_packet(sisusb, 6, &packet); 986 *data = (u16)(packet.data >> 8); 987 break; 988 case 2: 989 packet.header = (type << 6) | 0x000c; 990 ret = sisusb_send_packet(sisusb, 6, &packet); 991 *data = (u16)(packet.data >> 16); 992 break; 993 case 3: 994 packet.header = (type << 6) | 0x0008; 995 ret = sisusb_send_packet(sisusb, 6, &packet); 996 *data = (u16)(packet.data >> 24); 997 packet.header = (type << 6) | 0x0001; 998 packet.address = (addr & ~3) + 4; 999 ret |= sisusb_send_packet(sisusb, 6, &packet); 1000 *data |= (u16)(packet.data << 8); 1001 } 1002 1003 return ret; 1004 } 1005 1006 static int sisusb_read_memio_24bit(struct sisusb_usb_data *sisusb, int type, 1007 u32 addr, u32 *data) 1008 { 1009 struct sisusb_packet packet; 1010 int ret = 0; 1011 1012 packet.address = addr & ~3; 1013 1014 switch (addr & 3) { 1015 case 0: 1016 packet.header = (type << 6) | 0x0007; 1017 ret = sisusb_send_packet(sisusb, 6, &packet); 1018 *data = packet.data & 0x00ffffff; 1019 break; 1020 case 1: 1021 packet.header = (type << 6) | 0x000e; 1022 ret = sisusb_send_packet(sisusb, 6, &packet); 1023 *data = packet.data >> 8; 1024 break; 1025 case 2: 1026 packet.header = (type << 6) | 0x000c; 1027 ret = sisusb_send_packet(sisusb, 6, &packet); 1028 *data = packet.data >> 16; 1029 packet.header = (type << 6) | 0x0001; 1030 packet.address = (addr & ~3) + 4; 1031 ret |= sisusb_send_packet(sisusb, 6, &packet); 1032 *data |= ((packet.data & 0xff) << 16); 1033 break; 1034 case 3: 1035 packet.header = (type << 6) | 0x0008; 1036 ret = sisusb_send_packet(sisusb, 6, &packet); 1037 *data = packet.data >> 24; 1038 packet.header = (type << 6) | 0x0003; 1039 packet.address = (addr & ~3) + 4; 1040 ret |= sisusb_send_packet(sisusb, 6, &packet); 1041 *data |= ((packet.data & 0xffff) << 8); 1042 } 1043 1044 return ret; 1045 } 1046 1047 static int sisusb_read_memio_long(struct sisusb_usb_data *sisusb, int type, 1048 u32 addr, u32 *data) 1049 { 1050 struct sisusb_packet packet; 1051 int ret = 0; 1052 1053 packet.address = addr & ~3; 1054 1055 switch (addr & 3) { 1056 case 0: 1057 packet.header = (type << 6) | 0x000f; 1058 ret = sisusb_send_packet(sisusb, 6, &packet); 1059 *data = packet.data; 1060 break; 1061 case 1: 1062 packet.header = (type << 6) | 0x000e; 1063 ret = sisusb_send_packet(sisusb, 6, &packet); 1064 *data = packet.data >> 8; 1065 packet.header = (type << 6) | 0x0001; 1066 packet.address = (addr & ~3) + 4; 1067 ret |= sisusb_send_packet(sisusb, 6, &packet); 1068 *data |= (packet.data << 24); 1069 break; 1070 case 2: 1071 packet.header = (type << 6) | 0x000c; 1072 ret = sisusb_send_packet(sisusb, 6, &packet); 1073 *data = packet.data >> 16; 1074 packet.header = (type << 6) | 0x0003; 1075 packet.address = (addr & ~3) + 4; 1076 ret |= sisusb_send_packet(sisusb, 6, &packet); 1077 *data |= (packet.data << 16); 1078 break; 1079 case 3: 1080 packet.header = (type << 6) | 0x0008; 1081 ret = sisusb_send_packet(sisusb, 6, &packet); 1082 *data = packet.data >> 24; 1083 packet.header = (type << 6) | 0x0007; 1084 packet.address = (addr & ~3) + 4; 1085 ret |= sisusb_send_packet(sisusb, 6, &packet); 1086 *data |= (packet.data << 8); 1087 } 1088 1089 return ret; 1090 } 1091 1092 static int sisusb_read_mem_bulk(struct sisusb_usb_data *sisusb, u32 addr, 1093 char *kernbuffer, int length, char __user *userbuffer, 1094 ssize_t *bytes_read) 1095 { 1096 int ret = 0; 1097 char buf[4]; 1098 u16 swap16; 1099 u32 swap32; 1100 1101 (*bytes_read = 0); 1102 1103 length &= 0x00ffffff; 1104 1105 while (length) { 1106 switch (length) { 1107 case 1: 1108 ret |= sisusb_read_memio_byte(sisusb, SISUSB_TYPE_MEM, 1109 addr, &buf[0]); 1110 if (!ret) { 1111 (*bytes_read)++; 1112 if (userbuffer) { 1113 if (put_user(buf[0], (u8 __user *)userbuffer)) 1114 return -EFAULT; 1115 } else 1116 kernbuffer[0] = buf[0]; 1117 } 1118 return ret; 1119 1120 case 2: 1121 ret |= sisusb_read_memio_word(sisusb, SISUSB_TYPE_MEM, 1122 addr, &swap16); 1123 if (!ret) { 1124 (*bytes_read) += 2; 1125 if (userbuffer) { 1126 if (put_user(swap16, (u16 __user *)userbuffer)) 1127 return -EFAULT; 1128 } else { 1129 *((u16 *)kernbuffer) = swap16; 1130 } 1131 } 1132 return ret; 1133 1134 case 3: 1135 ret |= sisusb_read_memio_24bit(sisusb, SISUSB_TYPE_MEM, 1136 addr, &swap32); 1137 if (!ret) { 1138 (*bytes_read) += 3; 1139 #ifdef __BIG_ENDIAN 1140 buf[0] = (swap32 >> 16) & 0xff; 1141 buf[1] = (swap32 >> 8) & 0xff; 1142 buf[2] = swap32 & 0xff; 1143 #else 1144 buf[2] = (swap32 >> 16) & 0xff; 1145 buf[1] = (swap32 >> 8) & 0xff; 1146 buf[0] = swap32 & 0xff; 1147 #endif 1148 if (userbuffer) { 1149 if (copy_to_user(userbuffer, 1150 &buf[0], 3)) 1151 return -EFAULT; 1152 } else { 1153 kernbuffer[0] = buf[0]; 1154 kernbuffer[1] = buf[1]; 1155 kernbuffer[2] = buf[2]; 1156 } 1157 } 1158 return ret; 1159 1160 default: 1161 ret |= sisusb_read_memio_long(sisusb, SISUSB_TYPE_MEM, 1162 addr, &swap32); 1163 if (!ret) { 1164 (*bytes_read) += 4; 1165 if (userbuffer) { 1166 if (put_user(swap32, (u32 __user *)userbuffer)) 1167 return -EFAULT; 1168 1169 userbuffer += 4; 1170 } else { 1171 *((u32 *)kernbuffer) = swap32; 1172 kernbuffer += 4; 1173 } 1174 addr += 4; 1175 length -= 4; 1176 } 1177 } 1178 if (ret) 1179 break; 1180 } 1181 1182 return ret; 1183 } 1184 1185 /* High level: Gfx (indexed) register access */ 1186 1187 static int sisusb_setidxreg(struct sisusb_usb_data *sisusb, u32 port, 1188 u8 index, u8 data) 1189 { 1190 int ret; 1191 1192 ret = sisusb_write_memio_byte(sisusb, SISUSB_TYPE_IO, port, index); 1193 ret |= sisusb_write_memio_byte(sisusb, SISUSB_TYPE_IO, port + 1, data); 1194 return ret; 1195 } 1196 1197 static int sisusb_getidxreg(struct sisusb_usb_data *sisusb, u32 port, 1198 u8 index, u8 *data) 1199 { 1200 int ret; 1201 1202 ret = sisusb_write_memio_byte(sisusb, SISUSB_TYPE_IO, port, index); 1203 ret |= sisusb_read_memio_byte(sisusb, SISUSB_TYPE_IO, port + 1, data); 1204 return ret; 1205 } 1206 1207 static int sisusb_setidxregandor(struct sisusb_usb_data *sisusb, u32 port, u8 idx, 1208 u8 myand, u8 myor) 1209 { 1210 int ret; 1211 u8 tmp; 1212 1213 ret = sisusb_write_memio_byte(sisusb, SISUSB_TYPE_IO, port, idx); 1214 ret |= sisusb_read_memio_byte(sisusb, SISUSB_TYPE_IO, port + 1, &tmp); 1215 tmp &= myand; 1216 tmp |= myor; 1217 ret |= sisusb_write_memio_byte(sisusb, SISUSB_TYPE_IO, port + 1, tmp); 1218 return ret; 1219 } 1220 1221 static int sisusb_setidxregmask(struct sisusb_usb_data *sisusb, 1222 u32 port, u8 idx, u8 data, u8 mask) 1223 { 1224 int ret; 1225 u8 tmp; 1226 1227 ret = sisusb_write_memio_byte(sisusb, SISUSB_TYPE_IO, port, idx); 1228 ret |= sisusb_read_memio_byte(sisusb, SISUSB_TYPE_IO, port + 1, &tmp); 1229 tmp &= ~(mask); 1230 tmp |= (data & mask); 1231 ret |= sisusb_write_memio_byte(sisusb, SISUSB_TYPE_IO, port + 1, tmp); 1232 return ret; 1233 } 1234 1235 static int sisusb_setidxregor(struct sisusb_usb_data *sisusb, u32 port, 1236 u8 index, u8 myor) 1237 { 1238 return sisusb_setidxregandor(sisusb, port, index, 0xff, myor); 1239 } 1240 1241 static int sisusb_setidxregand(struct sisusb_usb_data *sisusb, u32 port, 1242 u8 idx, u8 myand) 1243 { 1244 return sisusb_setidxregandor(sisusb, port, idx, myand, 0x00); 1245 } 1246 1247 /* Write/read video ram */ 1248 1249 #ifdef SISUSBENDIANTEST 1250 static void sisusb_testreadwrite(struct sisusb_usb_data *sisusb) 1251 { 1252 static u8 srcbuffer[] = { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 }; 1253 char destbuffer[10]; 1254 int i, j; 1255 1256 sisusb_copy_memory(sisusb, srcbuffer, sisusb->vrambase, 7); 1257 1258 for (i = 1; i <= 7; i++) { 1259 dev_dbg(&sisusb->sisusb_dev->dev, 1260 "sisusb: rwtest %d bytes\n", i); 1261 sisusb_read_memory(sisusb, destbuffer, sisusb->vrambase, i); 1262 for (j = 0; j < i; j++) { 1263 dev_dbg(&sisusb->sisusb_dev->dev, 1264 "rwtest read[%d] = %x\n", 1265 j, destbuffer[j]); 1266 } 1267 } 1268 } 1269 #endif 1270 1271 /* access pci config registers (reg numbers 0, 4, 8, etc) */ 1272 1273 static int sisusb_write_pci_config(struct sisusb_usb_data *sisusb, 1274 int regnum, u32 data) 1275 { 1276 struct sisusb_packet packet; 1277 1278 packet.header = 0x008f; 1279 packet.address = regnum | 0x10000; 1280 packet.data = data; 1281 return sisusb_send_packet(sisusb, 10, &packet); 1282 } 1283 1284 static int sisusb_read_pci_config(struct sisusb_usb_data *sisusb, 1285 int regnum, u32 *data) 1286 { 1287 struct sisusb_packet packet; 1288 int ret; 1289 1290 packet.header = 0x008f; 1291 packet.address = (u32)regnum | 0x10000; 1292 ret = sisusb_send_packet(sisusb, 6, &packet); 1293 *data = packet.data; 1294 return ret; 1295 } 1296 1297 /* Clear video RAM */ 1298 1299 static int sisusb_clear_vram(struct sisusb_usb_data *sisusb, 1300 u32 address, int length) 1301 { 1302 int ret, i; 1303 ssize_t j; 1304 1305 if (address < sisusb->vrambase) 1306 return 1; 1307 1308 if (address >= sisusb->vrambase + sisusb->vramsize) 1309 return 1; 1310 1311 if (address + length > sisusb->vrambase + sisusb->vramsize) 1312 length = sisusb->vrambase + sisusb->vramsize - address; 1313 1314 if (length <= 0) 1315 return 0; 1316 1317 /* allocate free buffer/urb and clear the buffer */ 1318 i = sisusb_alloc_outbuf(sisusb); 1319 if (i < 0) 1320 return -EBUSY; 1321 1322 memset(sisusb->obuf[i], 0, sisusb->obufsize); 1323 1324 /* We can write a length > buffer size here. The buffer 1325 * data will simply be re-used (like a ring-buffer). 1326 */ 1327 ret = sisusb_write_mem_bulk(sisusb, address, NULL, length, NULL, i, &j); 1328 1329 /* Free the buffer/urb */ 1330 sisusb_free_outbuf(sisusb, i); 1331 1332 return ret; 1333 } 1334 1335 /* Initialize the graphics core (return 0 on success) 1336 * This resets the graphics hardware and puts it into 1337 * a defined mode (640x480@60Hz) 1338 */ 1339 1340 #define GETREG(r, d) sisusb_read_memio_byte(sisusb, SISUSB_TYPE_IO, r, d) 1341 #define SETREG(r, d) sisusb_write_memio_byte(sisusb, SISUSB_TYPE_IO, r, d) 1342 #define SETIREG(r, i, d) sisusb_setidxreg(sisusb, r, i, d) 1343 #define GETIREG(r, i, d) sisusb_getidxreg(sisusb, r, i, d) 1344 #define SETIREGOR(r, i, o) sisusb_setidxregor(sisusb, r, i, o) 1345 #define SETIREGAND(r, i, a) sisusb_setidxregand(sisusb, r, i, a) 1346 #define SETIREGANDOR(r, i, a, o) sisusb_setidxregandor(sisusb, r, i, a, o) 1347 #define READL(a, d) sisusb_read_memio_long(sisusb, SISUSB_TYPE_MEM, a, d) 1348 #define WRITEL(a, d) sisusb_write_memio_long(sisusb, SISUSB_TYPE_MEM, a, d) 1349 #define READB(a, d) sisusb_read_memio_byte(sisusb, SISUSB_TYPE_MEM, a, d) 1350 #define WRITEB(a, d) sisusb_write_memio_byte(sisusb, SISUSB_TYPE_MEM, a, d) 1351 1352 static int sisusb_triggersr16(struct sisusb_usb_data *sisusb, u8 ramtype) 1353 { 1354 int ret; 1355 u8 tmp8; 1356 1357 ret = GETIREG(SISSR, 0x16, &tmp8); 1358 if (ramtype <= 1) { 1359 tmp8 &= 0x3f; 1360 ret |= SETIREG(SISSR, 0x16, tmp8); 1361 tmp8 |= 0x80; 1362 ret |= SETIREG(SISSR, 0x16, tmp8); 1363 } else { 1364 tmp8 |= 0xc0; 1365 ret |= SETIREG(SISSR, 0x16, tmp8); 1366 tmp8 &= 0x0f; 1367 ret |= SETIREG(SISSR, 0x16, tmp8); 1368 tmp8 |= 0x80; 1369 ret |= SETIREG(SISSR, 0x16, tmp8); 1370 tmp8 &= 0x0f; 1371 ret |= SETIREG(SISSR, 0x16, tmp8); 1372 tmp8 |= 0xd0; 1373 ret |= SETIREG(SISSR, 0x16, tmp8); 1374 tmp8 &= 0x0f; 1375 ret |= SETIREG(SISSR, 0x16, tmp8); 1376 tmp8 |= 0xa0; 1377 ret |= SETIREG(SISSR, 0x16, tmp8); 1378 } 1379 return ret; 1380 } 1381 1382 static int sisusb_getbuswidth(struct sisusb_usb_data *sisusb, 1383 int *bw, int *chab) 1384 { 1385 int ret; 1386 u8 ramtype, done = 0; 1387 u32 t0, t1, t2, t3; 1388 u32 ramptr = SISUSB_PCI_MEMBASE; 1389 1390 ret = GETIREG(SISSR, 0x3a, &ramtype); 1391 ramtype &= 3; 1392 1393 ret |= SETIREG(SISSR, 0x13, 0x00); 1394 1395 if (ramtype <= 1) { 1396 ret |= SETIREG(SISSR, 0x14, 0x12); 1397 ret |= SETIREGAND(SISSR, 0x15, 0xef); 1398 } else { 1399 ret |= SETIREG(SISSR, 0x14, 0x02); 1400 } 1401 1402 ret |= sisusb_triggersr16(sisusb, ramtype); 1403 ret |= WRITEL(ramptr + 0, 0x01234567); 1404 ret |= WRITEL(ramptr + 4, 0x456789ab); 1405 ret |= WRITEL(ramptr + 8, 0x89abcdef); 1406 ret |= WRITEL(ramptr + 12, 0xcdef0123); 1407 ret |= WRITEL(ramptr + 16, 0x55555555); 1408 ret |= WRITEL(ramptr + 20, 0x55555555); 1409 ret |= WRITEL(ramptr + 24, 0xffffffff); 1410 ret |= WRITEL(ramptr + 28, 0xffffffff); 1411 ret |= READL(ramptr + 0, &t0); 1412 ret |= READL(ramptr + 4, &t1); 1413 ret |= READL(ramptr + 8, &t2); 1414 ret |= READL(ramptr + 12, &t3); 1415 1416 if (ramtype <= 1) { 1417 1418 *chab = 0; *bw = 64; 1419 1420 if ((t3 != 0xcdef0123) || (t2 != 0x89abcdef)) { 1421 if ((t1 == 0x456789ab) && (t0 == 0x01234567)) { 1422 *chab = 0; *bw = 64; 1423 ret |= SETIREGAND(SISSR, 0x14, 0xfd); 1424 } 1425 } 1426 if ((t1 != 0x456789ab) || (t0 != 0x01234567)) { 1427 *chab = 1; *bw = 64; 1428 ret |= SETIREGANDOR(SISSR, 0x14, 0xfc, 0x01); 1429 1430 ret |= sisusb_triggersr16(sisusb, ramtype); 1431 ret |= WRITEL(ramptr + 0, 0x89abcdef); 1432 ret |= WRITEL(ramptr + 4, 0xcdef0123); 1433 ret |= WRITEL(ramptr + 8, 0x55555555); 1434 ret |= WRITEL(ramptr + 12, 0x55555555); 1435 ret |= WRITEL(ramptr + 16, 0xaaaaaaaa); 1436 ret |= WRITEL(ramptr + 20, 0xaaaaaaaa); 1437 ret |= READL(ramptr + 4, &t1); 1438 1439 if (t1 != 0xcdef0123) { 1440 *bw = 32; 1441 ret |= SETIREGOR(SISSR, 0x15, 0x10); 1442 } 1443 } 1444 1445 } else { 1446 1447 *chab = 0; *bw = 64; /* default: cha, bw = 64 */ 1448 1449 done = 0; 1450 1451 if (t1 == 0x456789ab) { 1452 if (t0 == 0x01234567) { 1453 *chab = 0; *bw = 64; 1454 done = 1; 1455 } 1456 } else { 1457 if (t0 == 0x01234567) { 1458 *chab = 0; *bw = 32; 1459 ret |= SETIREG(SISSR, 0x14, 0x00); 1460 done = 1; 1461 } 1462 } 1463 1464 if (!done) { 1465 ret |= SETIREG(SISSR, 0x14, 0x03); 1466 ret |= sisusb_triggersr16(sisusb, ramtype); 1467 1468 ret |= WRITEL(ramptr + 0, 0x01234567); 1469 ret |= WRITEL(ramptr + 4, 0x456789ab); 1470 ret |= WRITEL(ramptr + 8, 0x89abcdef); 1471 ret |= WRITEL(ramptr + 12, 0xcdef0123); 1472 ret |= WRITEL(ramptr + 16, 0x55555555); 1473 ret |= WRITEL(ramptr + 20, 0x55555555); 1474 ret |= WRITEL(ramptr + 24, 0xffffffff); 1475 ret |= WRITEL(ramptr + 28, 0xffffffff); 1476 ret |= READL(ramptr + 0, &t0); 1477 ret |= READL(ramptr + 4, &t1); 1478 1479 if (t1 == 0x456789ab) { 1480 if (t0 == 0x01234567) { 1481 *chab = 1; *bw = 64; 1482 return ret; 1483 } /* else error */ 1484 } else { 1485 if (t0 == 0x01234567) { 1486 *chab = 1; *bw = 32; 1487 ret |= SETIREG(SISSR, 0x14, 0x01); 1488 } /* else error */ 1489 } 1490 } 1491 } 1492 return ret; 1493 } 1494 1495 static int sisusb_verify_mclk(struct sisusb_usb_data *sisusb) 1496 { 1497 int ret = 0; 1498 u32 ramptr = SISUSB_PCI_MEMBASE; 1499 u8 tmp1, tmp2, i, j; 1500 1501 ret |= WRITEB(ramptr, 0xaa); 1502 ret |= WRITEB(ramptr + 16, 0x55); 1503 ret |= READB(ramptr, &tmp1); 1504 ret |= READB(ramptr + 16, &tmp2); 1505 if ((tmp1 != 0xaa) || (tmp2 != 0x55)) { 1506 for (i = 0, j = 16; i < 2; i++, j += 16) { 1507 ret |= GETIREG(SISSR, 0x21, &tmp1); 1508 ret |= SETIREGAND(SISSR, 0x21, (tmp1 & 0xfb)); 1509 ret |= SETIREGOR(SISSR, 0x3c, 0x01); /* not on 330 */ 1510 ret |= SETIREGAND(SISSR, 0x3c, 0xfe); /* not on 330 */ 1511 ret |= SETIREG(SISSR, 0x21, tmp1); 1512 ret |= WRITEB(ramptr + 16 + j, j); 1513 ret |= READB(ramptr + 16 + j, &tmp1); 1514 if (tmp1 == j) { 1515 ret |= WRITEB(ramptr + j, j); 1516 break; 1517 } 1518 } 1519 } 1520 return ret; 1521 } 1522 1523 static int sisusb_set_rank(struct sisusb_usb_data *sisusb, int *iret, 1524 int index, u8 rankno, u8 chab, const u8 dramtype[][5], int bw) 1525 { 1526 int ret = 0, ranksize; 1527 u8 tmp; 1528 1529 *iret = 0; 1530 1531 if ((rankno == 2) && (dramtype[index][0] == 2)) 1532 return ret; 1533 1534 ranksize = dramtype[index][3] / 2 * bw / 32; 1535 1536 if ((ranksize * rankno) > 128) 1537 return ret; 1538 1539 tmp = 0; 1540 while ((ranksize >>= 1) > 0) 1541 tmp += 0x10; 1542 1543 tmp |= ((rankno - 1) << 2); 1544 tmp |= ((bw / 64) & 0x02); 1545 tmp |= (chab & 0x01); 1546 1547 ret = SETIREG(SISSR, 0x14, tmp); 1548 ret |= sisusb_triggersr16(sisusb, 0); /* sic! */ 1549 1550 *iret = 1; 1551 1552 return ret; 1553 } 1554 1555 static int sisusb_check_rbc(struct sisusb_usb_data *sisusb, int *iret, 1556 u32 inc, int testn) 1557 { 1558 int ret = 0, i; 1559 u32 j, tmp; 1560 1561 *iret = 0; 1562 1563 for (i = 0, j = 0; i < testn; i++) { 1564 ret |= WRITEL(sisusb->vrambase + j, j); 1565 j += inc; 1566 } 1567 1568 for (i = 0, j = 0; i < testn; i++) { 1569 ret |= READL(sisusb->vrambase + j, &tmp); 1570 if (tmp != j) 1571 return ret; 1572 1573 j += inc; 1574 } 1575 1576 *iret = 1; 1577 return ret; 1578 } 1579 1580 static int sisusb_check_ranks(struct sisusb_usb_data *sisusb, 1581 int *iret, int rankno, int idx, int bw, const u8 rtype[][5]) 1582 { 1583 int ret = 0, i, i2ret; 1584 u32 inc; 1585 1586 *iret = 0; 1587 1588 for (i = rankno; i >= 1; i--) { 1589 inc = 1 << (rtype[idx][2] + rtype[idx][1] + rtype[idx][0] + 1590 bw / 64 + i); 1591 ret |= sisusb_check_rbc(sisusb, &i2ret, inc, 2); 1592 if (!i2ret) 1593 return ret; 1594 } 1595 1596 inc = 1 << (rtype[idx][2] + bw / 64 + 2); 1597 ret |= sisusb_check_rbc(sisusb, &i2ret, inc, 4); 1598 if (!i2ret) 1599 return ret; 1600 1601 inc = 1 << (10 + bw / 64); 1602 ret |= sisusb_check_rbc(sisusb, &i2ret, inc, 2); 1603 if (!i2ret) 1604 return ret; 1605 1606 *iret = 1; 1607 return ret; 1608 } 1609 1610 static int sisusb_get_sdram_size(struct sisusb_usb_data *sisusb, int *iret, 1611 int bw, int chab) 1612 { 1613 int ret = 0, i2ret = 0, i, j; 1614 static const u8 sdramtype[13][5] = { 1615 { 2, 12, 9, 64, 0x35 }, 1616 { 1, 13, 9, 64, 0x44 }, 1617 { 2, 12, 8, 32, 0x31 }, 1618 { 2, 11, 9, 32, 0x25 }, 1619 { 1, 12, 9, 32, 0x34 }, 1620 { 1, 13, 8, 32, 0x40 }, 1621 { 2, 11, 8, 16, 0x21 }, 1622 { 1, 12, 8, 16, 0x30 }, 1623 { 1, 11, 9, 16, 0x24 }, 1624 { 1, 11, 8, 8, 0x20 }, 1625 { 2, 9, 8, 4, 0x01 }, 1626 { 1, 10, 8, 4, 0x10 }, 1627 { 1, 9, 8, 2, 0x00 } 1628 }; 1629 1630 *iret = 1; /* error */ 1631 1632 for (i = 0; i < 13; i++) { 1633 ret |= SETIREGANDOR(SISSR, 0x13, 0x80, sdramtype[i][4]); 1634 for (j = 2; j > 0; j--) { 1635 ret |= sisusb_set_rank(sisusb, &i2ret, i, j, chab, 1636 sdramtype, bw); 1637 if (!i2ret) 1638 continue; 1639 1640 ret |= sisusb_check_ranks(sisusb, &i2ret, j, i, bw, 1641 sdramtype); 1642 if (i2ret) { 1643 *iret = 0; /* ram size found */ 1644 return ret; 1645 } 1646 } 1647 } 1648 1649 return ret; 1650 } 1651 1652 static int sisusb_setup_screen(struct sisusb_usb_data *sisusb, 1653 int clrall, int drwfr) 1654 { 1655 int ret = 0; 1656 u32 address; 1657 int i, length, modex, modey, bpp; 1658 1659 modex = 640; modey = 480; bpp = 2; 1660 1661 address = sisusb->vrambase; /* Clear video ram */ 1662 1663 if (clrall) 1664 length = sisusb->vramsize; 1665 else 1666 length = modex * bpp * modey; 1667 1668 ret = sisusb_clear_vram(sisusb, address, length); 1669 1670 if (!ret && drwfr) { 1671 for (i = 0; i < modex; i++) { 1672 address = sisusb->vrambase + (i * bpp); 1673 ret |= sisusb_write_memio_word(sisusb, SISUSB_TYPE_MEM, 1674 address, 0xf100); 1675 address += (modex * (modey-1) * bpp); 1676 ret |= sisusb_write_memio_word(sisusb, SISUSB_TYPE_MEM, 1677 address, 0xf100); 1678 } 1679 for (i = 0; i < modey; i++) { 1680 address = sisusb->vrambase + ((i * modex) * bpp); 1681 ret |= sisusb_write_memio_word(sisusb, SISUSB_TYPE_MEM, 1682 address, 0xf100); 1683 address += ((modex - 1) * bpp); 1684 ret |= sisusb_write_memio_word(sisusb, SISUSB_TYPE_MEM, 1685 address, 0xf100); 1686 } 1687 } 1688 1689 return ret; 1690 } 1691 1692 static void sisusb_set_default_mode(struct sisusb_usb_data *sisusb, 1693 int touchengines) 1694 { 1695 int i, j, modex, bpp, du; 1696 u8 sr31, cr63, tmp8; 1697 static const char attrdata[] = { 1698 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 1699 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 1700 0x01, 0x00, 0x00, 0x00 1701 }; 1702 static const char crtcrdata[] = { 1703 0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0x0b, 0x3e, 1704 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 1705 0xea, 0x8c, 0xdf, 0x28, 0x40, 0xe7, 0x04, 0xa3, 1706 0xff 1707 }; 1708 static const char grcdata[] = { 1709 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0f, 1710 0xff 1711 }; 1712 static const char crtcdata[] = { 1713 0x5f, 0x4f, 0x4f, 0x83, 0x55, 0x81, 0x0b, 0x3e, 1714 0xe9, 0x8b, 0xdf, 0xe8, 0x0c, 0x00, 0x00, 0x05, 1715 0x00 1716 }; 1717 1718 modex = 640; bpp = 2; 1719 1720 GETIREG(SISSR, 0x31, &sr31); 1721 GETIREG(SISCR, 0x63, &cr63); 1722 SETIREGOR(SISSR, 0x01, 0x20); 1723 SETIREG(SISCR, 0x63, cr63 & 0xbf); 1724 SETIREGOR(SISCR, 0x17, 0x80); 1725 SETIREGOR(SISSR, 0x1f, 0x04); 1726 SETIREGAND(SISSR, 0x07, 0xfb); 1727 SETIREG(SISSR, 0x00, 0x03); /* seq */ 1728 SETIREG(SISSR, 0x01, 0x21); 1729 SETIREG(SISSR, 0x02, 0x0f); 1730 SETIREG(SISSR, 0x03, 0x00); 1731 SETIREG(SISSR, 0x04, 0x0e); 1732 SETREG(SISMISCW, 0x23); /* misc */ 1733 for (i = 0; i <= 0x18; i++) { /* crtc */ 1734 SETIREG(SISCR, i, crtcrdata[i]); 1735 } 1736 for (i = 0; i <= 0x13; i++) { /* att */ 1737 GETREG(SISINPSTAT, &tmp8); 1738 SETREG(SISAR, i); 1739 SETREG(SISAR, attrdata[i]); 1740 } 1741 GETREG(SISINPSTAT, &tmp8); 1742 SETREG(SISAR, 0x14); 1743 SETREG(SISAR, 0x00); 1744 GETREG(SISINPSTAT, &tmp8); 1745 SETREG(SISAR, 0x20); 1746 GETREG(SISINPSTAT, &tmp8); 1747 for (i = 0; i <= 0x08; i++) { /* grc */ 1748 SETIREG(SISGR, i, grcdata[i]); 1749 } 1750 SETIREGAND(SISGR, 0x05, 0xbf); 1751 for (i = 0x0A; i <= 0x0E; i++) { /* clr ext */ 1752 SETIREG(SISSR, i, 0x00); 1753 } 1754 SETIREGAND(SISSR, 0x37, 0xfe); 1755 SETREG(SISMISCW, 0xef); /* sync */ 1756 SETIREG(SISCR, 0x11, 0x00); /* crtc */ 1757 for (j = 0x00, i = 0; i <= 7; i++, j++) 1758 SETIREG(SISCR, j, crtcdata[i]); 1759 1760 for (j = 0x10; i <= 10; i++, j++) 1761 SETIREG(SISCR, j, crtcdata[i]); 1762 1763 for (j = 0x15; i <= 12; i++, j++) 1764 SETIREG(SISCR, j, crtcdata[i]); 1765 1766 for (j = 0x0A; i <= 15; i++, j++) 1767 SETIREG(SISSR, j, crtcdata[i]); 1768 1769 SETIREG(SISSR, 0x0E, (crtcdata[16] & 0xE0)); 1770 SETIREGANDOR(SISCR, 0x09, 0x5f, ((crtcdata[16] & 0x01) << 5)); 1771 SETIREG(SISCR, 0x14, 0x4f); 1772 du = (modex / 16) * (bpp * 2); /* offset/pitch */ 1773 SETIREGANDOR(SISSR, 0x0e, 0xf0, ((du >> 8) & 0x0f)); 1774 SETIREG(SISCR, 0x13, (du & 0xff)); 1775 du <<= 5; 1776 tmp8 = du >> 8; 1777 SETIREG(SISSR, 0x10, tmp8); 1778 SETIREG(SISSR, 0x31, 0x00); /* VCLK */ 1779 SETIREG(SISSR, 0x2b, 0x1b); 1780 SETIREG(SISSR, 0x2c, 0xe1); 1781 SETIREG(SISSR, 0x2d, 0x01); 1782 SETIREGAND(SISSR, 0x3d, 0xfe); /* FIFO */ 1783 SETIREG(SISSR, 0x08, 0xae); 1784 SETIREGAND(SISSR, 0x09, 0xf0); 1785 SETIREG(SISSR, 0x08, 0x34); 1786 SETIREGOR(SISSR, 0x3d, 0x01); 1787 SETIREGAND(SISSR, 0x1f, 0x3f); /* mode regs */ 1788 SETIREGANDOR(SISSR, 0x06, 0xc0, 0x0a); 1789 SETIREG(SISCR, 0x19, 0x00); 1790 SETIREGAND(SISCR, 0x1a, 0xfc); 1791 SETIREGAND(SISSR, 0x0f, 0xb7); 1792 SETIREGAND(SISSR, 0x31, 0xfb); 1793 SETIREGANDOR(SISSR, 0x21, 0x1f, 0xa0); 1794 SETIREGAND(SISSR, 0x32, 0xf3); 1795 SETIREGANDOR(SISSR, 0x07, 0xf8, 0x03); 1796 SETIREG(SISCR, 0x52, 0x6c); 1797 1798 SETIREG(SISCR, 0x0d, 0x00); /* adjust frame */ 1799 SETIREG(SISCR, 0x0c, 0x00); 1800 SETIREG(SISSR, 0x0d, 0x00); 1801 SETIREGAND(SISSR, 0x37, 0xfe); 1802 1803 SETIREG(SISCR, 0x32, 0x20); 1804 SETIREGAND(SISSR, 0x01, 0xdf); /* enable display */ 1805 SETIREG(SISCR, 0x63, (cr63 & 0xbf)); 1806 SETIREG(SISSR, 0x31, (sr31 & 0xfb)); 1807 1808 if (touchengines) { 1809 SETIREG(SISSR, 0x20, 0xa1); /* enable engines */ 1810 SETIREGOR(SISSR, 0x1e, 0x5a); 1811 1812 SETIREG(SISSR, 0x26, 0x01); /* disable cmdqueue */ 1813 SETIREG(SISSR, 0x27, 0x1f); 1814 SETIREG(SISSR, 0x26, 0x00); 1815 } 1816 1817 SETIREG(SISCR, 0x34, 0x44); /* we just set std mode #44 */ 1818 } 1819 1820 static int sisusb_init_gfxcore(struct sisusb_usb_data *sisusb) 1821 { 1822 int ret = 0, i, j, bw, chab, iret, retry = 3; 1823 u8 tmp8, ramtype; 1824 u32 tmp32; 1825 static const char mclktable[] = { 1826 0x3b, 0x22, 0x01, 143, 1827 0x3b, 0x22, 0x01, 143, 1828 0x3b, 0x22, 0x01, 143, 1829 0x3b, 0x22, 0x01, 143 1830 }; 1831 static const char eclktable[] = { 1832 0x3b, 0x22, 0x01, 143, 1833 0x3b, 0x22, 0x01, 143, 1834 0x3b, 0x22, 0x01, 143, 1835 0x3b, 0x22, 0x01, 143 1836 }; 1837 static const char ramtypetable1[] = { 1838 0x00, 0x04, 0x60, 0x60, 1839 0x0f, 0x0f, 0x1f, 0x1f, 1840 0xba, 0xba, 0xba, 0xba, 1841 0xa9, 0xa9, 0xac, 0xac, 1842 0xa0, 0xa0, 0xa0, 0xa8, 1843 0x00, 0x00, 0x02, 0x02, 1844 0x30, 0x30, 0x40, 0x40 1845 }; 1846 static const char ramtypetable2[] = { 1847 0x77, 0x77, 0x44, 0x44, 1848 0x77, 0x77, 0x44, 0x44, 1849 0x00, 0x00, 0x00, 0x00, 1850 0x5b, 0x5b, 0xab, 0xab, 1851 0x00, 0x00, 0xf0, 0xf8 1852 }; 1853 1854 while (retry--) { 1855 1856 /* Enable VGA */ 1857 ret = GETREG(SISVGAEN, &tmp8); 1858 ret |= SETREG(SISVGAEN, (tmp8 | 0x01)); 1859 1860 /* Enable GPU access to VRAM */ 1861 ret |= GETREG(SISMISCR, &tmp8); 1862 ret |= SETREG(SISMISCW, (tmp8 | 0x01)); 1863 1864 if (ret) 1865 continue; 1866 1867 /* Reset registers */ 1868 ret |= SETIREGAND(SISCR, 0x5b, 0xdf); 1869 ret |= SETIREG(SISSR, 0x05, 0x86); 1870 ret |= SETIREGOR(SISSR, 0x20, 0x01); 1871 1872 ret |= SETREG(SISMISCW, 0x67); 1873 1874 for (i = 0x06; i <= 0x1f; i++) 1875 ret |= SETIREG(SISSR, i, 0x00); 1876 1877 for (i = 0x21; i <= 0x27; i++) 1878 ret |= SETIREG(SISSR, i, 0x00); 1879 1880 for (i = 0x31; i <= 0x3d; i++) 1881 ret |= SETIREG(SISSR, i, 0x00); 1882 1883 for (i = 0x12; i <= 0x1b; i++) 1884 ret |= SETIREG(SISSR, i, 0x00); 1885 1886 for (i = 0x79; i <= 0x7c; i++) 1887 ret |= SETIREG(SISCR, i, 0x00); 1888 1889 if (ret) 1890 continue; 1891 1892 ret |= SETIREG(SISCR, 0x63, 0x80); 1893 1894 ret |= GETIREG(SISSR, 0x3a, &ramtype); 1895 ramtype &= 0x03; 1896 1897 ret |= SETIREG(SISSR, 0x28, mclktable[ramtype * 4]); 1898 ret |= SETIREG(SISSR, 0x29, mclktable[(ramtype * 4) + 1]); 1899 ret |= SETIREG(SISSR, 0x2a, mclktable[(ramtype * 4) + 2]); 1900 1901 ret |= SETIREG(SISSR, 0x2e, eclktable[ramtype * 4]); 1902 ret |= SETIREG(SISSR, 0x2f, eclktable[(ramtype * 4) + 1]); 1903 ret |= SETIREG(SISSR, 0x30, eclktable[(ramtype * 4) + 2]); 1904 1905 ret |= SETIREG(SISSR, 0x07, 0x18); 1906 ret |= SETIREG(SISSR, 0x11, 0x0f); 1907 1908 if (ret) 1909 continue; 1910 1911 for (i = 0x15, j = 0; i <= 0x1b; i++, j++) { 1912 ret |= SETIREG(SISSR, i, 1913 ramtypetable1[(j*4) + ramtype]); 1914 } 1915 for (i = 0x40, j = 0; i <= 0x44; i++, j++) { 1916 ret |= SETIREG(SISCR, i, 1917 ramtypetable2[(j*4) + ramtype]); 1918 } 1919 1920 ret |= SETIREG(SISCR, 0x49, 0xaa); 1921 1922 ret |= SETIREG(SISSR, 0x1f, 0x00); 1923 ret |= SETIREG(SISSR, 0x20, 0xa0); 1924 ret |= SETIREG(SISSR, 0x23, 0xf6); 1925 ret |= SETIREG(SISSR, 0x24, 0x0d); 1926 ret |= SETIREG(SISSR, 0x25, 0x33); 1927 1928 ret |= SETIREG(SISSR, 0x11, 0x0f); 1929 1930 ret |= SETIREGOR(SISPART1, 0x2f, 0x01); 1931 1932 ret |= SETIREGAND(SISCAP, 0x3f, 0xef); 1933 1934 if (ret) 1935 continue; 1936 1937 ret |= SETIREG(SISPART1, 0x00, 0x00); 1938 1939 ret |= GETIREG(SISSR, 0x13, &tmp8); 1940 tmp8 >>= 4; 1941 1942 ret |= SETIREG(SISPART1, 0x02, 0x00); 1943 ret |= SETIREG(SISPART1, 0x2e, 0x08); 1944 1945 ret |= sisusb_read_pci_config(sisusb, 0x50, &tmp32); 1946 tmp32 &= 0x00f00000; 1947 tmp8 = (tmp32 == 0x100000) ? 0x33 : 0x03; 1948 ret |= SETIREG(SISSR, 0x25, tmp8); 1949 tmp8 = (tmp32 == 0x100000) ? 0xaa : 0x88; 1950 ret |= SETIREG(SISCR, 0x49, tmp8); 1951 1952 ret |= SETIREG(SISSR, 0x27, 0x1f); 1953 ret |= SETIREG(SISSR, 0x31, 0x00); 1954 ret |= SETIREG(SISSR, 0x32, 0x11); 1955 ret |= SETIREG(SISSR, 0x33, 0x00); 1956 1957 if (ret) 1958 continue; 1959 1960 ret |= SETIREG(SISCR, 0x83, 0x00); 1961 1962 sisusb_set_default_mode(sisusb, 0); 1963 1964 ret |= SETIREGAND(SISSR, 0x21, 0xdf); 1965 ret |= SETIREGOR(SISSR, 0x01, 0x20); 1966 ret |= SETIREGOR(SISSR, 0x16, 0x0f); 1967 1968 ret |= sisusb_triggersr16(sisusb, ramtype); 1969 1970 /* Disable refresh */ 1971 ret |= SETIREGAND(SISSR, 0x17, 0xf8); 1972 ret |= SETIREGOR(SISSR, 0x19, 0x03); 1973 1974 ret |= sisusb_getbuswidth(sisusb, &bw, &chab); 1975 ret |= sisusb_verify_mclk(sisusb); 1976 1977 if (ramtype <= 1) { 1978 ret |= sisusb_get_sdram_size(sisusb, &iret, bw, chab); 1979 if (iret) { 1980 dev_err(&sisusb->sisusb_dev->dev, 1981 "RAM size detection failed, assuming 8MB video RAM\n"); 1982 ret |= SETIREG(SISSR, 0x14, 0x31); 1983 /* TODO */ 1984 } 1985 } else { 1986 dev_err(&sisusb->sisusb_dev->dev, 1987 "DDR RAM device found, assuming 8MB video RAM\n"); 1988 ret |= SETIREG(SISSR, 0x14, 0x31); 1989 /* *** TODO *** */ 1990 } 1991 1992 /* Enable refresh */ 1993 ret |= SETIREG(SISSR, 0x16, ramtypetable1[4 + ramtype]); 1994 ret |= SETIREG(SISSR, 0x17, ramtypetable1[8 + ramtype]); 1995 ret |= SETIREG(SISSR, 0x19, ramtypetable1[16 + ramtype]); 1996 1997 ret |= SETIREGOR(SISSR, 0x21, 0x20); 1998 1999 ret |= SETIREG(SISSR, 0x22, 0xfb); 2000 ret |= SETIREG(SISSR, 0x21, 0xa5); 2001 2002 if (ret == 0) 2003 break; 2004 } 2005 2006 return ret; 2007 } 2008 2009 #undef SETREG 2010 #undef GETREG 2011 #undef SETIREG 2012 #undef GETIREG 2013 #undef SETIREGOR 2014 #undef SETIREGAND 2015 #undef SETIREGANDOR 2016 #undef READL 2017 #undef WRITEL 2018 2019 static void sisusb_get_ramconfig(struct sisusb_usb_data *sisusb) 2020 { 2021 u8 tmp8, tmp82, ramtype; 2022 int bw = 0; 2023 char *ramtypetext1 = NULL; 2024 static const char ram_datarate[4] = {'S', 'S', 'D', 'D'}; 2025 static const char ram_dynamictype[4] = {'D', 'G', 'D', 'G'}; 2026 static const int busSDR[4] = {64, 64, 128, 128}; 2027 static const int busDDR[4] = {32, 32, 64, 64}; 2028 static const int busDDRA[4] = {64+32, 64+32, (64+32)*2, (64+32)*2}; 2029 2030 sisusb_getidxreg(sisusb, SISSR, 0x14, &tmp8); 2031 sisusb_getidxreg(sisusb, SISSR, 0x15, &tmp82); 2032 sisusb_getidxreg(sisusb, SISSR, 0x3a, &ramtype); 2033 sisusb->vramsize = (1 << ((tmp8 & 0xf0) >> 4)) * 1024 * 1024; 2034 ramtype &= 0x03; 2035 switch ((tmp8 >> 2) & 0x03) { 2036 case 0: 2037 ramtypetext1 = "1 ch/1 r"; 2038 if (tmp82 & 0x10) 2039 bw = 32; 2040 else 2041 bw = busSDR[(tmp8 & 0x03)]; 2042 2043 break; 2044 case 1: 2045 ramtypetext1 = "1 ch/2 r"; 2046 sisusb->vramsize <<= 1; 2047 bw = busSDR[(tmp8 & 0x03)]; 2048 break; 2049 case 2: 2050 ramtypetext1 = "asymmetric"; 2051 sisusb->vramsize += sisusb->vramsize/2; 2052 bw = busDDRA[(tmp8 & 0x03)]; 2053 break; 2054 case 3: 2055 ramtypetext1 = "2 channel"; 2056 sisusb->vramsize <<= 1; 2057 bw = busDDR[(tmp8 & 0x03)]; 2058 break; 2059 } 2060 2061 dev_info(&sisusb->sisusb_dev->dev, 2062 "%dMB %s %cDR S%cRAM, bus width %d\n", 2063 sisusb->vramsize >> 20, ramtypetext1, 2064 ram_datarate[ramtype], ram_dynamictype[ramtype], bw); 2065 } 2066 2067 static int sisusb_do_init_gfxdevice(struct sisusb_usb_data *sisusb) 2068 { 2069 struct sisusb_packet packet; 2070 int ret; 2071 u32 tmp32; 2072 2073 /* Do some magic */ 2074 packet.header = 0x001f; 2075 packet.address = 0x00000324; 2076 packet.data = 0x00000004; 2077 ret = sisusb_send_bridge_packet(sisusb, 10, &packet, 0); 2078 2079 packet.header = 0x001f; 2080 packet.address = 0x00000364; 2081 packet.data = 0x00000004; 2082 ret |= sisusb_send_bridge_packet(sisusb, 10, &packet, 0); 2083 2084 packet.header = 0x001f; 2085 packet.address = 0x00000384; 2086 packet.data = 0x00000004; 2087 ret |= sisusb_send_bridge_packet(sisusb, 10, &packet, 0); 2088 2089 packet.header = 0x001f; 2090 packet.address = 0x00000100; 2091 packet.data = 0x00000700; 2092 ret |= sisusb_send_bridge_packet(sisusb, 10, &packet, 0); 2093 2094 packet.header = 0x000f; 2095 packet.address = 0x00000004; 2096 ret |= sisusb_send_bridge_packet(sisusb, 6, &packet, 0); 2097 packet.data |= 0x17; 2098 ret |= sisusb_send_bridge_packet(sisusb, 10, &packet, 0); 2099 2100 /* Init BAR 0 (VRAM) */ 2101 ret |= sisusb_read_pci_config(sisusb, 0x10, &tmp32); 2102 ret |= sisusb_write_pci_config(sisusb, 0x10, 0xfffffff0); 2103 ret |= sisusb_read_pci_config(sisusb, 0x10, &tmp32); 2104 tmp32 &= 0x0f; 2105 tmp32 |= SISUSB_PCI_MEMBASE; 2106 ret |= sisusb_write_pci_config(sisusb, 0x10, tmp32); 2107 2108 /* Init BAR 1 (MMIO) */ 2109 ret |= sisusb_read_pci_config(sisusb, 0x14, &tmp32); 2110 ret |= sisusb_write_pci_config(sisusb, 0x14, 0xfffffff0); 2111 ret |= sisusb_read_pci_config(sisusb, 0x14, &tmp32); 2112 tmp32 &= 0x0f; 2113 tmp32 |= SISUSB_PCI_MMIOBASE; 2114 ret |= sisusb_write_pci_config(sisusb, 0x14, tmp32); 2115 2116 /* Init BAR 2 (i/o ports) */ 2117 ret |= sisusb_read_pci_config(sisusb, 0x18, &tmp32); 2118 ret |= sisusb_write_pci_config(sisusb, 0x18, 0xfffffff0); 2119 ret |= sisusb_read_pci_config(sisusb, 0x18, &tmp32); 2120 tmp32 &= 0x0f; 2121 tmp32 |= SISUSB_PCI_IOPORTBASE; 2122 ret |= sisusb_write_pci_config(sisusb, 0x18, tmp32); 2123 2124 /* Enable memory and i/o access */ 2125 ret |= sisusb_read_pci_config(sisusb, 0x04, &tmp32); 2126 tmp32 |= 0x3; 2127 ret |= sisusb_write_pci_config(sisusb, 0x04, tmp32); 2128 2129 if (ret == 0) { 2130 /* Some further magic */ 2131 packet.header = 0x001f; 2132 packet.address = 0x00000050; 2133 packet.data = 0x000000ff; 2134 ret |= sisusb_send_bridge_packet(sisusb, 10, &packet, 0); 2135 } 2136 2137 return ret; 2138 } 2139 2140 /* Initialize the graphics device (return 0 on success) 2141 * This initializes the net2280 as well as the PCI registers 2142 * of the graphics board. 2143 */ 2144 2145 static int sisusb_init_gfxdevice(struct sisusb_usb_data *sisusb, int initscreen) 2146 { 2147 int ret = 0, test = 0; 2148 u32 tmp32; 2149 2150 if (sisusb->devinit == 1) { 2151 /* Read PCI BARs and see if they have been set up */ 2152 ret |= sisusb_read_pci_config(sisusb, 0x10, &tmp32); 2153 if (ret) 2154 return ret; 2155 2156 if ((tmp32 & 0xfffffff0) == SISUSB_PCI_MEMBASE) 2157 test++; 2158 2159 ret |= sisusb_read_pci_config(sisusb, 0x14, &tmp32); 2160 if (ret) 2161 return ret; 2162 2163 if ((tmp32 & 0xfffffff0) == SISUSB_PCI_MMIOBASE) 2164 test++; 2165 2166 ret |= sisusb_read_pci_config(sisusb, 0x18, &tmp32); 2167 if (ret) 2168 return ret; 2169 2170 if ((tmp32 & 0xfffffff0) == SISUSB_PCI_IOPORTBASE) 2171 test++; 2172 } 2173 2174 /* No? So reset the device */ 2175 if ((sisusb->devinit == 0) || (test != 3)) { 2176 2177 ret |= sisusb_do_init_gfxdevice(sisusb); 2178 2179 if (ret == 0) 2180 sisusb->devinit = 1; 2181 2182 } 2183 2184 if (sisusb->devinit) { 2185 /* Initialize the graphics core */ 2186 if (sisusb_init_gfxcore(sisusb) == 0) { 2187 sisusb->gfxinit = 1; 2188 sisusb_get_ramconfig(sisusb); 2189 sisusb_set_default_mode(sisusb, 1); 2190 ret |= sisusb_setup_screen(sisusb, 1, initscreen); 2191 } 2192 } 2193 2194 return ret; 2195 } 2196 2197 /* fops */ 2198 2199 static int sisusb_open(struct inode *inode, struct file *file) 2200 { 2201 struct sisusb_usb_data *sisusb; 2202 struct usb_interface *interface; 2203 int subminor = iminor(inode); 2204 2205 interface = usb_find_interface(&sisusb_driver, subminor); 2206 if (!interface) 2207 return -ENODEV; 2208 2209 sisusb = usb_get_intfdata(interface); 2210 if (!sisusb) 2211 return -ENODEV; 2212 2213 mutex_lock(&sisusb->lock); 2214 2215 if (!sisusb->present || !sisusb->ready) { 2216 mutex_unlock(&sisusb->lock); 2217 return -ENODEV; 2218 } 2219 2220 if (sisusb->isopen) { 2221 mutex_unlock(&sisusb->lock); 2222 return -EBUSY; 2223 } 2224 2225 if (!sisusb->devinit) { 2226 if (sisusb->sisusb_dev->speed == USB_SPEED_HIGH || 2227 sisusb->sisusb_dev->speed >= USB_SPEED_SUPER) { 2228 if (sisusb_init_gfxdevice(sisusb, 0)) { 2229 mutex_unlock(&sisusb->lock); 2230 dev_err(&sisusb->sisusb_dev->dev, 2231 "Failed to initialize device\n"); 2232 return -EIO; 2233 } 2234 } else { 2235 mutex_unlock(&sisusb->lock); 2236 dev_err(&sisusb->sisusb_dev->dev, 2237 "Device not attached to USB 2.0 hub\n"); 2238 return -EIO; 2239 } 2240 } 2241 2242 /* Increment usage count for our sisusb */ 2243 kref_get(&sisusb->kref); 2244 2245 sisusb->isopen = 1; 2246 2247 file->private_data = sisusb; 2248 2249 mutex_unlock(&sisusb->lock); 2250 2251 return 0; 2252 } 2253 2254 static void sisusb_delete(struct kref *kref) 2255 { 2256 struct sisusb_usb_data *sisusb = to_sisusb_dev(kref); 2257 2258 if (!sisusb) 2259 return; 2260 2261 usb_put_dev(sisusb->sisusb_dev); 2262 2263 sisusb->sisusb_dev = NULL; 2264 sisusb_free_buffers(sisusb); 2265 sisusb_free_urbs(sisusb); 2266 kfree(sisusb); 2267 } 2268 2269 static int sisusb_release(struct inode *inode, struct file *file) 2270 { 2271 struct sisusb_usb_data *sisusb; 2272 2273 sisusb = file->private_data; 2274 if (!sisusb) 2275 return -ENODEV; 2276 2277 mutex_lock(&sisusb->lock); 2278 2279 if (sisusb->present) { 2280 /* Wait for all URBs to finish if device still present */ 2281 if (!sisusb_wait_all_out_complete(sisusb)) 2282 sisusb_kill_all_busy(sisusb); 2283 } 2284 2285 sisusb->isopen = 0; 2286 file->private_data = NULL; 2287 2288 mutex_unlock(&sisusb->lock); 2289 2290 /* decrement the usage count on our device */ 2291 kref_put(&sisusb->kref, sisusb_delete); 2292 2293 return 0; 2294 } 2295 2296 static ssize_t sisusb_read(struct file *file, char __user *buffer, 2297 size_t count, loff_t *ppos) 2298 { 2299 struct sisusb_usb_data *sisusb; 2300 ssize_t bytes_read = 0; 2301 int errno = 0; 2302 u8 buf8; 2303 u16 buf16; 2304 u32 buf32, address; 2305 2306 sisusb = file->private_data; 2307 if (!sisusb) 2308 return -ENODEV; 2309 2310 mutex_lock(&sisusb->lock); 2311 2312 /* Sanity check */ 2313 if (!sisusb->present || !sisusb->ready || !sisusb->sisusb_dev) { 2314 mutex_unlock(&sisusb->lock); 2315 return -ENODEV; 2316 } 2317 2318 if ((*ppos) >= SISUSB_PCI_PSEUDO_IOPORTBASE && 2319 (*ppos) < SISUSB_PCI_PSEUDO_IOPORTBASE + 128) { 2320 2321 address = (*ppos) - SISUSB_PCI_PSEUDO_IOPORTBASE + 2322 SISUSB_PCI_IOPORTBASE; 2323 2324 /* Read i/o ports 2325 * Byte, word and long(32) can be read. As this 2326 * emulates inX instructions, the data returned is 2327 * in machine-endianness. 2328 */ 2329 switch (count) { 2330 case 1: 2331 if (sisusb_read_memio_byte(sisusb, SISUSB_TYPE_IO, 2332 address, &buf8)) 2333 errno = -EIO; 2334 else if (put_user(buf8, (u8 __user *)buffer)) 2335 errno = -EFAULT; 2336 else 2337 bytes_read = 1; 2338 2339 break; 2340 2341 case 2: 2342 if (sisusb_read_memio_word(sisusb, SISUSB_TYPE_IO, 2343 address, &buf16)) 2344 errno = -EIO; 2345 else if (put_user(buf16, (u16 __user *)buffer)) 2346 errno = -EFAULT; 2347 else 2348 bytes_read = 2; 2349 2350 break; 2351 2352 case 4: 2353 if (sisusb_read_memio_long(sisusb, SISUSB_TYPE_IO, 2354 address, &buf32)) 2355 errno = -EIO; 2356 else if (put_user(buf32, (u32 __user *)buffer)) 2357 errno = -EFAULT; 2358 else 2359 bytes_read = 4; 2360 2361 break; 2362 2363 default: 2364 errno = -EIO; 2365 2366 } 2367 2368 } else if ((*ppos) >= SISUSB_PCI_PSEUDO_MEMBASE && (*ppos) < 2369 SISUSB_PCI_PSEUDO_MEMBASE + sisusb->vramsize) { 2370 2371 address = (*ppos) - SISUSB_PCI_PSEUDO_MEMBASE + 2372 SISUSB_PCI_MEMBASE; 2373 2374 /* Read video ram 2375 * Remember: Data delivered is never endian-corrected 2376 */ 2377 errno = sisusb_read_mem_bulk(sisusb, address, 2378 NULL, count, buffer, &bytes_read); 2379 2380 if (bytes_read) 2381 errno = bytes_read; 2382 2383 } else if ((*ppos) >= SISUSB_PCI_PSEUDO_MMIOBASE && 2384 (*ppos) < SISUSB_PCI_PSEUDO_MMIOBASE + 2385 SISUSB_PCI_MMIOSIZE) { 2386 2387 address = (*ppos) - SISUSB_PCI_PSEUDO_MMIOBASE + 2388 SISUSB_PCI_MMIOBASE; 2389 2390 /* Read MMIO 2391 * Remember: Data delivered is never endian-corrected 2392 */ 2393 errno = sisusb_read_mem_bulk(sisusb, address, 2394 NULL, count, buffer, &bytes_read); 2395 2396 if (bytes_read) 2397 errno = bytes_read; 2398 2399 } else if ((*ppos) >= SISUSB_PCI_PSEUDO_PCIBASE && 2400 (*ppos) <= SISUSB_PCI_PSEUDO_PCIBASE + 0x5c) { 2401 2402 if (count != 4) { 2403 mutex_unlock(&sisusb->lock); 2404 return -EINVAL; 2405 } 2406 2407 address = (*ppos) - SISUSB_PCI_PSEUDO_PCIBASE; 2408 2409 /* Read PCI config register 2410 * Return value delivered in machine endianness. 2411 */ 2412 if (sisusb_read_pci_config(sisusb, address, &buf32)) 2413 errno = -EIO; 2414 else if (put_user(buf32, (u32 __user *)buffer)) 2415 errno = -EFAULT; 2416 else 2417 bytes_read = 4; 2418 2419 } else { 2420 2421 errno = -EBADFD; 2422 2423 } 2424 2425 (*ppos) += bytes_read; 2426 2427 mutex_unlock(&sisusb->lock); 2428 2429 return errno ? errno : bytes_read; 2430 } 2431 2432 static ssize_t sisusb_write(struct file *file, const char __user *buffer, 2433 size_t count, loff_t *ppos) 2434 { 2435 struct sisusb_usb_data *sisusb; 2436 int errno = 0; 2437 ssize_t bytes_written = 0; 2438 u8 buf8; 2439 u16 buf16; 2440 u32 buf32, address; 2441 2442 sisusb = file->private_data; 2443 if (!sisusb) 2444 return -ENODEV; 2445 2446 mutex_lock(&sisusb->lock); 2447 2448 /* Sanity check */ 2449 if (!sisusb->present || !sisusb->ready || !sisusb->sisusb_dev) { 2450 mutex_unlock(&sisusb->lock); 2451 return -ENODEV; 2452 } 2453 2454 if ((*ppos) >= SISUSB_PCI_PSEUDO_IOPORTBASE && 2455 (*ppos) < SISUSB_PCI_PSEUDO_IOPORTBASE + 128) { 2456 2457 address = (*ppos) - SISUSB_PCI_PSEUDO_IOPORTBASE + 2458 SISUSB_PCI_IOPORTBASE; 2459 2460 /* Write i/o ports 2461 * Byte, word and long(32) can be written. As this 2462 * emulates outX instructions, the data is expected 2463 * in machine-endianness. 2464 */ 2465 switch (count) { 2466 case 1: 2467 if (get_user(buf8, (u8 __user *)buffer)) 2468 errno = -EFAULT; 2469 else if (sisusb_write_memio_byte(sisusb, 2470 SISUSB_TYPE_IO, address, buf8)) 2471 errno = -EIO; 2472 else 2473 bytes_written = 1; 2474 2475 break; 2476 2477 case 2: 2478 if (get_user(buf16, (u16 __user *)buffer)) 2479 errno = -EFAULT; 2480 else if (sisusb_write_memio_word(sisusb, 2481 SISUSB_TYPE_IO, address, buf16)) 2482 errno = -EIO; 2483 else 2484 bytes_written = 2; 2485 2486 break; 2487 2488 case 4: 2489 if (get_user(buf32, (u32 __user *)buffer)) 2490 errno = -EFAULT; 2491 else if (sisusb_write_memio_long(sisusb, 2492 SISUSB_TYPE_IO, address, buf32)) 2493 errno = -EIO; 2494 else 2495 bytes_written = 4; 2496 2497 break; 2498 2499 default: 2500 errno = -EIO; 2501 } 2502 2503 } else if ((*ppos) >= SISUSB_PCI_PSEUDO_MEMBASE && 2504 (*ppos) < SISUSB_PCI_PSEUDO_MEMBASE + 2505 sisusb->vramsize) { 2506 2507 address = (*ppos) - SISUSB_PCI_PSEUDO_MEMBASE + 2508 SISUSB_PCI_MEMBASE; 2509 2510 /* Write video ram. 2511 * Buffer is copied 1:1, therefore, on big-endian 2512 * machines, the data must be swapped by userland 2513 * in advance (if applicable; no swapping in 8bpp 2514 * mode or if YUV data is being transferred). 2515 */ 2516 errno = sisusb_write_mem_bulk(sisusb, address, NULL, 2517 count, buffer, 0, &bytes_written); 2518 2519 if (bytes_written) 2520 errno = bytes_written; 2521 2522 } else if ((*ppos) >= SISUSB_PCI_PSEUDO_MMIOBASE && 2523 (*ppos) < SISUSB_PCI_PSEUDO_MMIOBASE + 2524 SISUSB_PCI_MMIOSIZE) { 2525 2526 address = (*ppos) - SISUSB_PCI_PSEUDO_MMIOBASE + 2527 SISUSB_PCI_MMIOBASE; 2528 2529 /* Write MMIO. 2530 * Buffer is copied 1:1, therefore, on big-endian 2531 * machines, the data must be swapped by userland 2532 * in advance. 2533 */ 2534 errno = sisusb_write_mem_bulk(sisusb, address, NULL, 2535 count, buffer, 0, &bytes_written); 2536 2537 if (bytes_written) 2538 errno = bytes_written; 2539 2540 } else if ((*ppos) >= SISUSB_PCI_PSEUDO_PCIBASE && 2541 (*ppos) <= SISUSB_PCI_PSEUDO_PCIBASE + 2542 SISUSB_PCI_PCONFSIZE) { 2543 2544 if (count != 4) { 2545 mutex_unlock(&sisusb->lock); 2546 return -EINVAL; 2547 } 2548 2549 address = (*ppos) - SISUSB_PCI_PSEUDO_PCIBASE; 2550 2551 /* Write PCI config register. 2552 * Given value expected in machine endianness. 2553 */ 2554 if (get_user(buf32, (u32 __user *)buffer)) 2555 errno = -EFAULT; 2556 else if (sisusb_write_pci_config(sisusb, address, buf32)) 2557 errno = -EIO; 2558 else 2559 bytes_written = 4; 2560 2561 2562 } else { 2563 2564 /* Error */ 2565 errno = -EBADFD; 2566 2567 } 2568 2569 (*ppos) += bytes_written; 2570 2571 mutex_unlock(&sisusb->lock); 2572 2573 return errno ? errno : bytes_written; 2574 } 2575 2576 static loff_t sisusb_lseek(struct file *file, loff_t offset, int orig) 2577 { 2578 struct sisusb_usb_data *sisusb; 2579 loff_t ret; 2580 2581 sisusb = file->private_data; 2582 if (!sisusb) 2583 return -ENODEV; 2584 2585 mutex_lock(&sisusb->lock); 2586 2587 /* Sanity check */ 2588 if (!sisusb->present || !sisusb->ready || !sisusb->sisusb_dev) { 2589 mutex_unlock(&sisusb->lock); 2590 return -ENODEV; 2591 } 2592 2593 ret = no_seek_end_llseek(file, offset, orig); 2594 2595 mutex_unlock(&sisusb->lock); 2596 return ret; 2597 } 2598 2599 static int sisusb_handle_command(struct sisusb_usb_data *sisusb, 2600 struct sisusb_command *y, unsigned long arg) 2601 { 2602 int retval, length; 2603 u32 port, address; 2604 2605 /* All our commands require the device 2606 * to be initialized. 2607 */ 2608 if (!sisusb->devinit) 2609 return -ENODEV; 2610 2611 port = y->data3 - 2612 SISUSB_PCI_PSEUDO_IOPORTBASE + 2613 SISUSB_PCI_IOPORTBASE; 2614 2615 switch (y->operation) { 2616 case SUCMD_GET: 2617 retval = sisusb_getidxreg(sisusb, port, y->data0, &y->data1); 2618 if (!retval) { 2619 if (copy_to_user((void __user *)arg, y, sizeof(*y))) 2620 retval = -EFAULT; 2621 } 2622 break; 2623 2624 case SUCMD_SET: 2625 retval = sisusb_setidxreg(sisusb, port, y->data0, y->data1); 2626 break; 2627 2628 case SUCMD_SETOR: 2629 retval = sisusb_setidxregor(sisusb, port, y->data0, y->data1); 2630 break; 2631 2632 case SUCMD_SETAND: 2633 retval = sisusb_setidxregand(sisusb, port, y->data0, y->data1); 2634 break; 2635 2636 case SUCMD_SETANDOR: 2637 retval = sisusb_setidxregandor(sisusb, port, y->data0, 2638 y->data1, y->data2); 2639 break; 2640 2641 case SUCMD_SETMASK: 2642 retval = sisusb_setidxregmask(sisusb, port, y->data0, 2643 y->data1, y->data2); 2644 break; 2645 2646 case SUCMD_CLRSCR: 2647 /* Gfx core must be initialized */ 2648 if (!sisusb->gfxinit) 2649 return -ENODEV; 2650 2651 length = (y->data0 << 16) | (y->data1 << 8) | y->data2; 2652 address = y->data3 - SISUSB_PCI_PSEUDO_MEMBASE + 2653 SISUSB_PCI_MEMBASE; 2654 retval = sisusb_clear_vram(sisusb, address, length); 2655 break; 2656 2657 case SUCMD_HANDLETEXTMODE: 2658 retval = 0; 2659 break; 2660 2661 default: 2662 retval = -EINVAL; 2663 } 2664 2665 if (retval > 0) 2666 retval = -EIO; 2667 2668 return retval; 2669 } 2670 2671 static long sisusb_ioctl(struct file *file, unsigned int cmd, unsigned long arg) 2672 { 2673 struct sisusb_usb_data *sisusb; 2674 struct sisusb_info x; 2675 struct sisusb_command y; 2676 long retval = 0; 2677 u32 __user *argp = (u32 __user *)arg; 2678 2679 sisusb = file->private_data; 2680 if (!sisusb) 2681 return -ENODEV; 2682 2683 mutex_lock(&sisusb->lock); 2684 2685 /* Sanity check */ 2686 if (!sisusb->present || !sisusb->ready || !sisusb->sisusb_dev) { 2687 retval = -ENODEV; 2688 goto err_out; 2689 } 2690 2691 switch (cmd) { 2692 case SISUSB_GET_CONFIG_SIZE: 2693 2694 if (put_user(sizeof(x), argp)) 2695 retval = -EFAULT; 2696 2697 break; 2698 2699 case SISUSB_GET_CONFIG: 2700 2701 x.sisusb_id = SISUSB_ID; 2702 x.sisusb_version = SISUSB_VERSION; 2703 x.sisusb_revision = SISUSB_REVISION; 2704 x.sisusb_patchlevel = SISUSB_PATCHLEVEL; 2705 x.sisusb_gfxinit = sisusb->gfxinit; 2706 x.sisusb_vrambase = SISUSB_PCI_PSEUDO_MEMBASE; 2707 x.sisusb_mmiobase = SISUSB_PCI_PSEUDO_MMIOBASE; 2708 x.sisusb_iobase = SISUSB_PCI_PSEUDO_IOPORTBASE; 2709 x.sisusb_pcibase = SISUSB_PCI_PSEUDO_PCIBASE; 2710 x.sisusb_vramsize = sisusb->vramsize; 2711 x.sisusb_minor = sisusb->minor; 2712 x.sisusb_fbdevactive = 0; 2713 x.sisusb_conactive = 0; 2714 memset(x.sisusb_reserved, 0, sizeof(x.sisusb_reserved)); 2715 2716 if (copy_to_user((void __user *)arg, &x, sizeof(x))) 2717 retval = -EFAULT; 2718 2719 break; 2720 2721 case SISUSB_COMMAND: 2722 2723 if (copy_from_user(&y, (void __user *)arg, sizeof(y))) 2724 retval = -EFAULT; 2725 else 2726 retval = sisusb_handle_command(sisusb, &y, arg); 2727 2728 break; 2729 2730 default: 2731 retval = -ENOTTY; 2732 break; 2733 } 2734 2735 err_out: 2736 mutex_unlock(&sisusb->lock); 2737 return retval; 2738 } 2739 2740 #ifdef CONFIG_COMPAT 2741 static long sisusb_compat_ioctl(struct file *f, unsigned int cmd, 2742 unsigned long arg) 2743 { 2744 switch (cmd) { 2745 case SISUSB_GET_CONFIG_SIZE: 2746 case SISUSB_GET_CONFIG: 2747 case SISUSB_COMMAND: 2748 return sisusb_ioctl(f, cmd, arg); 2749 2750 default: 2751 return -ENOIOCTLCMD; 2752 } 2753 } 2754 #endif 2755 2756 static const struct file_operations usb_sisusb_fops = { 2757 .owner = THIS_MODULE, 2758 .open = sisusb_open, 2759 .release = sisusb_release, 2760 .read = sisusb_read, 2761 .write = sisusb_write, 2762 .llseek = sisusb_lseek, 2763 #ifdef CONFIG_COMPAT 2764 .compat_ioctl = sisusb_compat_ioctl, 2765 #endif 2766 .unlocked_ioctl = sisusb_ioctl 2767 }; 2768 2769 static struct usb_class_driver usb_sisusb_class = { 2770 .name = "sisusbvga%d", 2771 .fops = &usb_sisusb_fops, 2772 .minor_base = SISUSB_MINOR 2773 }; 2774 2775 static int sisusb_probe(struct usb_interface *intf, 2776 const struct usb_device_id *id) 2777 { 2778 struct usb_device *dev = interface_to_usbdev(intf); 2779 struct sisusb_usb_data *sisusb; 2780 int retval = 0, i; 2781 static const u8 ep_addresses[] = { 2782 SISUSB_EP_GFX_IN | USB_DIR_IN, 2783 SISUSB_EP_GFX_OUT | USB_DIR_OUT, 2784 SISUSB_EP_GFX_BULK_OUT | USB_DIR_OUT, 2785 SISUSB_EP_GFX_LBULK_OUT | USB_DIR_OUT, 2786 SISUSB_EP_BRIDGE_IN | USB_DIR_IN, 2787 SISUSB_EP_BRIDGE_OUT | USB_DIR_OUT, 2788 0}; 2789 2790 /* Are the expected endpoints present? */ 2791 if (!usb_check_bulk_endpoints(intf, ep_addresses)) { 2792 dev_err(&intf->dev, "Invalid USB2VGA device\n"); 2793 return -EINVAL; 2794 } 2795 2796 dev_info(&dev->dev, "USB2VGA dongle found at address %d\n", 2797 dev->devnum); 2798 2799 /* Allocate memory for our private */ 2800 sisusb = kzalloc(sizeof(*sisusb), GFP_KERNEL); 2801 if (!sisusb) 2802 return -ENOMEM; 2803 2804 kref_init(&sisusb->kref); 2805 2806 mutex_init(&(sisusb->lock)); 2807 2808 sisusb->sisusb_dev = dev; 2809 sisusb->vrambase = SISUSB_PCI_MEMBASE; 2810 sisusb->mmiobase = SISUSB_PCI_MMIOBASE; 2811 sisusb->mmiosize = SISUSB_PCI_MMIOSIZE; 2812 sisusb->ioportbase = SISUSB_PCI_IOPORTBASE; 2813 /* Everything else is zero */ 2814 2815 /* Register device */ 2816 retval = usb_register_dev(intf, &usb_sisusb_class); 2817 if (retval) { 2818 dev_err(&sisusb->sisusb_dev->dev, 2819 "Failed to get a minor for device %d\n", 2820 dev->devnum); 2821 retval = -ENODEV; 2822 goto error_1; 2823 } 2824 2825 sisusb->minor = intf->minor; 2826 2827 /* Allocate buffers */ 2828 sisusb->ibufsize = SISUSB_IBUF_SIZE; 2829 sisusb->ibuf = kmalloc(SISUSB_IBUF_SIZE, GFP_KERNEL); 2830 if (!sisusb->ibuf) { 2831 retval = -ENOMEM; 2832 goto error_2; 2833 } 2834 2835 sisusb->numobufs = 0; 2836 sisusb->obufsize = SISUSB_OBUF_SIZE; 2837 for (i = 0; i < NUMOBUFS; i++) { 2838 sisusb->obuf[i] = kmalloc(SISUSB_OBUF_SIZE, GFP_KERNEL); 2839 if (!sisusb->obuf[i]) { 2840 if (i == 0) { 2841 retval = -ENOMEM; 2842 goto error_3; 2843 } 2844 break; 2845 } 2846 sisusb->numobufs++; 2847 } 2848 2849 /* Allocate URBs */ 2850 sisusb->sisurbin = usb_alloc_urb(0, GFP_KERNEL); 2851 if (!sisusb->sisurbin) { 2852 retval = -ENOMEM; 2853 goto error_3; 2854 } 2855 sisusb->completein = 1; 2856 2857 for (i = 0; i < sisusb->numobufs; i++) { 2858 sisusb->sisurbout[i] = usb_alloc_urb(0, GFP_KERNEL); 2859 if (!sisusb->sisurbout[i]) { 2860 retval = -ENOMEM; 2861 goto error_4; 2862 } 2863 sisusb->urbout_context[i].sisusb = (void *)sisusb; 2864 sisusb->urbout_context[i].urbindex = i; 2865 sisusb->urbstatus[i] = 0; 2866 } 2867 2868 dev_info(&sisusb->sisusb_dev->dev, "Allocated %d output buffers\n", 2869 sisusb->numobufs); 2870 2871 /* Do remaining init stuff */ 2872 2873 init_waitqueue_head(&sisusb->wait_q); 2874 2875 usb_set_intfdata(intf, sisusb); 2876 2877 usb_get_dev(sisusb->sisusb_dev); 2878 2879 sisusb->present = 1; 2880 2881 if (dev->speed == USB_SPEED_HIGH || dev->speed >= USB_SPEED_SUPER) { 2882 int initscreen = 1; 2883 if (sisusb_init_gfxdevice(sisusb, initscreen)) 2884 dev_err(&sisusb->sisusb_dev->dev, 2885 "Failed to early initialize device\n"); 2886 2887 } else 2888 dev_info(&sisusb->sisusb_dev->dev, 2889 "Not attached to USB 2.0 hub, deferring init\n"); 2890 2891 sisusb->ready = 1; 2892 2893 #ifdef SISUSBENDIANTEST 2894 dev_dbg(&sisusb->sisusb_dev->dev, "*** RWTEST ***\n"); 2895 sisusb_testreadwrite(sisusb); 2896 dev_dbg(&sisusb->sisusb_dev->dev, "*** RWTEST END ***\n"); 2897 #endif 2898 2899 return 0; 2900 2901 error_4: 2902 sisusb_free_urbs(sisusb); 2903 error_3: 2904 sisusb_free_buffers(sisusb); 2905 error_2: 2906 usb_deregister_dev(intf, &usb_sisusb_class); 2907 error_1: 2908 kfree(sisusb); 2909 return retval; 2910 } 2911 2912 static void sisusb_disconnect(struct usb_interface *intf) 2913 { 2914 struct sisusb_usb_data *sisusb; 2915 2916 /* This should *not* happen */ 2917 sisusb = usb_get_intfdata(intf); 2918 if (!sisusb) 2919 return; 2920 2921 usb_deregister_dev(intf, &usb_sisusb_class); 2922 2923 mutex_lock(&sisusb->lock); 2924 2925 /* Wait for all URBs to complete and kill them in case (MUST do) */ 2926 if (!sisusb_wait_all_out_complete(sisusb)) 2927 sisusb_kill_all_busy(sisusb); 2928 2929 usb_set_intfdata(intf, NULL); 2930 2931 sisusb->present = 0; 2932 sisusb->ready = 0; 2933 2934 mutex_unlock(&sisusb->lock); 2935 2936 /* decrement our usage count */ 2937 kref_put(&sisusb->kref, sisusb_delete); 2938 } 2939 2940 static const struct usb_device_id sisusb_table[] = { 2941 { USB_DEVICE(0x0711, 0x0550) }, 2942 { USB_DEVICE(0x0711, 0x0900) }, 2943 { USB_DEVICE(0x0711, 0x0901) }, 2944 { USB_DEVICE(0x0711, 0x0902) }, 2945 { USB_DEVICE(0x0711, 0x0903) }, 2946 { USB_DEVICE(0x0711, 0x0918) }, 2947 { USB_DEVICE(0x0711, 0x0920) }, 2948 { USB_DEVICE(0x0711, 0x0950) }, 2949 { USB_DEVICE(0x0711, 0x5200) }, 2950 { USB_DEVICE(0x182d, 0x021c) }, 2951 { USB_DEVICE(0x182d, 0x0269) }, 2952 { } 2953 }; 2954 2955 MODULE_DEVICE_TABLE(usb, sisusb_table); 2956 2957 static struct usb_driver sisusb_driver = { 2958 .name = "sisusb", 2959 .probe = sisusb_probe, 2960 .disconnect = sisusb_disconnect, 2961 .id_table = sisusb_table, 2962 }; 2963 2964 module_usb_driver(sisusb_driver); 2965 2966 MODULE_AUTHOR("Thomas Winischhofer <thomas@winischhofer.net>"); 2967 MODULE_DESCRIPTION("sisusbvga - Driver for Net2280/SiS315-based USB2VGA dongles"); 2968 MODULE_LICENSE("GPL"); 2969 2970