2  * sisusb - usb kernel driver for SiS315(E) based USB2VGA dongles
 
   6  * Copyright (C) 2005 by Thomas Winischhofer, Vienna, Austria
 
   8  * If distributed as part of the Linux kernel, this code is licensed under the
 
  11  * Otherwise, the following license terms apply:
 
  13  * * Redistribution and use in source and binary forms, with or without
 
  14  * * modification, are permitted provided that the following conditions
 
  16  * * 1) Redistributions of source code must retain the above copyright
 
  17  * *    notice, this list of conditions and the following disclaimer.
 
  18  * * 2) Redistributions in binary form must reproduce the above copyright
 
  19  * *    notice, this list of conditions and the following disclaimer in the
 
  20  * *    documentation and/or other materials provided with the distribution.
 
  21  * * 3) The name of the author may not be used to endorse or promote products
 
  22  * *    derived from this software without specific psisusbr written permission.
 
  24  * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED OR
 
  25  * * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 
  26  * * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 
  27  * * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 
  28  * * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 
  29  * * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 
  30  * * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 
  31  * * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 
  32  * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 
  33  * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
  35  * Author:      Thomas Winischhofer <thomas@winischhofer.net>
 
  39 #include <linux/mutex.h>
 
  40 #include <linux/module.h>
 
  41 #include <linux/kernel.h>
 
  42 #include <linux/signal.h>
 
  43 #include <linux/errno.h>
 
  44 #include <linux/poll.h>
 
  45 #include <linux/init.h>
 
  46 #include <linux/slab.h>
 
  47 #include <linux/spinlock.h>
 
  48 #include <linux/kref.h>
 
  49 #include <linux/usb.h>
 
  50 #include <linux/smp_lock.h>
 
  51 #include <linux/vmalloc.h>
 
  54 #include "sisusb_init.h"
 
  56 #ifdef INCL_SISUSB_CON
 
  57 #include <linux/font.h>
 
  60 #define SISUSB_DONTSYNC
 
  62 /* Forward declarations / clean-up routines */
 
  64 #ifdef INCL_SISUSB_CON
 
  65 static int sisusb_first_vc = 0;
 
  66 static int sisusb_last_vc = 0;
 
  67 module_param_named(first, sisusb_first_vc, int, 0);
 
  68 module_param_named(last, sisusb_last_vc, int, 0);
 
  69 MODULE_PARM_DESC(first, "Number of first console to take over (1 - MAX_NR_CONSOLES)");
 
  70 MODULE_PARM_DESC(last, "Number of last console to take over (1 - MAX_NR_CONSOLES)");
 
  73 static struct usb_driver sisusb_driver;
 
  76 sisusb_free_buffers(struct sisusb_usb_data *sisusb)
 
  80         for (i = 0; i < NUMOBUFS; i++) {
 
  81                 if (sisusb->obuf[i]) {
 
  82                         usb_buffer_free(sisusb->sisusb_dev, sisusb->obufsize,
 
  83                                 sisusb->obuf[i], sisusb->transfer_dma_out[i]);
 
  84                         sisusb->obuf[i] = NULL;
 
  88                 usb_buffer_free(sisusb->sisusb_dev, sisusb->ibufsize,
 
  89                         sisusb->ibuf, sisusb->transfer_dma_in);
 
  95 sisusb_free_urbs(struct sisusb_usb_data *sisusb)
 
  99         for (i = 0; i < NUMOBUFS; i++) {
 
 100                 usb_free_urb(sisusb->sisurbout[i]);
 
 101                 sisusb->sisurbout[i] = NULL;
 
 103         usb_free_urb(sisusb->sisurbin);
 
 104         sisusb->sisurbin = NULL;
 
 107 /* Level 0: USB transport layer */
 
 111 /* out-urb management */
 
 113 /* Return 1 if all free, 0 otherwise */
 
 115 sisusb_all_free(struct sisusb_usb_data *sisusb)
 
 119         for (i = 0; i < sisusb->numobufs; i++) {
 
 121                 if (sisusb->urbstatus[i] & SU_URB_BUSY)
 
 129 /* Kill all busy URBs */
 
 131 sisusb_kill_all_busy(struct sisusb_usb_data *sisusb)
 
 135         if (sisusb_all_free(sisusb))
 
 138         for (i = 0; i < sisusb->numobufs; i++) {
 
 140                 if (sisusb->urbstatus[i] & SU_URB_BUSY)
 
 141                         usb_kill_urb(sisusb->sisurbout[i]);
 
 146 /* Return 1 if ok, 0 if error (not all complete within timeout) */
 
 148 sisusb_wait_all_out_complete(struct sisusb_usb_data *sisusb)
 
 150         int timeout = 5 * HZ, i = 1;
 
 152         wait_event_timeout(sisusb->wait_q,
 
 153                                 (i = sisusb_all_free(sisusb)),
 
 160 sisusb_outurb_available(struct sisusb_usb_data *sisusb)
 
 164         for (i = 0; i < sisusb->numobufs; i++) {
 
 166                 if ((sisusb->urbstatus[i] & (SU_URB_BUSY|SU_URB_ALLOC)) == 0)
 
 175 sisusb_get_free_outbuf(struct sisusb_usb_data *sisusb)
 
 177         int i, timeout = 5 * HZ;
 
 179         wait_event_timeout(sisusb->wait_q,
 
 180                                 ((i = sisusb_outurb_available(sisusb)) >= 0),
 
 187 sisusb_alloc_outbuf(struct sisusb_usb_data *sisusb)
 
 191         i = sisusb_outurb_available(sisusb);
 
 194                 sisusb->urbstatus[i] |= SU_URB_ALLOC;
 
 200 sisusb_free_outbuf(struct sisusb_usb_data *sisusb, int index)
 
 202         if ((index >= 0) && (index < sisusb->numobufs))
 
 203                 sisusb->urbstatus[index] &= ~SU_URB_ALLOC;
 
 206 /* completion callback */
 
 209 sisusb_bulk_completeout(struct urb *urb)
 
 211         struct sisusb_urb_context *context = urb->context;
 
 212         struct sisusb_usb_data *sisusb;
 
 217         sisusb = context->sisusb;
 
 219         if (!sisusb || !sisusb->sisusb_dev || !sisusb->present)
 
 222 #ifndef SISUSB_DONTSYNC
 
 223         if (context->actual_length)
 
 224                 *(context->actual_length) += urb->actual_length;
 
 227         sisusb->urbstatus[context->urbindex] &= ~SU_URB_BUSY;
 
 228         wake_up(&sisusb->wait_q);
 
 232 sisusb_bulkout_msg(struct sisusb_usb_data *sisusb, int index, unsigned int pipe, void *data,
 
 233                 int len, int *actual_length, int timeout, unsigned int tflags,
 
 234                 dma_addr_t transfer_dma)
 
 236         struct urb *urb = sisusb->sisurbout[index];
 
 237         int retval, byteswritten = 0;
 
 240         urb->transfer_flags = 0;
 
 242         usb_fill_bulk_urb(urb, sisusb->sisusb_dev, pipe, data, len,
 
 243                 sisusb_bulk_completeout, &sisusb->urbout_context[index]);
 
 245         urb->transfer_flags |= tflags;
 
 246         urb->actual_length = 0;
 
 248         if ((urb->transfer_dma = transfer_dma))
 
 249                 urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
 
 252         sisusb->urbout_context[index].actual_length = (timeout) ?
 
 253                                                 NULL : actual_length;
 
 255         /* Declare this urb/buffer in use */
 
 256         sisusb->urbstatus[index] |= SU_URB_BUSY;
 
 259         retval = usb_submit_urb(urb, GFP_ATOMIC);
 
 261         /* If OK, and if timeout > 0, wait for completion */
 
 262         if ((retval == 0) && timeout) {
 
 263                 wait_event_timeout(sisusb->wait_q,
 
 264                                    (!(sisusb->urbstatus[index] & SU_URB_BUSY)),
 
 266                 if (sisusb->urbstatus[index] & SU_URB_BUSY) {
 
 267                         /* URB timed out... kill it and report error */
 
 271                         /* Otherwise, report urb status */
 
 272                         retval = urb->status;
 
 273                         byteswritten = urb->actual_length;
 
 278                 *actual_length = byteswritten;
 
 285 /* completion callback */
 
 288 sisusb_bulk_completein(struct urb *urb)
 
 290         struct sisusb_usb_data *sisusb = urb->context;
 
 292         if (!sisusb || !sisusb->sisusb_dev || !sisusb->present)
 
 295         sisusb->completein = 1;
 
 296         wake_up(&sisusb->wait_q);
 
 300 sisusb_bulkin_msg(struct sisusb_usb_data *sisusb, unsigned int pipe, void *data, int len,
 
 301                 int *actual_length, int timeout, unsigned int tflags, dma_addr_t transfer_dma)
 
 303         struct urb *urb = sisusb->sisurbin;
 
 304         int retval, readbytes = 0;
 
 306         urb->transfer_flags = 0;
 
 308         usb_fill_bulk_urb(urb, sisusb->sisusb_dev, pipe, data, len,
 
 309                         sisusb_bulk_completein, sisusb);
 
 311         urb->transfer_flags |= tflags;
 
 312         urb->actual_length = 0;
 
 314         if ((urb->transfer_dma = transfer_dma))
 
 315                 urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
 
 317         sisusb->completein = 0;
 
 318         retval = usb_submit_urb(urb, GFP_ATOMIC);
 
 320                 wait_event_timeout(sisusb->wait_q, sisusb->completein, timeout);
 
 321                 if (!sisusb->completein) {
 
 322                         /* URB timed out... kill it and report error */
 
 326                         /* URB completed within timout */
 
 327                         retval = urb->status;
 
 328                         readbytes = urb->actual_length;
 
 333                 *actual_length = readbytes;
 
 341 /* Send a bulk message of variable size
 
 343  * To copy the data from userspace, give pointer to "userbuffer",
 
 344  * to copy from (non-DMA) kernel memory, give "kernbuffer". If
 
 345  * both of these are NULL, it is assumed, that the transfer
 
 346  * buffer "sisusb->obuf[index]" is set up with the data to send.
 
 347  * Index is ignored if either kernbuffer or userbuffer is set.
 
 348  * If async is nonzero, URBs will be sent without waiting for
 
 349  * completion of the previous URB.
 
 351  * (return 0 on success)
 
 354 static int sisusb_send_bulk_msg(struct sisusb_usb_data *sisusb, int ep, int len,
 
 355                 char *kernbuffer, const char __user *userbuffer, int index,
 
 356                 ssize_t *bytes_written, unsigned int tflags, int async)
 
 358         int result = 0, retry, count = len;
 
 359         int passsize, thispass, transferred_len = 0;
 
 360         int fromuser = (userbuffer != NULL) ? 1 : 0;
 
 361         int fromkern = (kernbuffer != NULL) ? 1 : 0;
 
 365         (*bytes_written) = 0;
 
 368         if (!sisusb || !sisusb->present || !sisusb->sisusb_dev)
 
 371         /* If we copy data from kernel or userspace, force the
 
 372          * allocation of a buffer/urb. If we have the data in
 
 373          * the transfer buffer[index] already, reuse the buffer/URB
 
 374          * if the length is > buffer size. (So, transmitting
 
 375          * large data amounts directly from the transfer buffer
 
 376          * treats the buffer as a ring buffer. However, we need
 
 377          * to sync in this case.)
 
 379         if (fromuser || fromkern)
 
 381         else if (len > sisusb->obufsize)
 
 384         pipe = usb_sndbulkpipe(sisusb->sisusb_dev, ep);
 
 387                 passsize = thispass = (sisusb->obufsize < count) ?
 
 388                                                 sisusb->obufsize : count;
 
 391                         index = sisusb_get_free_outbuf(sisusb);
 
 396                 buffer = sisusb->obuf[index];
 
 400                         if (copy_from_user(buffer, userbuffer, passsize))
 
 403                         userbuffer += passsize;
 
 405                 } else if (fromkern) {
 
 407                         memcpy(buffer, kernbuffer, passsize);
 
 408                         kernbuffer += passsize;
 
 415                         if (!sisusb->sisusb_dev)
 
 418                         result = sisusb_bulkout_msg(sisusb,
 
 426                                                 sisusb->transfer_dma_out[index]);
 
 428                         if (result == -ETIMEDOUT) {
 
 430                                 /* Will not happen if async */
 
 436                         } else if ((result == 0) && !async && transferred_len) {
 
 438                                 thispass -= transferred_len;
 
 440                                         if (sisusb->transfer_dma_out) {
 
 441                                                 /* If DMA, copy remaining
 
 442                                                  * to beginning of buffer
 
 445                                                        buffer + transferred_len,
 
 448                                                 /* If not DMA, simply increase
 
 451                                                 buffer += transferred_len;
 
 462                 (*bytes_written) += passsize;
 
 465                 /* Force new allocation in next iteration */
 
 466                 if (fromuser || fromkern)
 
 472 #ifdef SISUSB_DONTSYNC
 
 473                 (*bytes_written) = len;
 
 474                 /* Some URBs/buffers might be busy */
 
 476                 sisusb_wait_all_out_complete(sisusb);
 
 477                 (*bytes_written) = transferred_len;
 
 478                 /* All URBs and all buffers are available */
 
 482         return ((*bytes_written) == len) ? 0 : -EIO;
 
 485 /* Receive a bulk message of variable size
 
 487  * To copy the data to userspace, give pointer to "userbuffer",
 
 488  * to copy to kernel memory, give "kernbuffer". One of them
 
 489  * MUST be set. (There is no technique for letting the caller
 
 490  * read directly from the ibuf.)
 
 494 static int sisusb_recv_bulk_msg(struct sisusb_usb_data *sisusb, int ep, int len,
 
 495                 void *kernbuffer, char __user *userbuffer, ssize_t *bytes_read,
 
 498         int result = 0, retry, count = len;
 
 499         int bufsize, thispass, transferred_len;
 
 506         if (!sisusb || !sisusb->present || !sisusb->sisusb_dev)
 
 509         pipe = usb_rcvbulkpipe(sisusb->sisusb_dev, ep);
 
 510         buffer = sisusb->ibuf;
 
 511         bufsize = sisusb->ibufsize;
 
 515 #ifdef SISUSB_DONTSYNC
 
 516         if (!(sisusb_wait_all_out_complete(sisusb)))
 
 522                 if (!sisusb->sisusb_dev)
 
 525                 thispass = (bufsize < count) ? bufsize : count;
 
 527                 result = sisusb_bulkin_msg(sisusb,
 
 534                                            sisusb->transfer_dma_in);
 
 537                         thispass = transferred_len;
 
 539                 else if (result == -ETIMEDOUT) {
 
 552                         (*bytes_read) += thispass;
 
 557                                 if (copy_to_user(userbuffer, buffer, thispass))
 
 560                                 userbuffer += thispass;
 
 564                                 memcpy(kernbuffer, buffer, thispass);
 
 565                                 kernbuffer += thispass;
 
 573         return ((*bytes_read) == len) ? 0 : -EIO;
 
 576 static int sisusb_send_packet(struct sisusb_usb_data *sisusb, int len,
 
 577                                                 struct sisusb_packet *packet)
 
 580         ssize_t bytes_transferred = 0;
 
 586 #ifdef SISUSB_DONTSYNC
 
 587         if (!(sisusb_wait_all_out_complete(sisusb)))
 
 591         /* Eventually correct endianness */
 
 592         SISUSB_CORRECT_ENDIANNESS_PACKET(packet);
 
 594         /* 1. send the packet */
 
 595         ret = sisusb_send_bulk_msg(sisusb, SISUSB_EP_GFX_OUT, len,
 
 596                         (char *)packet, NULL, 0, &bytes_transferred, 0, 0);
 
 598         if ((ret == 0) && (len == 6)) {
 
 600                 /* 2. if packet len == 6, it means we read, so wait for 32bit
 
 601                  *    return value and write it to packet->data
 
 603                 ret = sisusb_recv_bulk_msg(sisusb, SISUSB_EP_GFX_IN, 4,
 
 604                                 (char *)&tmp, NULL, &bytes_transferred, 0);
 
 606                 packet->data = le32_to_cpu(tmp);
 
 612 static int sisusb_send_bridge_packet(struct sisusb_usb_data *sisusb, int len,
 
 613                                         struct sisusb_packet *packet,
 
 617         ssize_t bytes_transferred = 0;
 
 623 #ifdef SISUSB_DONTSYNC
 
 624         if (!(sisusb_wait_all_out_complete(sisusb)))
 
 628         /* Eventually correct endianness */
 
 629         SISUSB_CORRECT_ENDIANNESS_PACKET(packet);
 
 631         /* 1. send the packet */
 
 632         ret = sisusb_send_bulk_msg(sisusb, SISUSB_EP_BRIDGE_OUT, len,
 
 633                         (char *)packet, NULL, 0, &bytes_transferred, tflags, 0);
 
 635         if ((ret == 0) && (len == 6)) {
 
 637                 /* 2. if packet len == 6, it means we read, so wait for 32bit
 
 638                  *    return value and write it to packet->data
 
 640                 ret = sisusb_recv_bulk_msg(sisusb, SISUSB_EP_BRIDGE_IN, 4,
 
 641                                 (char *)&tmp, NULL, &bytes_transferred, 0);
 
 643                 packet->data = le32_to_cpu(tmp);
 
 649 /* access video memory and mmio (return 0 on success) */
 
 653 /* The following routines assume being used to transfer byte, word,
 
 656  *   - the write routines expect "data" in machine endianness format.
 
 657  *     The data will be converted to leXX in sisusb_xxx_packet.
 
 658  *   - the read routines can expect read data in machine-endianess.
 
 661 static int sisusb_write_memio_byte(struct sisusb_usb_data *sisusb, int type,
 
 664         struct sisusb_packet packet;
 
 667         packet.header  = (1 << (addr & 3)) | (type << 6);
 
 668         packet.address = addr & ~3;
 
 669         packet.data    = data << ((addr & 3) << 3);
 
 670         ret = sisusb_send_packet(sisusb, 10, &packet);
 
 674 static int sisusb_write_memio_word(struct sisusb_usb_data *sisusb, int type,
 
 677         struct sisusb_packet packet;
 
 680         packet.address = addr & ~3;
 
 684                         packet.header = (type << 6) | 0x0003;
 
 685                         packet.data   = (u32)data;
 
 686                         ret = sisusb_send_packet(sisusb, 10, &packet);
 
 689                         packet.header = (type << 6) | 0x0006;
 
 690                         packet.data   = (u32)data << 8;
 
 691                         ret = sisusb_send_packet(sisusb, 10, &packet);
 
 694                         packet.header = (type << 6) | 0x000c;
 
 695                         packet.data   = (u32)data << 16;
 
 696                         ret = sisusb_send_packet(sisusb, 10, &packet);
 
 699                         packet.header = (type << 6) | 0x0008;
 
 700                         packet.data   = (u32)data << 24;
 
 701                         ret = sisusb_send_packet(sisusb, 10, &packet);
 
 702                         packet.header = (type << 6) | 0x0001;
 
 703                         packet.address = (addr & ~3) + 4;
 
 704                         packet.data   = (u32)data >> 8;
 
 705                         ret |= sisusb_send_packet(sisusb, 10, &packet);
 
 711 static int sisusb_write_memio_24bit(struct sisusb_usb_data *sisusb, int type,
 
 714         struct sisusb_packet packet;
 
 717         packet.address = addr & ~3;
 
 721                         packet.header  = (type << 6) | 0x0007;
 
 722                         packet.data    = data & 0x00ffffff;
 
 723                         ret = sisusb_send_packet(sisusb, 10, &packet);
 
 726                         packet.header  = (type << 6) | 0x000e;
 
 727                         packet.data    = data << 8;
 
 728                         ret = sisusb_send_packet(sisusb, 10, &packet);
 
 731                         packet.header  = (type << 6) | 0x000c;
 
 732                         packet.data    = data << 16;
 
 733                         ret = sisusb_send_packet(sisusb, 10, &packet);
 
 734                         packet.header  = (type << 6) | 0x0001;
 
 735                         packet.address = (addr & ~3) + 4;
 
 736                         packet.data    = (data >> 16) & 0x00ff;
 
 737                         ret |= sisusb_send_packet(sisusb, 10, &packet);
 
 740                         packet.header  = (type << 6) | 0x0008;
 
 741                         packet.data    = data << 24;
 
 742                         ret = sisusb_send_packet(sisusb, 10, &packet);
 
 743                         packet.header  = (type << 6) | 0x0003;
 
 744                         packet.address = (addr & ~3) + 4;
 
 745                         packet.data    = (data >> 8) & 0xffff;
 
 746                         ret |= sisusb_send_packet(sisusb, 10, &packet);
 
 752 static int sisusb_write_memio_long(struct sisusb_usb_data *sisusb, int type,
 
 755         struct sisusb_packet packet;
 
 758         packet.address = addr & ~3;
 
 762                         packet.header  = (type << 6) | 0x000f;
 
 764                         ret = sisusb_send_packet(sisusb, 10, &packet);
 
 767                         packet.header  = (type << 6) | 0x000e;
 
 768                         packet.data    = data << 8;
 
 769                         ret = sisusb_send_packet(sisusb, 10, &packet);
 
 770                         packet.header  = (type << 6) | 0x0001;
 
 771                         packet.address = (addr & ~3) + 4;
 
 772                         packet.data    = data >> 24;
 
 773                         ret |= sisusb_send_packet(sisusb, 10, &packet);
 
 776                         packet.header  = (type << 6) | 0x000c;
 
 777                         packet.data    = data << 16;
 
 778                         ret = sisusb_send_packet(sisusb, 10, &packet);
 
 779                         packet.header  = (type << 6) | 0x0003;
 
 780                         packet.address = (addr & ~3) + 4;
 
 781                         packet.data    = data >> 16;
 
 782                         ret |= sisusb_send_packet(sisusb, 10, &packet);
 
 785                         packet.header  = (type << 6) | 0x0008;
 
 786                         packet.data    = data << 24;
 
 787                         ret = sisusb_send_packet(sisusb, 10, &packet);
 
 788                         packet.header  = (type << 6) | 0x0007;
 
 789                         packet.address = (addr & ~3) + 4;
 
 790                         packet.data    = data >> 8;
 
 791                         ret |= sisusb_send_packet(sisusb, 10, &packet);
 
 797 /* The xxx_bulk routines copy a buffer of variable size. They treat the
 
 798  * buffer as chars, therefore lsb/msb has to be corrected if using the
 
 799  * byte/word/long/etc routines for speed-up
 
 801  * If data is from userland, set "userbuffer" (and clear "kernbuffer"),
 
 802  * if data is in kernel space, set "kernbuffer" (and clear "userbuffer");
 
 803  * if neither "kernbuffer" nor "userbuffer" are given, it is assumed
 
 804  * that the data already is in the transfer buffer "sisusb->obuf[index]".
 
 807 static int sisusb_write_mem_bulk(struct sisusb_usb_data *sisusb, u32 addr,
 
 808                                 char *kernbuffer, int length,
 
 809                                 const char __user *userbuffer, int index,
 
 810                                 ssize_t *bytes_written)
 
 812         struct sisusb_packet packet;
 
 814         static int msgcount = 0;
 
 815         u8   swap8, fromkern = kernbuffer ? 1 : 0;
 
 817         u32  swap32, flag = (length >> 28) & 1;
 
 820         /* if neither kernbuffer not userbuffer are given, assume
 
 823         if (!fromkern && !userbuffer)
 
 824                 kernbuffer = sisusb->obuf[index];
 
 826         (*bytes_written = 0);
 
 828         length &= 0x00ffffff;
 
 836                                 if (get_user(swap8, (u8 __user *)userbuffer))
 
 839                                 swap8 = kernbuffer[0];
 
 841                         ret = sisusb_write_memio_byte(sisusb,
 
 852                                 if (get_user(swap16, (u16 __user *)userbuffer))
 
 855                                 swap16 = *((u16 *)kernbuffer);
 
 857                         ret = sisusb_write_memio_word(sisusb,
 
 863                                 (*bytes_written) += 2;
 
 869                                 if (copy_from_user(&buf, userbuffer, 3))
 
 872                                 swap32 = (buf[0] << 16) |
 
 876                                 swap32 = (buf[2] << 16) |
 
 882                                 swap32 = (kernbuffer[0] << 16) |
 
 883                                          (kernbuffer[1] <<  8) |
 
 886                                 swap32 = (kernbuffer[2] << 16) |
 
 887                                          (kernbuffer[1] <<  8) |
 
 891                         ret = sisusb_write_memio_24bit(sisusb,
 
 897                                 (*bytes_written) += 3;
 
 903                                 if (get_user(swap32, (u32 __user *)userbuffer))
 
 906                                 swap32 = *((u32 *)kernbuffer);
 
 908                         ret = sisusb_write_memio_long(sisusb,
 
 913                                 (*bytes_written) += 4;
 
 918                         if ((length & ~3) > 0x10000) {
 
 920                            packet.header  = 0x001f;
 
 921                            packet.address = 0x000001d4;
 
 923                            ret = sisusb_send_bridge_packet(sisusb, 10,
 
 925                            packet.header  = 0x001f;
 
 926                            packet.address = 0x000001d0;
 
 927                            packet.data    = (length & ~3);
 
 928                            ret |= sisusb_send_bridge_packet(sisusb, 10,
 
 930                            packet.header  = 0x001f;
 
 931                            packet.address = 0x000001c0;
 
 932                            packet.data    = flag | 0x16;
 
 933                            ret |= sisusb_send_bridge_packet(sisusb, 10,
 
 936                                 ret |= sisusb_send_bulk_msg(sisusb,
 
 937                                                         SISUSB_EP_GFX_LBULK_OUT,
 
 940                                                         bytes_written, 0, 1);
 
 941                                 userbuffer += (*bytes_written);
 
 942                            } else if (fromkern) {
 
 943                                 ret |= sisusb_send_bulk_msg(sisusb,
 
 944                                                         SISUSB_EP_GFX_LBULK_OUT,
 
 947                                                         bytes_written, 0, 1);
 
 948                                 kernbuffer += (*bytes_written);
 
 950                         ret |= sisusb_send_bulk_msg(sisusb,
 
 951                                                         SISUSB_EP_GFX_LBULK_OUT,
 
 954                                                         bytes_written, 0, 1);
 
 955                                 kernbuffer += ((*bytes_written) &
 
 956                                                 (sisusb->obufsize-1));
 
 961                            packet.header  = 0x001f;
 
 962                            packet.address = 0x00000194;
 
 964                            ret = sisusb_send_bridge_packet(sisusb, 10,
 
 966                            packet.header  = 0x001f;
 
 967                            packet.address = 0x00000190;
 
 968                            packet.data    = (length & ~3);
 
 969                            ret |= sisusb_send_bridge_packet(sisusb, 10,
 
 971                            if (sisusb->flagb0 != 0x16) {
 
 972                                 packet.header  = 0x001f;
 
 973                                 packet.address = 0x00000180;
 
 974                                 packet.data    = flag | 0x16;
 
 975                                 ret |= sisusb_send_bridge_packet(sisusb, 10,
 
 977                                 sisusb->flagb0 = 0x16;
 
 980                                 ret |= sisusb_send_bulk_msg(sisusb,
 
 981                                                         SISUSB_EP_GFX_BULK_OUT,
 
 984                                                         bytes_written, 0, 1);
 
 985                                 userbuffer += (*bytes_written);
 
 986                            } else if (fromkern) {
 
 987                                 ret |= sisusb_send_bulk_msg(sisusb,
 
 988                                                         SISUSB_EP_GFX_BULK_OUT,
 
 991                                                         bytes_written, 0, 1);
 
 992                                 kernbuffer += (*bytes_written);
 
 994                                 ret |= sisusb_send_bulk_msg(sisusb,
 
 995                                                         SISUSB_EP_GFX_BULK_OUT,
 
 998                                                         bytes_written, 0, 1);
 
 999                                 kernbuffer += ((*bytes_written) &
 
1000                                                 (sisusb->obufsize-1));
 
1006                                         dev_err(&sisusb->sisusb_dev->dev, "Wrote %zd of %d bytes, error %d\n",
 
1007                                                 *bytes_written, length, ret);
 
1008                                 else if (msgcount == 500)
 
1009                                         dev_err(&sisusb->sisusb_dev->dev, "Too many errors, logging stopped\n");
 
1011                         addr += (*bytes_written);
 
1012                         length -= (*bytes_written);
 
1020         return ret ? -EIO : 0;
 
1023 /* Remember: Read data in packet is in machine-endianess! So for
 
1024  * byte, word, 24bit, long no endian correction is necessary.
 
1027 static int sisusb_read_memio_byte(struct sisusb_usb_data *sisusb, int type,
 
1030         struct sisusb_packet packet;
 
1033         CLEARPACKET(&packet);
 
1034         packet.header  = (1 << (addr & 3)) | (type << 6);
 
1035         packet.address = addr & ~3;
 
1036         ret = sisusb_send_packet(sisusb, 6, &packet);
 
1037         *data = (u8)(packet.data >> ((addr & 3) << 3));
 
1041 static int sisusb_read_memio_word(struct sisusb_usb_data *sisusb, int type,
 
1042                                                         u32 addr, u16 *data)
 
1044         struct sisusb_packet packet;
 
1047         CLEARPACKET(&packet);
 
1049         packet.address = addr & ~3;
 
1053                         packet.header = (type << 6) | 0x0003;
 
1054                         ret = sisusb_send_packet(sisusb, 6, &packet);
 
1055                         *data = (u16)(packet.data);
 
1058                         packet.header = (type << 6) | 0x0006;
 
1059                         ret = sisusb_send_packet(sisusb, 6, &packet);
 
1060                         *data = (u16)(packet.data >> 8);
 
1063                         packet.header = (type << 6) | 0x000c;
 
1064                         ret = sisusb_send_packet(sisusb, 6, &packet);
 
1065                         *data = (u16)(packet.data >> 16);
 
1068                         packet.header = (type << 6) | 0x0008;
 
1069                         ret = sisusb_send_packet(sisusb, 6, &packet);
 
1070                         *data = (u16)(packet.data >> 24);
 
1071                         packet.header = (type << 6) | 0x0001;
 
1072                         packet.address = (addr & ~3) + 4;
 
1073                         ret |= sisusb_send_packet(sisusb, 6, &packet);
 
1074                         *data |= (u16)(packet.data << 8);
 
1080 static int sisusb_read_memio_24bit(struct sisusb_usb_data *sisusb, int type,
 
1081                                                         u32 addr, u32 *data)
 
1083         struct sisusb_packet packet;
 
1086         packet.address = addr & ~3;
 
1090                         packet.header  = (type << 6) | 0x0007;
 
1091                         ret = sisusb_send_packet(sisusb, 6, &packet);
 
1092                         *data = packet.data & 0x00ffffff;
 
1095                         packet.header  = (type << 6) | 0x000e;
 
1096                         ret = sisusb_send_packet(sisusb, 6, &packet);
 
1097                         *data = packet.data >> 8;
 
1100                         packet.header  = (type << 6) | 0x000c;
 
1101                         ret = sisusb_send_packet(sisusb, 6, &packet);
 
1102                         *data = packet.data >> 16;
 
1103                         packet.header  = (type << 6) | 0x0001;
 
1104                         packet.address = (addr & ~3) + 4;
 
1105                         ret |= sisusb_send_packet(sisusb, 6, &packet);
 
1106                         *data |= ((packet.data & 0xff) << 16);
 
1109                         packet.header  = (type << 6) | 0x0008;
 
1110                         ret = sisusb_send_packet(sisusb, 6, &packet);
 
1111                         *data = packet.data >> 24;
 
1112                         packet.header  = (type << 6) | 0x0003;
 
1113                         packet.address = (addr & ~3) + 4;
 
1114                         ret |= sisusb_send_packet(sisusb, 6, &packet);
 
1115                         *data |= ((packet.data & 0xffff) << 8);
 
1121 static int sisusb_read_memio_long(struct sisusb_usb_data *sisusb, int type,
 
1122                                                         u32 addr, u32 *data)
 
1124         struct sisusb_packet packet;
 
1127         packet.address = addr & ~3;
 
1131                         packet.header  = (type << 6) | 0x000f;
 
1132                         ret = sisusb_send_packet(sisusb, 6, &packet);
 
1133                         *data = packet.data;
 
1136                         packet.header  = (type << 6) | 0x000e;
 
1137                         ret = sisusb_send_packet(sisusb, 6, &packet);
 
1138                         *data = packet.data >> 8;
 
1139                         packet.header  = (type << 6) | 0x0001;
 
1140                         packet.address = (addr & ~3) + 4;
 
1141                         ret |= sisusb_send_packet(sisusb, 6, &packet);
 
1142                         *data |= (packet.data << 24);
 
1145                         packet.header  = (type << 6) | 0x000c;
 
1146                         ret = sisusb_send_packet(sisusb, 6, &packet);
 
1147                         *data = packet.data >> 16;
 
1148                         packet.header  = (type << 6) | 0x0003;
 
1149                         packet.address = (addr & ~3) + 4;
 
1150                         ret |= sisusb_send_packet(sisusb, 6, &packet);
 
1151                         *data |= (packet.data << 16);
 
1154                         packet.header  = (type << 6) | 0x0008;
 
1155                         ret = sisusb_send_packet(sisusb, 6, &packet);
 
1156                         *data = packet.data >> 24;
 
1157                         packet.header  = (type << 6) | 0x0007;
 
1158                         packet.address = (addr & ~3) + 4;
 
1159                         ret |= sisusb_send_packet(sisusb, 6, &packet);
 
1160                         *data |= (packet.data << 8);
 
1166 static int sisusb_read_mem_bulk(struct sisusb_usb_data *sisusb, u32 addr,
 
1167                                 char *kernbuffer, int length,
 
1168                                 char __user *userbuffer, ssize_t *bytes_read)
 
1177         length &= 0x00ffffff;
 
1185                         ret |= sisusb_read_memio_byte(sisusb, SISUSB_TYPE_MEM,
 
1190                                         if (put_user(buf[0],
 
1191                                                 (u8 __user *)userbuffer)) {
 
1195                                         kernbuffer[0] = buf[0];
 
1201                         ret |= sisusb_read_memio_word(sisusb, SISUSB_TYPE_MEM,
 
1206                                         if (put_user(swap16,
 
1207                                                 (u16 __user *)userbuffer))
 
1210                                         *((u16 *)kernbuffer) = swap16;
 
1216                         ret |= sisusb_read_memio_24bit(sisusb, SISUSB_TYPE_MEM,
 
1221                                 buf[0] = (swap32 >> 16) & 0xff;
 
1222                                 buf[1] = (swap32 >> 8) & 0xff;
 
1223                                 buf[2] = swap32 & 0xff;
 
1225                                 buf[2] = (swap32 >> 16) & 0xff;
 
1226                                 buf[1] = (swap32 >> 8) & 0xff;
 
1227                                 buf[0] = swap32 & 0xff;
 
1230                                         if (copy_to_user(userbuffer, &buf[0], 3))
 
1233                                         kernbuffer[0] = buf[0];
 
1234                                         kernbuffer[1] = buf[1];
 
1235                                         kernbuffer[2] = buf[2];
 
1241                         ret |= sisusb_read_memio_long(sisusb, SISUSB_TYPE_MEM,
 
1246                                         if (put_user(swap32,
 
1247                                                 (u32 __user *)userbuffer))
 
1252                                         *((u32 *)kernbuffer) = swap32;
 
1267 /* High level: Gfx (indexed) register access */
 
1269 #ifdef INCL_SISUSB_CON
 
1271 sisusb_setreg(struct sisusb_usb_data *sisusb, int port, u8 data)
 
1273         return sisusb_write_memio_byte(sisusb, SISUSB_TYPE_IO, port, data);
 
1277 sisusb_getreg(struct sisusb_usb_data *sisusb, int port, u8 *data)
 
1279         return sisusb_read_memio_byte(sisusb, SISUSB_TYPE_IO, port, data);
 
1284 sisusb_setidxreg(struct sisusb_usb_data *sisusb, int port, u8 index, u8 data)
 
1287         ret = sisusb_write_memio_byte(sisusb, SISUSB_TYPE_IO, port, index);
 
1288         ret |= sisusb_write_memio_byte(sisusb, SISUSB_TYPE_IO, port + 1, data);
 
1293 sisusb_getidxreg(struct sisusb_usb_data *sisusb, int port, u8 index, u8 *data)
 
1296         ret = sisusb_write_memio_byte(sisusb, SISUSB_TYPE_IO, port, index);
 
1297         ret |= sisusb_read_memio_byte(sisusb, SISUSB_TYPE_IO, port + 1, data);
 
1302 sisusb_setidxregandor(struct sisusb_usb_data *sisusb, int port, u8 idx,
 
1308         ret = sisusb_write_memio_byte(sisusb, SISUSB_TYPE_IO, port, idx);
 
1309         ret |= sisusb_read_memio_byte(sisusb, SISUSB_TYPE_IO, port + 1, &tmp);
 
1312         ret |= sisusb_write_memio_byte(sisusb, SISUSB_TYPE_IO, port + 1, tmp);
 
1317 sisusb_setidxregmask(struct sisusb_usb_data *sisusb, int port, u8 idx,
 
1322         ret = sisusb_write_memio_byte(sisusb, SISUSB_TYPE_IO, port, idx);
 
1323         ret |= sisusb_read_memio_byte(sisusb, SISUSB_TYPE_IO, port + 1, &tmp);
 
1325         tmp |= (data & mask);
 
1326         ret |= sisusb_write_memio_byte(sisusb, SISUSB_TYPE_IO, port + 1, tmp);
 
1331 sisusb_setidxregor(struct sisusb_usb_data *sisusb, int port, u8 index, u8 myor)
 
1333         return(sisusb_setidxregandor(sisusb, port, index, 0xff, myor));
 
1337 sisusb_setidxregand(struct sisusb_usb_data *sisusb, int port, u8 idx, u8 myand)
 
1339         return(sisusb_setidxregandor(sisusb, port, idx, myand, 0x00));
 
1342 /* Write/read video ram */
 
1344 #ifdef INCL_SISUSB_CON
 
1346 sisusb_writeb(struct sisusb_usb_data *sisusb, u32 adr, u8 data)
 
1348         return(sisusb_write_memio_byte(sisusb, SISUSB_TYPE_MEM, adr, data));
 
1352 sisusb_readb(struct sisusb_usb_data *sisusb, u32 adr, u8 *data)
 
1354         return(sisusb_read_memio_byte(sisusb, SISUSB_TYPE_MEM, adr, data));
 
1358 sisusb_copy_memory(struct sisusb_usb_data *sisusb, char *src,
 
1359                         u32 dest, int length, size_t *bytes_written)
 
1361         return(sisusb_write_mem_bulk(sisusb, dest, src, length, NULL, 0, bytes_written));
 
1364 #ifdef SISUSBENDIANTEST
 
1366 sisusb_read_memory(struct sisusb_usb_data *sisusb, char *dest,
 
1367                         u32 src, int length, size_t *bytes_written)
 
1369         return(sisusb_read_mem_bulk(sisusb, src, dest, length, NULL, bytes_written));
 
1374 #ifdef SISUSBENDIANTEST
 
1376 sisusb_testreadwrite(struct sisusb_usb_data *sisusb)
 
1378     static char srcbuffer[] = { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 };
 
1379     char destbuffer[10];
 
1383     sisusb_copy_memory(sisusb, srcbuffer, sisusb->vrambase, 7, &dummy);
 
1385     for(i = 1; i <= 7; i++) {
 
1386         dev_dbg(&sisusb->sisusb_dev->dev, "sisusb: rwtest %d bytes\n", i);
 
1387         sisusb_read_memory(sisusb, destbuffer, sisusb->vrambase, i, &dummy);
 
1388         for(j = 0; j < i; j++) {
 
1389              dev_dbg(&sisusb->sisusb_dev->dev, "rwtest read[%d] = %x\n", j, destbuffer[j]);
 
1395 /* access pci config registers (reg numbers 0, 4, 8, etc) */
 
1398 sisusb_write_pci_config(struct sisusb_usb_data *sisusb, int regnum, u32 data)
 
1400         struct sisusb_packet packet;
 
1403         packet.header = 0x008f;
 
1404         packet.address = regnum | 0x10000;
 
1406         ret = sisusb_send_packet(sisusb, 10, &packet);
 
1411 sisusb_read_pci_config(struct sisusb_usb_data *sisusb, int regnum, u32 *data)
 
1413         struct sisusb_packet packet;
 
1416         packet.header = 0x008f;
 
1417         packet.address = (u32)regnum | 0x10000;
 
1418         ret = sisusb_send_packet(sisusb, 6, &packet);
 
1419         *data = packet.data;
 
1423 /* Clear video RAM */
 
1426 sisusb_clear_vram(struct sisusb_usb_data *sisusb, u32 address, int length)
 
1431         if (address < sisusb->vrambase)
 
1434         if (address >= sisusb->vrambase + sisusb->vramsize)
 
1437         if (address + length > sisusb->vrambase + sisusb->vramsize)
 
1438                 length = sisusb->vrambase + sisusb->vramsize - address;
 
1443         /* allocate free buffer/urb and clear the buffer */
 
1444         if ((i = sisusb_alloc_outbuf(sisusb)) < 0)
 
1447         memset(sisusb->obuf[i], 0, sisusb->obufsize);
 
1449         /* We can write a length > buffer size here. The buffer
 
1450          * data will simply be re-used (like a ring-buffer).
 
1452         ret = sisusb_write_mem_bulk(sisusb, address, NULL, length, NULL, i, &j);
 
1454         /* Free the buffer/urb */
 
1455         sisusb_free_outbuf(sisusb, i);
 
1460 /* Initialize the graphics core (return 0 on success)
 
1461  * This resets the graphics hardware and puts it into
 
1462  * a defined mode (640x480@60Hz)
 
1465 #define GETREG(r,d)     sisusb_read_memio_byte(sisusb, SISUSB_TYPE_IO, r, d)
 
1466 #define SETREG(r,d)     sisusb_write_memio_byte(sisusb, SISUSB_TYPE_IO, r, d)
 
1467 #define SETIREG(r,i,d)  sisusb_setidxreg(sisusb, r, i, d)
 
1468 #define GETIREG(r,i,d)  sisusb_getidxreg(sisusb, r, i, d)
 
1469 #define SETIREGOR(r,i,o)        sisusb_setidxregor(sisusb, r, i, o)
 
1470 #define SETIREGAND(r,i,a)       sisusb_setidxregand(sisusb, r, i, a)
 
1471 #define SETIREGANDOR(r,i,a,o)   sisusb_setidxregandor(sisusb, r, i, a, o)
 
1472 #define READL(a,d)      sisusb_read_memio_long(sisusb, SISUSB_TYPE_MEM, a, d)
 
1473 #define WRITEL(a,d)     sisusb_write_memio_long(sisusb, SISUSB_TYPE_MEM, a, d)
 
1474 #define READB(a,d)      sisusb_read_memio_byte(sisusb, SISUSB_TYPE_MEM, a, d)
 
1475 #define WRITEB(a,d)     sisusb_write_memio_byte(sisusb, SISUSB_TYPE_MEM, a, d)
 
1478 sisusb_triggersr16(struct sisusb_usb_data *sisusb, u8 ramtype)
 
1483         ret = GETIREG(SISSR, 0x16, &tmp8);
 
1486                 ret |= SETIREG(SISSR, 0x16, tmp8);
 
1488                 ret |= SETIREG(SISSR, 0x16, tmp8);
 
1491                 ret |= SETIREG(SISSR, 0x16, tmp8);
 
1493                 ret |= SETIREG(SISSR, 0x16, tmp8);
 
1495                 ret |= SETIREG(SISSR, 0x16, tmp8);
 
1497                 ret |= SETIREG(SISSR, 0x16, tmp8);
 
1499                 ret |= SETIREG(SISSR, 0x16, tmp8);
 
1501                 ret |= SETIREG(SISSR, 0x16, tmp8);
 
1503                 ret |= SETIREG(SISSR, 0x16, tmp8);
 
1509 sisusb_getbuswidth(struct sisusb_usb_data *sisusb, int *bw, int *chab)
 
1512         u8  ramtype, done = 0;
 
1514         u32 ramptr = SISUSB_PCI_MEMBASE;
 
1516         ret = GETIREG(SISSR, 0x3a, &ramtype);
 
1519         ret |= SETIREG(SISSR, 0x13, 0x00);
 
1522                 ret |= SETIREG(SISSR, 0x14, 0x12);
 
1523                 ret |= SETIREGAND(SISSR, 0x15, 0xef);
 
1525                 ret |= SETIREG(SISSR, 0x14, 0x02);
 
1528         ret |= sisusb_triggersr16(sisusb, ramtype);
 
1529         ret |= WRITEL(ramptr +  0, 0x01234567);
 
1530         ret |= WRITEL(ramptr +  4, 0x456789ab);
 
1531         ret |= WRITEL(ramptr +  8, 0x89abcdef);
 
1532         ret |= WRITEL(ramptr + 12, 0xcdef0123);
 
1533         ret |= WRITEL(ramptr + 16, 0x55555555);
 
1534         ret |= WRITEL(ramptr + 20, 0x55555555);
 
1535         ret |= WRITEL(ramptr + 24, 0xffffffff);
 
1536         ret |= WRITEL(ramptr + 28, 0xffffffff);
 
1537         ret |= READL(ramptr +  0, &t0);
 
1538         ret |= READL(ramptr +  4, &t1);
 
1539         ret |= READL(ramptr +  8, &t2);
 
1540         ret |= READL(ramptr + 12, &t3);
 
1544                 *chab = 0; *bw = 64;
 
1546                 if ((t3 != 0xcdef0123) || (t2 != 0x89abcdef)) {
 
1547                         if ((t1 == 0x456789ab) && (t0 == 0x01234567)) {
 
1548                                 *chab = 0; *bw = 64;
 
1549                                 ret |= SETIREGAND(SISSR, 0x14, 0xfd);
 
1552                 if ((t1 != 0x456789ab) || (t0 != 0x01234567)) {
 
1553                         *chab = 1; *bw = 64;
 
1554                         ret |= SETIREGANDOR(SISSR, 0x14, 0xfc,0x01);
 
1556                         ret |= sisusb_triggersr16(sisusb, ramtype);
 
1557                         ret |= WRITEL(ramptr +  0, 0x89abcdef);
 
1558                         ret |= WRITEL(ramptr +  4, 0xcdef0123);
 
1559                         ret |= WRITEL(ramptr +  8, 0x55555555);
 
1560                         ret |= WRITEL(ramptr + 12, 0x55555555);
 
1561                         ret |= WRITEL(ramptr + 16, 0xaaaaaaaa);
 
1562                         ret |= WRITEL(ramptr + 20, 0xaaaaaaaa);
 
1563                         ret |= READL(ramptr +  4, &t1);
 
1565                         if (t1 != 0xcdef0123) {
 
1567                                 ret |= SETIREGOR(SISSR, 0x15, 0x10);
 
1573                 *chab = 0; *bw = 64;    /* default: cha, bw = 64 */
 
1577                 if (t1 == 0x456789ab) {
 
1578                         if (t0 == 0x01234567) {
 
1579                                 *chab = 0; *bw = 64;
 
1583                         if (t0 == 0x01234567) {
 
1584                                 *chab = 0; *bw = 32;
 
1585                                 ret |= SETIREG(SISSR, 0x14, 0x00);
 
1591                         ret |= SETIREG(SISSR, 0x14, 0x03);
 
1592                         ret |= sisusb_triggersr16(sisusb, ramtype);
 
1594                         ret |= WRITEL(ramptr +  0, 0x01234567);
 
1595                         ret |= WRITEL(ramptr +  4, 0x456789ab);
 
1596                         ret |= WRITEL(ramptr +  8, 0x89abcdef);
 
1597                         ret |= WRITEL(ramptr + 12, 0xcdef0123);
 
1598                         ret |= WRITEL(ramptr + 16, 0x55555555);
 
1599                         ret |= WRITEL(ramptr + 20, 0x55555555);
 
1600                         ret |= WRITEL(ramptr + 24, 0xffffffff);
 
1601                         ret |= WRITEL(ramptr + 28, 0xffffffff);
 
1602                         ret |= READL(ramptr +  0, &t0);
 
1603                         ret |= READL(ramptr +  4, &t1);
 
1605                         if (t1 == 0x456789ab) {
 
1606                                 if (t0 == 0x01234567) {
 
1607                                         *chab = 1; *bw = 64;
 
1611                                 if (t0 == 0x01234567) {
 
1612                                         *chab = 1; *bw = 32;
 
1613                                         ret |= SETIREG(SISSR, 0x14, 0x01);
 
1622 sisusb_verify_mclk(struct sisusb_usb_data *sisusb)
 
1625         u32 ramptr = SISUSB_PCI_MEMBASE;
 
1626         u8 tmp1, tmp2, i, j;
 
1628         ret |= WRITEB(ramptr, 0xaa);
 
1629         ret |= WRITEB(ramptr + 16, 0x55);
 
1630         ret |= READB(ramptr, &tmp1);
 
1631         ret |= READB(ramptr + 16, &tmp2);
 
1632         if ((tmp1 != 0xaa) || (tmp2 != 0x55)) {
 
1633                 for (i = 0, j = 16; i < 2; i++, j += 16) {
 
1634                         ret |= GETIREG(SISSR, 0x21, &tmp1);
 
1635                         ret |= SETIREGAND(SISSR, 0x21, (tmp1 & 0xfb));
 
1636                         ret |= SETIREGOR(SISSR, 0x3c, 0x01);  /* not on 330 */
 
1637                         ret |= SETIREGAND(SISSR, 0x3c, 0xfe); /* not on 330 */
 
1638                         ret |= SETIREG(SISSR, 0x21, tmp1);
 
1639                         ret |= WRITEB(ramptr + 16 + j, j);
 
1640                         ret |= READB(ramptr + 16 + j, &tmp1);
 
1642                                 ret |= WRITEB(ramptr + j, j);
 
1651 sisusb_set_rank(struct sisusb_usb_data *sisusb, int *iret, int index,
 
1652                         u8 rankno, u8 chab, const u8 dramtype[][5],
 
1655         int ret = 0, ranksize;
 
1660         if ((rankno == 2) && (dramtype[index][0] == 2))
 
1663         ranksize = dramtype[index][3] / 2 * bw / 32;
 
1665         if ((ranksize * rankno) > 128)
 
1669         while ((ranksize >>= 1) > 0) tmp += 0x10;
 
1670         tmp |= ((rankno - 1) << 2);
 
1671         tmp |= ((bw / 64) & 0x02);
 
1672         tmp |= (chab & 0x01);
 
1674         ret = SETIREG(SISSR, 0x14, tmp);
 
1675         ret |= sisusb_triggersr16(sisusb, 0); /* sic! */
 
1683 sisusb_check_rbc(struct sisusb_usb_data *sisusb, int *iret, u32 inc, int testn)
 
1690         for (i = 0, j = 0; i < testn; i++) {
 
1691                 ret |= WRITEL(sisusb->vrambase + j, j);
 
1695         for (i = 0, j = 0; i < testn; i++) {
 
1696                 ret |= READL(sisusb->vrambase + j, &tmp);
 
1697                 if (tmp != j) return ret;
 
1706 sisusb_check_ranks(struct sisusb_usb_data *sisusb, int *iret, int rankno,
 
1707                                         int idx, int bw, const u8 rtype[][5])
 
1709         int ret = 0, i, i2ret;
 
1714         for (i = rankno; i >= 1; i--) {
 
1715                 inc = 1 << (rtype[idx][2] +
 
1719                 ret |= sisusb_check_rbc(sisusb, &i2ret, inc, 2);
 
1724         inc = 1 << (rtype[idx][2] + bw / 64 + 2);
 
1725         ret |= sisusb_check_rbc(sisusb, &i2ret, inc, 4);
 
1729         inc = 1 << (10 + bw / 64);
 
1730         ret |= sisusb_check_rbc(sisusb, &i2ret, inc, 2);
 
1739 sisusb_get_sdram_size(struct sisusb_usb_data *sisusb, int *iret, int bw,
 
1742         int ret = 0, i2ret = 0, i, j;
 
1743         static const u8 sdramtype[13][5] = {
 
1744                 { 2, 12, 9, 64, 0x35 },
 
1745                 { 1, 13, 9, 64, 0x44 },
 
1746                 { 2, 12, 8, 32, 0x31 },
 
1747                 { 2, 11, 9, 32, 0x25 },
 
1748                 { 1, 12, 9, 32, 0x34 },
 
1749                 { 1, 13, 8, 32, 0x40 },
 
1750                 { 2, 11, 8, 16, 0x21 },
 
1751                 { 1, 12, 8, 16, 0x30 },
 
1752                 { 1, 11, 9, 16, 0x24 },
 
1753                 { 1, 11, 8,  8, 0x20 },
 
1754                 { 2,  9, 8,  4, 0x01 },
 
1755                 { 1, 10, 8,  4, 0x10 },
 
1756                 { 1,  9, 8,  2, 0x00 }
 
1759         *iret = 1; /* error */
 
1761         for (i = 0; i < 13; i++) {
 
1762                 ret |= SETIREGANDOR(SISSR, 0x13, 0x80, sdramtype[i][4]);
 
1763                 for (j = 2; j > 0; j--) {
 
1764                         ret |= sisusb_set_rank(sisusb, &i2ret, i, j,
 
1765                                                 chab, sdramtype, bw);
 
1769                         ret |= sisusb_check_ranks(sisusb, &i2ret, j, i,
 
1772                                 *iret = 0;      /* ram size found */
 
1782 sisusb_setup_screen(struct sisusb_usb_data *sisusb, int clrall, int drwfr)
 
1786         int i, length, modex, modey, bpp;
 
1788         modex = 640; modey = 480; bpp = 2;
 
1790         address = sisusb->vrambase;     /* Clear video ram */
 
1793                 length = sisusb->vramsize;
 
1795                 length = modex * bpp * modey;
 
1797         ret = sisusb_clear_vram(sisusb, address, length);
 
1799         if (!ret && drwfr) {
 
1800                 for (i = 0; i < modex; i++) {
 
1801                         address = sisusb->vrambase + (i * bpp);
 
1802                         ret |= sisusb_write_memio_word(sisusb, SISUSB_TYPE_MEM,
 
1804                         address += (modex * (modey-1) * bpp);
 
1805                         ret |= sisusb_write_memio_word(sisusb, SISUSB_TYPE_MEM,
 
1808                 for (i = 0; i < modey; i++) {
 
1809                         address = sisusb->vrambase + ((i * modex) * bpp);
 
1810                         ret |= sisusb_write_memio_word(sisusb, SISUSB_TYPE_MEM,
 
1812                         address += ((modex - 1) * bpp);
 
1813                         ret |= sisusb_write_memio_word(sisusb, SISUSB_TYPE_MEM,
 
1822 sisusb_set_default_mode(struct sisusb_usb_data *sisusb, int touchengines)
 
1824         int ret = 0, i, j, modex, modey, bpp, du;
 
1825         u8 sr31, cr63, tmp8;
 
1826         static const char attrdata[] = {
 
1827                 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
 
1828                 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
 
1831         static const char crtcrdata[] = {
 
1832                 0x5f,0x4f,0x50,0x82,0x54,0x80,0x0b,0x3e,
 
1833                 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
 
1834                 0xea,0x8c,0xdf,0x28,0x40,0xe7,0x04,0xa3,
 
1837         static const char grcdata[] = {
 
1838                 0x00,0x00,0x00,0x00,0x00,0x40,0x05,0x0f,
 
1841         static const char crtcdata[] = {
 
1842                 0x5f,0x4f,0x4f,0x83,0x55,0x81,0x0b,0x3e,
 
1843                 0xe9,0x8b,0xdf,0xe8,0x0c,0x00,0x00,0x05,
 
1847         modex = 640; modey = 480; bpp = 2;
 
1849         GETIREG(SISSR, 0x31, &sr31);
 
1850         GETIREG(SISCR, 0x63, &cr63);
 
1851         SETIREGOR(SISSR, 0x01, 0x20);
 
1852         SETIREG(SISCR, 0x63, cr63 & 0xbf);
 
1853         SETIREGOR(SISCR, 0x17, 0x80);
 
1854         SETIREGOR(SISSR, 0x1f, 0x04);
 
1855         SETIREGAND(SISSR, 0x07, 0xfb);
 
1856         SETIREG(SISSR, 0x00, 0x03);     /* seq */
 
1857         SETIREG(SISSR, 0x01, 0x21);
 
1858         SETIREG(SISSR, 0x02, 0x0f);
 
1859         SETIREG(SISSR, 0x03, 0x00);
 
1860         SETIREG(SISSR, 0x04, 0x0e);
 
1861         SETREG(SISMISCW, 0x23);         /* misc */
 
1862         for (i = 0; i <= 0x18; i++) {   /* crtc */
 
1863                 SETIREG(SISCR, i, crtcrdata[i]);
 
1865         for (i = 0; i <= 0x13; i++) {   /* att */
 
1866                 GETREG(SISINPSTAT, &tmp8);
 
1868                 SETREG(SISAR, attrdata[i]);
 
1870         GETREG(SISINPSTAT, &tmp8);
 
1871         SETREG(SISAR, 0x14);
 
1872         SETREG(SISAR, 0x00);
 
1873         GETREG(SISINPSTAT, &tmp8);
 
1874         SETREG(SISAR, 0x20);
 
1875         GETREG(SISINPSTAT, &tmp8);
 
1876         for (i = 0; i <= 0x08; i++) {   /* grc */
 
1877                 SETIREG(SISGR, i, grcdata[i]);
 
1879         SETIREGAND(SISGR, 0x05, 0xbf);
 
1880         for (i = 0x0A; i <= 0x0E; i++) {        /* clr ext */
 
1881                 SETIREG(SISSR, i, 0x00);
 
1883         SETIREGAND(SISSR, 0x37, 0xfe);
 
1884         SETREG(SISMISCW, 0xef);         /* sync */
 
1885         SETIREG(SISCR, 0x11, 0x00);     /* crtc */
 
1886         for (j = 0x00, i = 0; i <= 7; i++, j++) {
 
1887                 SETIREG(SISCR, j, crtcdata[i]);
 
1889         for (j = 0x10; i <= 10; i++, j++) {
 
1890                 SETIREG(SISCR, j, crtcdata[i]);
 
1892         for (j = 0x15; i <= 12; i++, j++) {
 
1893                 SETIREG(SISCR, j, crtcdata[i]);
 
1895         for (j = 0x0A; i <= 15; i++, j++) {
 
1896                 SETIREG(SISSR, j, crtcdata[i]);
 
1898         SETIREG(SISSR, 0x0E, (crtcdata[16] & 0xE0));
 
1899         SETIREGANDOR(SISCR, 0x09, 0x5f, ((crtcdata[16] & 0x01) << 5));
 
1900         SETIREG(SISCR, 0x14, 0x4f);
 
1901         du = (modex / 16) * (bpp * 2);  /* offset/pitch */
 
1902         if (modex % 16) du += bpp;
 
1903         SETIREGANDOR(SISSR, 0x0e, 0xf0, ((du >> 8) & 0x0f));
 
1904         SETIREG(SISCR, 0x13, (du & 0xff));
 
1907         if (du & 0xff) tmp8++;
 
1908         SETIREG(SISSR, 0x10, tmp8);
 
1909         SETIREG(SISSR, 0x31, 0x00);     /* VCLK */
 
1910         SETIREG(SISSR, 0x2b, 0x1b);
 
1911         SETIREG(SISSR, 0x2c, 0xe1);
 
1912         SETIREG(SISSR, 0x2d, 0x01);
 
1913         SETIREGAND(SISSR, 0x3d, 0xfe);  /* FIFO */
 
1914         SETIREG(SISSR, 0x08, 0xae);
 
1915         SETIREGAND(SISSR, 0x09, 0xf0);
 
1916         SETIREG(SISSR, 0x08, 0x34);
 
1917         SETIREGOR(SISSR, 0x3d, 0x01);
 
1918         SETIREGAND(SISSR, 0x1f, 0x3f);  /* mode regs */
 
1919         SETIREGANDOR(SISSR, 0x06, 0xc0, 0x0a);
 
1920         SETIREG(SISCR, 0x19, 0x00);
 
1921         SETIREGAND(SISCR, 0x1a, 0xfc);
 
1922         SETIREGAND(SISSR, 0x0f, 0xb7);
 
1923         SETIREGAND(SISSR, 0x31, 0xfb);
 
1924         SETIREGANDOR(SISSR, 0x21, 0x1f, 0xa0);
 
1925         SETIREGAND(SISSR, 0x32, 0xf3);
 
1926         SETIREGANDOR(SISSR, 0x07, 0xf8, 0x03);
 
1927         SETIREG(SISCR, 0x52, 0x6c);
 
1929         SETIREG(SISCR, 0x0d, 0x00);     /* adjust frame */
 
1930         SETIREG(SISCR, 0x0c, 0x00);
 
1931         SETIREG(SISSR, 0x0d, 0x00);
 
1932         SETIREGAND(SISSR, 0x37, 0xfe);
 
1934         SETIREG(SISCR, 0x32, 0x20);
 
1935         SETIREGAND(SISSR, 0x01, 0xdf);  /* enable display */
 
1936         SETIREG(SISCR, 0x63, (cr63 & 0xbf));
 
1937         SETIREG(SISSR, 0x31, (sr31 & 0xfb));
 
1940                 SETIREG(SISSR, 0x20, 0xa1);     /* enable engines */
 
1941                 SETIREGOR(SISSR, 0x1e, 0x5a);
 
1943                 SETIREG(SISSR, 0x26, 0x01);     /* disable cmdqueue */
 
1944                 SETIREG(SISSR, 0x27, 0x1f);
 
1945                 SETIREG(SISSR, 0x26, 0x00);
 
1948         SETIREG(SISCR, 0x34, 0x44);     /* we just set std mode #44 */
 
1954 sisusb_init_gfxcore(struct sisusb_usb_data *sisusb)
 
1956         int ret = 0, i, j, bw, chab, iret, retry = 3;
 
1959         static const char mclktable[] = {
 
1960                 0x3b, 0x22, 0x01, 143,
 
1961                 0x3b, 0x22, 0x01, 143,
 
1962                 0x3b, 0x22, 0x01, 143,
 
1963                 0x3b, 0x22, 0x01, 143
 
1965         static const char eclktable[] = {
 
1966                 0x3b, 0x22, 0x01, 143,
 
1967                 0x3b, 0x22, 0x01, 143,
 
1968                 0x3b, 0x22, 0x01, 143,
 
1969                 0x3b, 0x22, 0x01, 143
 
1971         static const char ramtypetable1[] = {
 
1972                 0x00, 0x04, 0x60, 0x60,
 
1973                 0x0f, 0x0f, 0x1f, 0x1f,
 
1974                 0xba, 0xba, 0xba, 0xba,
 
1975                 0xa9, 0xa9, 0xac, 0xac,
 
1976                 0xa0, 0xa0, 0xa0, 0xa8,
 
1977                 0x00, 0x00, 0x02, 0x02,
 
1978                 0x30, 0x30, 0x40, 0x40
 
1980         static const char ramtypetable2[] = {
 
1981                 0x77, 0x77, 0x44, 0x44,
 
1982                 0x77, 0x77, 0x44, 0x44,
 
1983                 0x00, 0x00, 0x00, 0x00,
 
1984                 0x5b, 0x5b, 0xab, 0xab,
 
1985                 0x00, 0x00, 0xf0, 0xf8
 
1991                 ret = GETREG(SISVGAEN, &tmp8);
 
1992                 ret |= SETREG(SISVGAEN, (tmp8 | 0x01));
 
1994                 /* Enable GPU access to VRAM */
 
1995                 ret |= GETREG(SISMISCR, &tmp8);
 
1996                 ret |= SETREG(SISMISCW, (tmp8 | 0x01));
 
2000                 /* Reset registers */
 
2001                 ret |= SETIREGAND(SISCR, 0x5b, 0xdf);
 
2002                 ret |= SETIREG(SISSR, 0x05, 0x86);
 
2003                 ret |= SETIREGOR(SISSR, 0x20, 0x01);
 
2005                 ret |= SETREG(SISMISCW, 0x67);
 
2007                 for (i = 0x06; i <= 0x1f; i++) {
 
2008                         ret |= SETIREG(SISSR, i, 0x00);
 
2010                 for (i = 0x21; i <= 0x27; i++) {
 
2011                         ret |= SETIREG(SISSR, i, 0x00);
 
2013                 for (i = 0x31; i <= 0x3d; i++) {
 
2014                         ret |= SETIREG(SISSR, i, 0x00);
 
2016                 for (i = 0x12; i <= 0x1b; i++) {
 
2017                         ret |= SETIREG(SISSR, i, 0x00);
 
2019                 for (i = 0x79; i <= 0x7c; i++) {
 
2020                         ret |= SETIREG(SISCR, i, 0x00);
 
2025                 ret |= SETIREG(SISCR, 0x63, 0x80);
 
2027                 ret |= GETIREG(SISSR, 0x3a, &ramtype);
 
2030                 ret |= SETIREG(SISSR, 0x28, mclktable[ramtype * 4]);
 
2031                 ret |= SETIREG(SISSR, 0x29, mclktable[(ramtype * 4) + 1]);
 
2032                 ret |= SETIREG(SISSR, 0x2a, mclktable[(ramtype * 4) + 2]);
 
2034                 ret |= SETIREG(SISSR, 0x2e, eclktable[ramtype * 4]);
 
2035                 ret |= SETIREG(SISSR, 0x2f, eclktable[(ramtype * 4) + 1]);
 
2036                 ret |= SETIREG(SISSR, 0x30, eclktable[(ramtype * 4) + 2]);
 
2038                 ret |= SETIREG(SISSR, 0x07, 0x18);
 
2039                 ret |= SETIREG(SISSR, 0x11, 0x0f);
 
2043                 for (i = 0x15, j = 0; i <= 0x1b; i++, j++) {
 
2044                         ret |= SETIREG(SISSR, i, ramtypetable1[(j*4) + ramtype]);
 
2046                 for (i = 0x40, j = 0; i <= 0x44; i++, j++) {
 
2047                         ret |= SETIREG(SISCR, i, ramtypetable2[(j*4) + ramtype]);
 
2050                 ret |= SETIREG(SISCR, 0x49, 0xaa);
 
2052                 ret |= SETIREG(SISSR, 0x1f, 0x00);
 
2053                 ret |= SETIREG(SISSR, 0x20, 0xa0);
 
2054                 ret |= SETIREG(SISSR, 0x23, 0xf6);
 
2055                 ret |= SETIREG(SISSR, 0x24, 0x0d);
 
2056                 ret |= SETIREG(SISSR, 0x25, 0x33);
 
2058                 ret |= SETIREG(SISSR, 0x11, 0x0f);
 
2060                 ret |= SETIREGOR(SISPART1, 0x2f, 0x01);
 
2062                 ret |= SETIREGAND(SISCAP, 0x3f, 0xef);
 
2066                 ret |= SETIREG(SISPART1, 0x00, 0x00);
 
2068                 ret |= GETIREG(SISSR, 0x13, &tmp8);
 
2071                 ret |= SETIREG(SISPART1, 0x02, 0x00);
 
2072                 ret |= SETIREG(SISPART1, 0x2e, 0x08);
 
2074                 ret |= sisusb_read_pci_config(sisusb, 0x50, &tmp32);
 
2075                 tmp32 &= 0x00f00000;
 
2076                 tmp8 = (tmp32 == 0x100000) ? 0x33 : 0x03;
 
2077                 ret |= SETIREG(SISSR, 0x25, tmp8);
 
2078                 tmp8 = (tmp32 == 0x100000) ? 0xaa : 0x88;
 
2079                 ret |= SETIREG(SISCR, 0x49, tmp8);
 
2081                 ret |= SETIREG(SISSR, 0x27, 0x1f);
 
2082                 ret |= SETIREG(SISSR, 0x31, 0x00);
 
2083                 ret |= SETIREG(SISSR, 0x32, 0x11);
 
2084                 ret |= SETIREG(SISSR, 0x33, 0x00);
 
2088                 ret |= SETIREG(SISCR, 0x83, 0x00);
 
2090                 ret |= sisusb_set_default_mode(sisusb, 0);
 
2092                 ret |= SETIREGAND(SISSR, 0x21, 0xdf);
 
2093                 ret |= SETIREGOR(SISSR, 0x01, 0x20);
 
2094                 ret |= SETIREGOR(SISSR, 0x16, 0x0f);
 
2096                 ret |= sisusb_triggersr16(sisusb, ramtype);
 
2098                 /* Disable refresh */
 
2099                 ret |= SETIREGAND(SISSR, 0x17, 0xf8);
 
2100                 ret |= SETIREGOR(SISSR, 0x19, 0x03);
 
2102                 ret |= sisusb_getbuswidth(sisusb, &bw, &chab);
 
2103                 ret |= sisusb_verify_mclk(sisusb);
 
2106                         ret |= sisusb_get_sdram_size(sisusb, &iret, bw, chab);
 
2108                                 dev_err(&sisusb->sisusb_dev->dev,"RAM size detection failed, assuming 8MB video RAM\n");
 
2109                                 ret |= SETIREG(SISSR,0x14,0x31);
 
2113                         dev_err(&sisusb->sisusb_dev->dev, "DDR RAM device found, assuming 8MB video RAM\n");
 
2114                         ret |= SETIREG(SISSR,0x14,0x31);
 
2118                 /* Enable refresh */
 
2119                 ret |= SETIREG(SISSR, 0x16, ramtypetable1[4 + ramtype]);
 
2120                 ret |= SETIREG(SISSR, 0x17, ramtypetable1[8 + ramtype]);
 
2121                 ret |= SETIREG(SISSR, 0x19, ramtypetable1[16 + ramtype]);
 
2123                 ret |= SETIREGOR(SISSR, 0x21, 0x20);
 
2125                 ret |= SETIREG(SISSR, 0x22, 0xfb);
 
2126                 ret |= SETIREG(SISSR, 0x21, 0xa5);
 
2146 sisusb_get_ramconfig(struct sisusb_usb_data *sisusb)
 
2148         u8 tmp8, tmp82, ramtype;
 
2150         char *ramtypetext1 = NULL;
 
2151         const char *ramtypetext2[] = {  "SDR SDRAM", "SDR SGRAM",
 
2152                                         "DDR SDRAM", "DDR SGRAM" };
 
2153         static const int busSDR[4]  = {64, 64, 128, 128};
 
2154         static const int busDDR[4]  = {32, 32,  64,  64};
 
2155         static const int busDDRA[4] = {64+32, 64+32 , (64+32)*2, (64+32)*2};
 
2157         sisusb_getidxreg(sisusb, SISSR, 0x14, &tmp8);
 
2158         sisusb_getidxreg(sisusb, SISSR, 0x15, &tmp82);
 
2159         sisusb_getidxreg(sisusb, SISSR, 0x3a, &ramtype);
 
2160         sisusb->vramsize = (1 << ((tmp8 & 0xf0) >> 4)) * 1024 * 1024;
 
2162         switch ((tmp8 >> 2) & 0x03) {
 
2163         case 0: ramtypetext1 = "1 ch/1 r";
 
2167                         bw = busSDR[(tmp8 & 0x03)];
 
2170         case 1: ramtypetext1 = "1 ch/2 r";
 
2171                 sisusb->vramsize <<= 1;
 
2172                 bw = busSDR[(tmp8 & 0x03)];
 
2174         case 2: ramtypetext1 = "asymmeric";
 
2175                 sisusb->vramsize += sisusb->vramsize/2;
 
2176                 bw = busDDRA[(tmp8 & 0x03)];
 
2178         case 3: ramtypetext1 = "2 channel";
 
2179                 sisusb->vramsize <<= 1;
 
2180                 bw = busDDR[(tmp8 & 0x03)];
 
2184         dev_info(&sisusb->sisusb_dev->dev, "%dMB %s %s, bus width %d\n", (sisusb->vramsize >> 20), ramtypetext1,
 
2185                         ramtypetext2[ramtype], bw);
 
2189 sisusb_do_init_gfxdevice(struct sisusb_usb_data *sisusb)
 
2191         struct sisusb_packet packet;
 
2196         packet.header  = 0x001f;
 
2197         packet.address = 0x00000324;
 
2198         packet.data    = 0x00000004;
 
2199         ret = sisusb_send_bridge_packet(sisusb, 10, &packet, 0);
 
2201         packet.header  = 0x001f;
 
2202         packet.address = 0x00000364;
 
2203         packet.data    = 0x00000004;
 
2204         ret |= sisusb_send_bridge_packet(sisusb, 10, &packet, 0);
 
2206         packet.header  = 0x001f;
 
2207         packet.address = 0x00000384;
 
2208         packet.data    = 0x00000004;
 
2209         ret |= sisusb_send_bridge_packet(sisusb, 10, &packet, 0);
 
2211         packet.header  = 0x001f;
 
2212         packet.address = 0x00000100;
 
2213         packet.data    = 0x00000700;
 
2214         ret |= sisusb_send_bridge_packet(sisusb, 10, &packet, 0);
 
2216         packet.header  = 0x000f;
 
2217         packet.address = 0x00000004;
 
2218         ret |= sisusb_send_bridge_packet(sisusb, 6, &packet, 0);
 
2219         packet.data |= 0x17;
 
2220         ret |= sisusb_send_bridge_packet(sisusb, 10, &packet, 0);
 
2222         /* Init BAR 0 (VRAM) */
 
2223         ret |= sisusb_read_pci_config(sisusb, 0x10, &tmp32);
 
2224         ret |= sisusb_write_pci_config(sisusb, 0x10, 0xfffffff0);
 
2225         ret |= sisusb_read_pci_config(sisusb, 0x10, &tmp32);
 
2227         tmp32 |= SISUSB_PCI_MEMBASE;
 
2228         ret |= sisusb_write_pci_config(sisusb, 0x10, tmp32);
 
2230         /* Init BAR 1 (MMIO) */
 
2231         ret |= sisusb_read_pci_config(sisusb, 0x14, &tmp32);
 
2232         ret |= sisusb_write_pci_config(sisusb, 0x14, 0xfffffff0);
 
2233         ret |= sisusb_read_pci_config(sisusb, 0x14, &tmp32);
 
2235         tmp32 |= SISUSB_PCI_MMIOBASE;
 
2236         ret |= sisusb_write_pci_config(sisusb, 0x14, tmp32);
 
2238         /* Init BAR 2 (i/o ports) */
 
2239         ret |= sisusb_read_pci_config(sisusb, 0x18, &tmp32);
 
2240         ret |= sisusb_write_pci_config(sisusb, 0x18, 0xfffffff0);
 
2241         ret |= sisusb_read_pci_config(sisusb, 0x18, &tmp32);
 
2243         tmp32 |= SISUSB_PCI_IOPORTBASE;
 
2244         ret |= sisusb_write_pci_config(sisusb, 0x18, tmp32);
 
2246         /* Enable memory and i/o access */
 
2247         ret |= sisusb_read_pci_config(sisusb, 0x04, &tmp32);
 
2249         ret |= sisusb_write_pci_config(sisusb, 0x04, tmp32);
 
2252                 /* Some further magic */
 
2253                 packet.header  = 0x001f;
 
2254                 packet.address = 0x00000050;
 
2255                 packet.data    = 0x000000ff;
 
2256                 ret |= sisusb_send_bridge_packet(sisusb, 10, &packet, 0);
 
2262 /* Initialize the graphics device (return 0 on success)
 
2263  * This initializes the net2280 as well as the PCI registers
 
2264  * of the graphics board.
 
2268 sisusb_init_gfxdevice(struct sisusb_usb_data *sisusb, int initscreen)
 
2270         int ret = 0, test = 0;
 
2273         if (sisusb->devinit == 1) {
 
2274                 /* Read PCI BARs and see if they have been set up */
 
2275                 ret |= sisusb_read_pci_config(sisusb, 0x10, &tmp32);
 
2276                 if (ret) return ret;
 
2277                 if ((tmp32 & 0xfffffff0) == SISUSB_PCI_MEMBASE) test++;
 
2279                 ret |= sisusb_read_pci_config(sisusb, 0x14, &tmp32);
 
2280                 if (ret) return ret;
 
2281                 if ((tmp32 & 0xfffffff0) == SISUSB_PCI_MMIOBASE) test++;
 
2283                 ret |= sisusb_read_pci_config(sisusb, 0x18, &tmp32);
 
2284                 if (ret) return ret;
 
2285                 if ((tmp32 & 0xfffffff0) == SISUSB_PCI_IOPORTBASE) test++;
 
2288         /* No? So reset the device */
 
2289         if ((sisusb->devinit == 0) || (test != 3)) {
 
2291                 ret |= sisusb_do_init_gfxdevice(sisusb);
 
2294                         sisusb->devinit = 1;
 
2298         if (sisusb->devinit) {
 
2299                 /* Initialize the graphics core */
 
2300                 if (sisusb_init_gfxcore(sisusb) == 0) {
 
2301                         sisusb->gfxinit = 1;
 
2302                         sisusb_get_ramconfig(sisusb);
 
2303                         ret |= sisusb_set_default_mode(sisusb, 1);
 
2304                         ret |= sisusb_setup_screen(sisusb, 1, initscreen);
 
2312 #ifdef INCL_SISUSB_CON
 
2314 /* Set up default text mode:
 
2315    - Set text mode (0x03)
 
2316    - Upload default font
 
2317    - Upload user font (if available)
 
2321 sisusb_reset_text_mode(struct sisusb_usb_data *sisusb, int init)
 
2323         int ret = 0, slot = sisusb->font_slot, i;
 
2324         const struct font_desc *myfont;
 
2328         static const char bootstring[] = "SiSUSB VGA text console, (C) 2005 Thomas Winischhofer.";
 
2329         static const char bootlogo[] = "(o_ //\\ V_/_";
 
2331         /* sisusb->lock is down */
 
2333         if (!sisusb->SiS_Pr)
 
2336         sisusb->SiS_Pr->IOAddress = SISUSB_PCI_IOPORTBASE + 0x30;
 
2337         sisusb->SiS_Pr->sisusb = (void *)sisusb;
 
2340         SiSUSBSetMode(sisusb->SiS_Pr, 0x03);
 
2342         if (!(myfont = find_font("VGA8x16")))
 
2345         if (!(tempbuf = vmalloc(8192)))
 
2348         for (i = 0; i < 256; i++)
 
2349                 memcpy(tempbuf + (i * 32), myfont->data + (i * 16), 16);
 
2351         /* Upload default font */
 
2352         ret = sisusbcon_do_font_op(sisusb, 1, 0, tempbuf, 8192, 0, 1, NULL, 16, 0);
 
2356         /* Upload user font (and reset current slot) */
 
2357         if (sisusb->font_backup) {
 
2358                 ret |= sisusbcon_do_font_op(sisusb, 1, 2, sisusb->font_backup,
 
2359                                 8192, sisusb->font_backup_512, 1, NULL,
 
2360                                 sisusb->font_backup_height, 0);
 
2362                         sisusbcon_do_font_op(sisusb, 1, 0, NULL, 0, 0, 1,
 
2366         if (init && !sisusb->scrbuf) {
 
2368                 if ((tempbuf = vmalloc(8192))) {
 
2371                         tempbufb = (u16 *)tempbuf;
 
2373                                 *(tempbufb++) = 0x0720;
 
2376                         tempbufb = (u16 *)tempbuf;
 
2377                         while (bootlogo[i]) {
 
2378                                 *(tempbufb++) = 0x0700 | bootlogo[i++];
 
2384                         tempbufb = (u16 *)tempbuf + 6;
 
2385                         while (bootstring[i])
 
2386                                 *(tempbufb++) = 0x0700 | bootstring[i++];
 
2388                         ret |= sisusb_copy_memory(sisusb, tempbuf,
 
2389                                 sisusb->vrambase, 8192, &written);
 
2395         } else if (sisusb->scrbuf) {
 
2397                 ret |= sisusb_copy_memory(sisusb, (char *)sisusb->scrbuf,
 
2398                                 sisusb->vrambase, sisusb->scrbuf_size, &written);
 
2402         if (sisusb->sisusb_cursor_size_from >= 0 &&
 
2403             sisusb->sisusb_cursor_size_to >= 0) {
 
2404                 sisusb_setidxreg(sisusb, SISCR, 0x0a,
 
2405                                 sisusb->sisusb_cursor_size_from);
 
2406                 sisusb_setidxregandor(sisusb, SISCR, 0x0b, 0xe0,
 
2407                                 sisusb->sisusb_cursor_size_to);
 
2409                 sisusb_setidxreg(sisusb, SISCR, 0x0a, 0x2d);
 
2410                 sisusb_setidxreg(sisusb, SISCR, 0x0b, 0x0e);
 
2411                 sisusb->sisusb_cursor_size_to = -1;
 
2414         slot = sisusb->sisusb_cursor_loc;
 
2415         if(slot < 0) slot = 0;
 
2417         sisusb->sisusb_cursor_loc = -1;
 
2418         sisusb->bad_cursor_pos = 1;
 
2420         sisusb_set_cursor(sisusb, slot);
 
2422         sisusb_setidxreg(sisusb, SISCR, 0x0c, (sisusb->cur_start_addr >> 8));
 
2423         sisusb_setidxreg(sisusb, SISCR, 0x0d, (sisusb->cur_start_addr & 0xff));
 
2425         sisusb->textmodedestroyed = 0;
 
2427         /* sisusb->lock is down */
 
2437 sisusb_open(struct inode *inode, struct file *file)
 
2439         struct sisusb_usb_data *sisusb;
 
2440         struct usb_interface *interface;
 
2441         int subminor = iminor(inode);
 
2443         if (!(interface = usb_find_interface(&sisusb_driver, subminor)))
 
2446         if (!(sisusb = usb_get_intfdata(interface)))
 
2449         mutex_lock(&sisusb->lock);
 
2451         if (!sisusb->present || !sisusb->ready) {
 
2452                 mutex_unlock(&sisusb->lock);
 
2456         if (sisusb->isopen) {
 
2457                 mutex_unlock(&sisusb->lock);
 
2461         if (!sisusb->devinit) {
 
2462                 if (sisusb->sisusb_dev->speed == USB_SPEED_HIGH) {
 
2463                         if (sisusb_init_gfxdevice(sisusb, 0)) {
 
2464                                 mutex_unlock(&sisusb->lock);
 
2465                                 dev_err(&sisusb->sisusb_dev->dev, "Failed to initialize device\n");
 
2469                         mutex_unlock(&sisusb->lock);
 
2470                         dev_err(&sisusb->sisusb_dev->dev, "Device not attached to USB 2.0 hub\n");
 
2475         /* Increment usage count for our sisusb */
 
2476         kref_get(&sisusb->kref);
 
2480         file->private_data = sisusb;
 
2482         mutex_unlock(&sisusb->lock);
 
2488 sisusb_delete(struct kref *kref)
 
2490         struct sisusb_usb_data *sisusb = to_sisusb_dev(kref);
 
2495         if (sisusb->sisusb_dev)
 
2496                 usb_put_dev(sisusb->sisusb_dev);
 
2498         sisusb->sisusb_dev = NULL;
 
2499         sisusb_free_buffers(sisusb);
 
2500         sisusb_free_urbs(sisusb);
 
2501 #ifdef INCL_SISUSB_CON
 
2502         kfree(sisusb->SiS_Pr);
 
2508 sisusb_release(struct inode *inode, struct file *file)
 
2510         struct sisusb_usb_data *sisusb;
 
2512         if (!(sisusb = (struct sisusb_usb_data *)file->private_data))
 
2515         mutex_lock(&sisusb->lock);
 
2517         if (sisusb->present) {
 
2518                 /* Wait for all URBs to finish if device still present */
 
2519                 if (!sisusb_wait_all_out_complete(sisusb))
 
2520                         sisusb_kill_all_busy(sisusb);
 
2524         file->private_data = NULL;
 
2526         mutex_unlock(&sisusb->lock);
 
2528         /* decrement the usage count on our device */
 
2529         kref_put(&sisusb->kref, sisusb_delete);
 
2535 sisusb_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
 
2537         struct sisusb_usb_data *sisusb;
 
2538         ssize_t bytes_read = 0;
 
2544         if (!(sisusb = (struct sisusb_usb_data *)file->private_data))
 
2547         mutex_lock(&sisusb->lock);
 
2550         if (!sisusb->present || !sisusb->ready || !sisusb->sisusb_dev) {
 
2551                 mutex_unlock(&sisusb->lock);
 
2555         if ((*ppos) >= SISUSB_PCI_PSEUDO_IOPORTBASE &&
 
2556             (*ppos) <  SISUSB_PCI_PSEUDO_IOPORTBASE + 128) {
 
2559                         SISUSB_PCI_PSEUDO_IOPORTBASE +
 
2560                         SISUSB_PCI_IOPORTBASE;
 
2563                  * Byte, word and long(32) can be read. As this
 
2564                  * emulates inX instructions, the data returned is
 
2565                  * in machine-endianness.
 
2570                                 if (sisusb_read_memio_byte(sisusb,
 
2574                                 else if (put_user(buf8, (u8 __user *)buffer))
 
2582                                 if (sisusb_read_memio_word(sisusb,
 
2586                                 else if (put_user(buf16, (u16 __user *)buffer))
 
2594                                 if (sisusb_read_memio_long(sisusb,
 
2598                                 else if (put_user(buf32, (u32 __user *)buffer))
 
2610         } else if ((*ppos) >= SISUSB_PCI_PSEUDO_MEMBASE &&
 
2611                    (*ppos) <  SISUSB_PCI_PSEUDO_MEMBASE + sisusb->vramsize) {
 
2614                         SISUSB_PCI_PSEUDO_MEMBASE +
 
2618                  * Remember: Data delivered is never endian-corrected
 
2620                 errno = sisusb_read_mem_bulk(sisusb, address,
 
2621                                         NULL, count, buffer, &bytes_read);
 
2626         } else  if ((*ppos) >= SISUSB_PCI_PSEUDO_MMIOBASE &&
 
2627                     (*ppos) <  SISUSB_PCI_PSEUDO_MMIOBASE + SISUSB_PCI_MMIOSIZE) {
 
2630                         SISUSB_PCI_PSEUDO_MMIOBASE +
 
2631                         SISUSB_PCI_MMIOBASE;
 
2634                  * Remember: Data delivered is never endian-corrected
 
2636                 errno = sisusb_read_mem_bulk(sisusb, address,
 
2637                                         NULL, count, buffer, &bytes_read);
 
2642         } else  if ((*ppos) >= SISUSB_PCI_PSEUDO_PCIBASE &&
 
2643                     (*ppos) <= SISUSB_PCI_PSEUDO_PCIBASE + 0x5c) {
 
2646                         mutex_unlock(&sisusb->lock);
 
2650                 address = (*ppos) - SISUSB_PCI_PSEUDO_PCIBASE;
 
2652                 /* Read PCI config register
 
2653                  * Return value delivered in machine endianness.
 
2655                 if (sisusb_read_pci_config(sisusb, address, &buf32))
 
2657                 else if (put_user(buf32, (u32 __user *)buffer))
 
2668         (*ppos) += bytes_read;
 
2670         mutex_unlock(&sisusb->lock);
 
2672         return errno ? errno : bytes_read;
 
2676 sisusb_write(struct file *file, const char __user *buffer, size_t count,
 
2679         struct sisusb_usb_data *sisusb;
 
2681         ssize_t bytes_written = 0;
 
2686         if (!(sisusb = (struct sisusb_usb_data *)file->private_data))
 
2689         mutex_lock(&sisusb->lock);
 
2692         if (!sisusb->present || !sisusb->ready || !sisusb->sisusb_dev) {
 
2693                 mutex_unlock(&sisusb->lock);
 
2697         if ((*ppos) >= SISUSB_PCI_PSEUDO_IOPORTBASE &&
 
2698             (*ppos) <  SISUSB_PCI_PSEUDO_IOPORTBASE + 128) {
 
2701                         SISUSB_PCI_PSEUDO_IOPORTBASE +
 
2702                         SISUSB_PCI_IOPORTBASE;
 
2705                  * Byte, word and long(32) can be written. As this
 
2706                  * emulates outX instructions, the data is expected
 
2707                  * in machine-endianness.
 
2712                                 if (get_user(buf8, (u8 __user *)buffer))
 
2714                                 else if (sisusb_write_memio_byte(sisusb,
 
2724                                 if (get_user(buf16, (u16 __user *)buffer))
 
2726                                 else if (sisusb_write_memio_word(sisusb,
 
2736                                 if (get_user(buf32, (u32 __user *)buffer))
 
2738                                 else if (sisusb_write_memio_long(sisusb,
 
2751         } else if ((*ppos) >= SISUSB_PCI_PSEUDO_MEMBASE &&
 
2752                    (*ppos) <  SISUSB_PCI_PSEUDO_MEMBASE + sisusb->vramsize) {
 
2755                         SISUSB_PCI_PSEUDO_MEMBASE +
 
2759                  * Buffer is copied 1:1, therefore, on big-endian
 
2760                  * machines, the data must be swapped by userland
 
2761                  * in advance (if applicable; no swapping in 8bpp
 
2762                  * mode or if YUV data is being transferred).
 
2764                 errno = sisusb_write_mem_bulk(sisusb, address, NULL,
 
2765                                         count, buffer, 0, &bytes_written);
 
2768                         errno = bytes_written;
 
2770         } else  if ((*ppos) >= SISUSB_PCI_PSEUDO_MMIOBASE &&
 
2771                     (*ppos) <  SISUSB_PCI_PSEUDO_MMIOBASE + SISUSB_PCI_MMIOSIZE) {
 
2774                         SISUSB_PCI_PSEUDO_MMIOBASE +
 
2775                         SISUSB_PCI_MMIOBASE;
 
2778                  * Buffer is copied 1:1, therefore, on big-endian
 
2779                  * machines, the data must be swapped by userland
 
2782                 errno = sisusb_write_mem_bulk(sisusb, address, NULL,
 
2783                                         count, buffer, 0, &bytes_written);
 
2786                         errno = bytes_written;
 
2788         } else  if ((*ppos) >= SISUSB_PCI_PSEUDO_PCIBASE &&
 
2789                     (*ppos) <= SISUSB_PCI_PSEUDO_PCIBASE + SISUSB_PCI_PCONFSIZE) {
 
2792                         mutex_unlock(&sisusb->lock);
 
2796                 address = (*ppos) - SISUSB_PCI_PSEUDO_PCIBASE;
 
2798                 /* Write PCI config register.
 
2799                  * Given value expected in machine endianness.
 
2801                 if (get_user(buf32, (u32 __user *)buffer))
 
2803                 else if (sisusb_write_pci_config(sisusb, address, buf32))
 
2816         (*ppos) += bytes_written;
 
2818         mutex_unlock(&sisusb->lock);
 
2820         return errno ? errno : bytes_written;
 
2824 sisusb_lseek(struct file *file, loff_t offset, int orig)
 
2826         struct sisusb_usb_data *sisusb;
 
2829         if (!(sisusb = (struct sisusb_usb_data *)file->private_data))
 
2832         mutex_lock(&sisusb->lock);
 
2835         if (!sisusb->present || !sisusb->ready || !sisusb->sisusb_dev) {
 
2836                 mutex_unlock(&sisusb->lock);
 
2842                         file->f_pos = offset;
 
2844                         /* never negative, no force_successful_syscall needed */
 
2847                         file->f_pos += offset;
 
2849                         /* never negative, no force_successful_syscall needed */
 
2852                         /* seeking relative to "end of file" is not supported */
 
2856         mutex_unlock(&sisusb->lock);
 
2861 sisusb_handle_command(struct sisusb_usb_data *sisusb, struct sisusb_command *y,
 
2864         int     retval, port, length;
 
2867         /* All our commands require the device
 
2868          * to be initialized.
 
2870         if (!sisusb->devinit)
 
2874                 SISUSB_PCI_PSEUDO_IOPORTBASE +
 
2875                 SISUSB_PCI_IOPORTBASE;
 
2877         switch (y->operation) {
 
2879                         retval = sisusb_getidxreg(sisusb, port,
 
2880                                                          y->data0, &y->data1);
 
2882                                 if (copy_to_user((void __user *)arg, y,
 
2889                         retval = sisusb_setidxreg(sisusb, port,
 
2890                                                 y->data0, y->data1);
 
2894                         retval = sisusb_setidxregor(sisusb, port,
 
2895                                                 y->data0, y->data1);
 
2899                         retval = sisusb_setidxregand(sisusb, port,
 
2900                                                 y->data0, y->data1);
 
2903                 case SUCMD_SETANDOR:
 
2904                         retval = sisusb_setidxregandor(sisusb, port,
 
2905                                                 y->data0, y->data1, y->data2);
 
2909                         retval = sisusb_setidxregmask(sisusb, port,
 
2910                                                 y->data0, y->data1, y->data2);
 
2914                         /* Gfx core must be initialized */
 
2915                         if (!sisusb->gfxinit)
 
2918                         length = (y->data0 << 16) | (y->data1 << 8) | y->data2;
 
2919                         address = y->data3 -
 
2920                                 SISUSB_PCI_PSEUDO_MEMBASE +
 
2922                         retval = sisusb_clear_vram(sisusb, address, length);
 
2925                 case SUCMD_HANDLETEXTMODE:
 
2927 #ifdef INCL_SISUSB_CON
 
2928                         /* Gfx core must be initialized, SiS_Pr must exist */
 
2929                         if (!sisusb->gfxinit || !sisusb->SiS_Pr)
 
2934                                 retval = sisusb_reset_text_mode(sisusb, 0);
 
2937                                 sisusb->textmodedestroyed = 1;
 
2943 #ifdef INCL_SISUSB_CON
 
2945                         /* Gfx core must be initialized, SiS_Pr must exist */
 
2946                         if (!sisusb->gfxinit || !sisusb->SiS_Pr)
 
2951                         sisusb->SiS_Pr->IOAddress = SISUSB_PCI_IOPORTBASE + 0x30;
 
2952                         sisusb->SiS_Pr->sisusb = (void *)sisusb;
 
2954                         if (SiSUSBSetMode(sisusb->SiS_Pr, y->data3))
 
2959                 case SUCMD_SETVESAMODE:
 
2960                         /* Gfx core must be initialized, SiS_Pr must exist */
 
2961                         if (!sisusb->gfxinit || !sisusb->SiS_Pr)
 
2966                         sisusb->SiS_Pr->IOAddress = SISUSB_PCI_IOPORTBASE + 0x30;
 
2967                         sisusb->SiS_Pr->sisusb = (void *)sisusb;
 
2969                         if (SiSUSBSetVESAMode(sisusb->SiS_Pr, y->data3))
 
2986 sisusb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
 
2989         struct sisusb_usb_data *sisusb;
 
2990         struct sisusb_info x;
 
2991         struct sisusb_command y;
 
2993         u32 __user *argp = (u32 __user *)arg;
 
2995         if (!(sisusb = (struct sisusb_usb_data *)file->private_data))
 
2998         mutex_lock(&sisusb->lock);
 
3001         if (!sisusb->present || !sisusb->ready || !sisusb->sisusb_dev) {
 
3008                 case SISUSB_GET_CONFIG_SIZE:
 
3010                         if (put_user(sizeof(x), argp))
 
3015                 case SISUSB_GET_CONFIG:
 
3017                         x.sisusb_id         = SISUSB_ID;
 
3018                         x.sisusb_version    = SISUSB_VERSION;
 
3019                         x.sisusb_revision   = SISUSB_REVISION;
 
3020                         x.sisusb_patchlevel = SISUSB_PATCHLEVEL;
 
3021                         x.sisusb_gfxinit    = sisusb->gfxinit;
 
3022                         x.sisusb_vrambase   = SISUSB_PCI_PSEUDO_MEMBASE;
 
3023                         x.sisusb_mmiobase   = SISUSB_PCI_PSEUDO_MMIOBASE;
 
3024                         x.sisusb_iobase     = SISUSB_PCI_PSEUDO_IOPORTBASE;
 
3025                         x.sisusb_pcibase    = SISUSB_PCI_PSEUDO_PCIBASE;
 
3026                         x.sisusb_vramsize   = sisusb->vramsize;
 
3027                         x.sisusb_minor      = sisusb->minor;
 
3028                         x.sisusb_fbdevactive= 0;
 
3029 #ifdef INCL_SISUSB_CON
 
3030                         x.sisusb_conactive  = sisusb->haveconsole ? 1 : 0;
 
3032                         x.sisusb_conactive  = 0;
 
3035                         if (copy_to_user((void __user *)arg, &x, sizeof(x)))
 
3040                 case SISUSB_COMMAND:
 
3042                         if (copy_from_user(&y, (void __user *)arg, sizeof(y)))
 
3045                                 retval = sisusb_handle_command(sisusb, &y, arg);
 
3055         mutex_unlock(&sisusb->lock);
 
3059 #ifdef SISUSB_NEW_CONFIG_COMPAT
 
3061 sisusb_compat_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
 
3066                 case SISUSB_GET_CONFIG_SIZE:
 
3067                 case SISUSB_GET_CONFIG:
 
3068                 case SISUSB_COMMAND:
 
3070                         retval = sisusb_ioctl(f->f_path.dentry->d_inode, f, cmd, arg);
 
3075                         return -ENOIOCTLCMD;
 
3080 static const struct file_operations usb_sisusb_fops = {
 
3081         .owner =        THIS_MODULE,
 
3082         .open =         sisusb_open,
 
3083         .release =      sisusb_release,
 
3084         .read =         sisusb_read,
 
3085         .write =        sisusb_write,
 
3086         .llseek =       sisusb_lseek,
 
3087 #ifdef SISUSB_NEW_CONFIG_COMPAT
 
3088         .compat_ioctl = sisusb_compat_ioctl,
 
3090         .ioctl =        sisusb_ioctl
 
3093 static struct usb_class_driver usb_sisusb_class = {
 
3094         .name =         "sisusbvga%d",
 
3095         .fops =         &usb_sisusb_fops,
 
3096         .minor_base =   SISUSB_MINOR
 
3099 static int sisusb_probe(struct usb_interface *intf,
 
3100                         const struct usb_device_id *id)
 
3102         struct usb_device *dev = interface_to_usbdev(intf);
 
3103         struct sisusb_usb_data *sisusb;
 
3106         dev_info(&dev->dev, "USB2VGA dongle found at address %d\n",
 
3109         /* Allocate memory for our private */
 
3110         if (!(sisusb = kzalloc(sizeof(*sisusb), GFP_KERNEL))) {
 
3111                 dev_err(&sisusb->sisusb_dev->dev, "Failed to allocate memory for private data\n");
 
3114         kref_init(&sisusb->kref);
 
3116         mutex_init(&(sisusb->lock));
 
3118         /* Register device */
 
3119         if ((retval = usb_register_dev(intf, &usb_sisusb_class))) {
 
3120                 dev_err(&sisusb->sisusb_dev->dev, "Failed to get a minor for device %d\n",
 
3126         sisusb->sisusb_dev = dev;
 
3127         sisusb->minor      = intf->minor;
 
3128         sisusb->vrambase   = SISUSB_PCI_MEMBASE;
 
3129         sisusb->mmiobase   = SISUSB_PCI_MMIOBASE;
 
3130         sisusb->mmiosize   = SISUSB_PCI_MMIOSIZE;
 
3131         sisusb->ioportbase = SISUSB_PCI_IOPORTBASE;
 
3132         /* Everything else is zero */
 
3134         /* Allocate buffers */
 
3135         sisusb->ibufsize = SISUSB_IBUF_SIZE;
 
3136         if (!(sisusb->ibuf = usb_buffer_alloc(dev, SISUSB_IBUF_SIZE,
 
3137                                         GFP_KERNEL, &sisusb->transfer_dma_in))) {
 
3138                 dev_err(&sisusb->sisusb_dev->dev, "Failed to allocate memory for input buffer");
 
3143         sisusb->numobufs = 0;
 
3144         sisusb->obufsize = SISUSB_OBUF_SIZE;
 
3145         for (i = 0; i < NUMOBUFS; i++) {
 
3146                 if (!(sisusb->obuf[i] = usb_buffer_alloc(dev, SISUSB_OBUF_SIZE,
 
3148                                         &sisusb->transfer_dma_out[i]))) {
 
3150                                 dev_err(&sisusb->sisusb_dev->dev, "Failed to allocate memory for output buffer\n");
 
3161         if (!(sisusb->sisurbin = usb_alloc_urb(0, GFP_KERNEL))) {
 
3162                 dev_err(&sisusb->sisusb_dev->dev, "Failed to allocate URBs\n");
 
3166         sisusb->completein = 1;
 
3168         for (i = 0; i < sisusb->numobufs; i++) {
 
3169                 if (!(sisusb->sisurbout[i] = usb_alloc_urb(0, GFP_KERNEL))) {
 
3170                         dev_err(&sisusb->sisusb_dev->dev, "Failed to allocate URBs\n");
 
3174                 sisusb->urbout_context[i].sisusb = (void *)sisusb;
 
3175                 sisusb->urbout_context[i].urbindex = i;
 
3176                 sisusb->urbstatus[i] = 0;
 
3179         dev_info(&sisusb->sisusb_dev->dev, "Allocated %d output buffers\n", sisusb->numobufs);
 
3181 #ifdef INCL_SISUSB_CON
 
3182         /* Allocate our SiS_Pr */
 
3183         if (!(sisusb->SiS_Pr = kmalloc(sizeof(struct SiS_Private), GFP_KERNEL))) {
 
3184                 dev_err(&sisusb->sisusb_dev->dev, "Failed to allocate SiS_Pr\n");
 
3188         /* Do remaining init stuff */
 
3190         init_waitqueue_head(&sisusb->wait_q);
 
3192         usb_set_intfdata(intf, sisusb);
 
3194         usb_get_dev(sisusb->sisusb_dev);
 
3196         sisusb->present = 1;
 
3198 #ifdef SISUSB_OLD_CONFIG_COMPAT
 
3201         /* Our ioctls are all "32/64bit compatible" */
 
3202         ret =  register_ioctl32_conversion(SISUSB_GET_CONFIG_SIZE, NULL);
 
3203         ret |= register_ioctl32_conversion(SISUSB_GET_CONFIG,      NULL);
 
3204         ret |= register_ioctl32_conversion(SISUSB_COMMAND,         NULL);
 
3206                 dev_err(&sisusb->sisusb_dev->dev, "Error registering ioctl32 translations\n");
 
3208                 sisusb->ioctl32registered = 1;
 
3212         if (dev->speed == USB_SPEED_HIGH) {
 
3214 #ifdef INCL_SISUSB_CON
 
3215                 if (sisusb_first_vc > 0 &&
 
3216                     sisusb_last_vc > 0 &&
 
3217                     sisusb_first_vc <= sisusb_last_vc &&
 
3218                     sisusb_last_vc <= MAX_NR_CONSOLES)
 
3221                 if (sisusb_init_gfxdevice(sisusb, initscreen))
 
3222                         dev_err(&sisusb->sisusb_dev->dev, "Failed to early initialize device\n");
 
3225                 dev_info(&sisusb->sisusb_dev->dev, "Not attached to USB 2.0 hub, deferring init\n");
 
3229 #ifdef SISUSBENDIANTEST
 
3230         dev_dbg(&sisusb->sisusb_dev->dev, "*** RWTEST ***\n");
 
3231         sisusb_testreadwrite(sisusb);
 
3232         dev_dbg(&sisusb->sisusb_dev->dev, "*** RWTEST END ***\n");
 
3235 #ifdef INCL_SISUSB_CON
 
3236         sisusb_console_init(sisusb, sisusb_first_vc, sisusb_last_vc);
 
3242         sisusb_free_urbs(sisusb);
 
3244         sisusb_free_buffers(sisusb);
 
3246         usb_deregister_dev(intf, &usb_sisusb_class);
 
3252 static void sisusb_disconnect(struct usb_interface *intf)
 
3254         struct sisusb_usb_data *sisusb;
 
3256         /* This should *not* happen */
 
3257         if (!(sisusb = usb_get_intfdata(intf)))
 
3260 #ifdef INCL_SISUSB_CON
 
3261         sisusb_console_exit(sisusb);
 
3264         usb_deregister_dev(intf, &usb_sisusb_class);
 
3266         mutex_lock(&sisusb->lock);
 
3268         /* Wait for all URBs to complete and kill them in case (MUST do) */
 
3269         if (!sisusb_wait_all_out_complete(sisusb))
 
3270                 sisusb_kill_all_busy(sisusb);
 
3272         usb_set_intfdata(intf, NULL);
 
3274 #ifdef SISUSB_OLD_CONFIG_COMPAT
 
3275         if (sisusb->ioctl32registered) {
 
3277                 sisusb->ioctl32registered = 0;
 
3278                 ret =  unregister_ioctl32_conversion(SISUSB_GET_CONFIG_SIZE);
 
3279                 ret |= unregister_ioctl32_conversion(SISUSB_GET_CONFIG);
 
3280                 ret |= unregister_ioctl32_conversion(SISUSB_COMMAND);
 
3282                         dev_err(&sisusb->sisusb_dev->dev, "Error unregistering ioctl32 translations\n");
 
3287         sisusb->present = 0;
 
3290         mutex_unlock(&sisusb->lock);
 
3292         /* decrement our usage count */
 
3293         kref_put(&sisusb->kref, sisusb_delete);
 
3295         dev_info(&sisusb->sisusb_dev->dev, "Disconnected\n");
 
3298 static struct usb_device_id sisusb_table [] = {
 
3299         { USB_DEVICE(0x0711, 0x0550) },
 
3300         { USB_DEVICE(0x0711, 0x0900) },
 
3301         { USB_DEVICE(0x0711, 0x0901) },
 
3302         { USB_DEVICE(0x0711, 0x0902) },
 
3303         { USB_DEVICE(0x182d, 0x021c) },
 
3304         { USB_DEVICE(0x182d, 0x0269) },
 
3308 MODULE_DEVICE_TABLE (usb, sisusb_table);
 
3310 static struct usb_driver sisusb_driver = {
 
3312         .probe =        sisusb_probe,
 
3313         .disconnect =   sisusb_disconnect,
 
3314         .id_table =     sisusb_table,
 
3317 static int __init usb_sisusb_init(void)
 
3320 #ifdef INCL_SISUSB_CON
 
3321         sisusb_init_concode();
 
3324         return usb_register(&sisusb_driver);
 
3327 static void __exit usb_sisusb_exit(void)
 
3329         usb_deregister(&sisusb_driver);
 
3332 module_init(usb_sisusb_init);
 
3333 module_exit(usb_sisusb_exit);
 
3335 MODULE_AUTHOR("Thomas Winischhofer <thomas@winischhofer.net>");
 
3336 MODULE_DESCRIPTION("sisusbvga - Driver for Net2280/SiS315-based USB2VGA dongles");
 
3337 MODULE_LICENSE("GPL");