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>
46 #include <linux/slab.h>
55 #ifdef INCL_SISUSB_CON
59 #define SISUSB_DONTSYNC
63 #ifdef INCL_SISUSB_CON
64 static int sisusb_first_vc = 0;
65 static int sisusb_last_vc = 0;
69 MODULE_PARM_DESC(last,
"Number of last console to take over (1 - MAX_NR_CONSOLES)");
72 static struct usb_driver sisusb_driver;
80 if (sisusb->
obuf[i]) {
116 for (i = 0; i < sisusb->
numobufs; i++) {
132 if (sisusb_all_free(sisusb))
135 for (i = 0; i < sisusb->
numobufs; i++) {
150 (i = sisusb_all_free(sisusb)),
161 for (i = 0; i < sisusb->
numobufs; i++) {
174 int i, timeout = 5 *
HZ;
177 ((i = sisusb_outurb_available(sisusb)) >= 0),
188 i = sisusb_outurb_available(sisusb);
199 if ((index >= 0) && (index < sisusb->numobufs))
206 sisusb_bulk_completeout(
struct urb *
urb)
219 #ifndef SISUSB_DONTSYNC
230 int len,
int *actual_length,
int timeout,
unsigned int tflags)
233 int retval, byteswritten = 0;
236 urb->transfer_flags = 0;
238 usb_fill_bulk_urb(urb, sisusb->
sisusb_dev, pipe, data, len,
241 urb->transfer_flags |= tflags;
242 urb->actual_length = 0;
246 NULL : actual_length;
255 if ((retval == 0) && timeout) {
265 retval = urb->status;
266 byteswritten = urb->actual_length;
271 *actual_length = byteswritten;
281 sisusb_bulk_completein(
struct urb *urb)
293 sisusb_bulkin_msg(
struct sisusb_usb_data *sisusb,
unsigned int pipe,
void *data,
294 int len,
int *actual_length,
int timeout,
unsigned int tflags)
297 int retval, readbytes = 0;
299 urb->transfer_flags = 0;
301 usb_fill_bulk_urb(urb, sisusb->
sisusb_dev, pipe, data, len,
302 sisusb_bulk_completein, sisusb);
304 urb->transfer_flags |= tflags;
305 urb->actual_length = 0;
317 retval = urb->status;
318 readbytes = urb->actual_length;
323 *actual_length = readbytes;
344 static int sisusb_send_bulk_msg(
struct sisusb_usb_data *sisusb,
int ep,
int len,
345 char *kernbuffer,
const char __user *userbuffer,
int index,
349 int passsize, thispass, transferred_len = 0;
350 int fromuser = (userbuffer !=
NULL) ? 1 : 0;
351 int fromkern = (kernbuffer !=
NULL) ? 1 : 0;
355 (*bytes_written) = 0;
369 if (fromuser || fromkern)
374 pipe = usb_sndbulkpipe(sisusb->
sisusb_dev, ep);
381 index = sisusb_get_free_outbuf(sisusb);
393 userbuffer += passsize;
395 }
else if (fromkern) {
397 memcpy(buffer, kernbuffer, passsize);
398 kernbuffer += passsize;
408 result = sisusb_bulkout_msg(sisusb,
426 if ((result == 0) && !async && transferred_len) {
428 thispass -= transferred_len;
429 buffer += transferred_len;
438 (*bytes_written) += passsize;
442 if (fromuser || fromkern)
448 #ifdef SISUSB_DONTSYNC
449 (*bytes_written) = len;
452 sisusb_wait_all_out_complete(sisusb);
453 (*bytes_written) = transferred_len;
458 return ((*bytes_written) == len) ? 0 : -
EIO;
470 static int sisusb_recv_bulk_msg(
struct sisusb_usb_data *sisusb,
int ep,
int len,
471 void *kernbuffer,
char __user *userbuffer,
ssize_t *bytes_read,
474 int result = 0,
retry, count = len;
475 int bufsize, thispass, transferred_len;
485 pipe = usb_rcvbulkpipe(sisusb->
sisusb_dev, ep);
486 buffer = sisusb->
ibuf;
491 #ifdef SISUSB_DONTSYNC
492 if (!(sisusb_wait_all_out_complete(sisusb)))
501 thispass = (bufsize <
count) ? bufsize : count;
503 result = sisusb_bulkin_msg(sisusb,
512 thispass = transferred_len;
527 (*bytes_read) += thispass;
535 userbuffer += thispass;
539 memcpy(kernbuffer, buffer, thispass);
540 kernbuffer += thispass;
548 return ((*bytes_read) == len) ? 0 : -
EIO;
561 #ifdef SISUSB_DONTSYNC
562 if (!(sisusb_wait_all_out_complete(sisusb)))
571 (
char *)packet,
NULL, 0, &bytes_transferred, 0, 0);
573 if ((ret == 0) && (len == 6)) {
579 (
char *)&tmp,
NULL, &bytes_transferred, 0);
587 static int sisusb_send_bridge_packet(
struct sisusb_usb_data *sisusb,
int len,
598 #ifdef SISUSB_DONTSYNC
599 if (!(sisusb_wait_all_out_complete(sisusb)))
608 (
char *)packet,
NULL, 0, &bytes_transferred, tflags, 0);
610 if ((ret == 0) && (len == 6)) {
616 (
char *)&tmp,
NULL, &bytes_transferred, 0);
642 packet.
header = (1 << (addr & 3)) | (type << 6);
644 packet.
data = data << ((addr & 3) << 3);
645 ret = sisusb_send_packet(sisusb, 10, &packet);
659 packet.
header = (type << 6) | 0x0003;
661 ret = sisusb_send_packet(sisusb, 10, &packet);
664 packet.
header = (type << 6) | 0x0006;
666 ret = sisusb_send_packet(sisusb, 10, &packet);
669 packet.
header = (type << 6) | 0x000c;
671 ret = sisusb_send_packet(sisusb, 10, &packet);
674 packet.
header = (type << 6) | 0x0008;
676 ret = sisusb_send_packet(sisusb, 10, &packet);
677 packet.
header = (type << 6) | 0x0001;
678 packet.
address = (addr & ~3) + 4;
680 ret |= sisusb_send_packet(sisusb, 10, &packet);
686 static int sisusb_write_memio_24bit(
struct sisusb_usb_data *sisusb,
int type,
696 packet.
header = (type << 6) | 0x0007;
697 packet.
data = data & 0x00ffffff;
698 ret = sisusb_send_packet(sisusb, 10, &packet);
701 packet.
header = (type << 6) | 0x000e;
702 packet.
data = data << 8;
703 ret = sisusb_send_packet(sisusb, 10, &packet);
706 packet.
header = (type << 6) | 0x000c;
707 packet.
data = data << 16;
708 ret = sisusb_send_packet(sisusb, 10, &packet);
709 packet.
header = (type << 6) | 0x0001;
710 packet.
address = (addr & ~3) + 4;
711 packet.
data = (data >> 16) & 0x00ff;
712 ret |= sisusb_send_packet(sisusb, 10, &packet);
715 packet.
header = (type << 6) | 0x0008;
716 packet.
data = data << 24;
717 ret = sisusb_send_packet(sisusb, 10, &packet);
718 packet.
header = (type << 6) | 0x0003;
719 packet.
address = (addr & ~3) + 4;
720 packet.
data = (data >> 8) & 0xffff;
721 ret |= sisusb_send_packet(sisusb, 10, &packet);
727 static int sisusb_write_memio_long(
struct sisusb_usb_data *sisusb,
int type,
737 packet.
header = (type << 6) | 0x000f;
739 ret = sisusb_send_packet(sisusb, 10, &packet);
742 packet.
header = (type << 6) | 0x000e;
743 packet.
data = data << 8;
744 ret = sisusb_send_packet(sisusb, 10, &packet);
745 packet.
header = (type << 6) | 0x0001;
746 packet.
address = (addr & ~3) + 4;
747 packet.
data = data >> 24;
748 ret |= sisusb_send_packet(sisusb, 10, &packet);
751 packet.
header = (type << 6) | 0x000c;
752 packet.
data = data << 16;
753 ret = sisusb_send_packet(sisusb, 10, &packet);
754 packet.
header = (type << 6) | 0x0003;
755 packet.
address = (addr & ~3) + 4;
756 packet.
data = data >> 16;
757 ret |= sisusb_send_packet(sisusb, 10, &packet);
760 packet.
header = (type << 6) | 0x0008;
761 packet.
data = data << 24;
762 ret = sisusb_send_packet(sisusb, 10, &packet);
763 packet.
header = (type << 6) | 0x0007;
764 packet.
address = (addr & ~3) + 4;
765 packet.
data = data >> 8;
766 ret |= sisusb_send_packet(sisusb, 10, &packet);
783 char *kernbuffer,
int length,
784 const char __user *userbuffer,
int index,
789 static int msgcount = 0;
790 u8 swap8, fromkern = kernbuffer ? 1 : 0;
792 u32 swap32,
flag = (length >> 28) & 1;
798 if (!fromkern && !userbuffer)
801 (*bytes_written = 0);
803 length &= 0x00ffffff;
814 swap8 = kernbuffer[0];
816 ret = sisusb_write_memio_byte(sisusb,
830 swap16 = *((
u16 *)kernbuffer);
832 ret = sisusb_write_memio_word(sisusb,
838 (*bytes_written) += 2;
847 swap32 = (buf[0] << 16) |
851 swap32 = (buf[2] << 16) |
857 swap32 = (kernbuffer[0] << 16) |
858 (kernbuffer[1] << 8) |
861 swap32 = (kernbuffer[2] << 16) |
862 (kernbuffer[1] << 8) |
866 ret = sisusb_write_memio_24bit(sisusb,
872 (*bytes_written) += 3;
881 swap32 = *((
u32 *)kernbuffer);
883 ret = sisusb_write_memio_long(sisusb,
888 (*bytes_written) += 4;
893 if ((length & ~3) > 0x10000) {
898 ret = sisusb_send_bridge_packet(sisusb, 10,
902 packet.
data = (length & ~3);
903 ret |= sisusb_send_bridge_packet(sisusb, 10,
907 packet.
data = flag | 0x16;
908 ret |= sisusb_send_bridge_packet(sisusb, 10,
911 ret |= sisusb_send_bulk_msg(sisusb,
915 bytes_written, 0, 1);
916 userbuffer += (*bytes_written);
917 }
else if (fromkern) {
918 ret |= sisusb_send_bulk_msg(sisusb,
922 bytes_written, 0, 1);
923 kernbuffer += (*bytes_written);
925 ret |= sisusb_send_bulk_msg(sisusb,
929 bytes_written, 0, 1);
930 kernbuffer += ((*bytes_written) &
939 ret = sisusb_send_bridge_packet(sisusb, 10,
943 packet.
data = (length & ~3);
944 ret |= sisusb_send_bridge_packet(sisusb, 10,
946 if (sisusb->
flagb0 != 0x16) {
949 packet.
data = flag | 0x16;
950 ret |= sisusb_send_bridge_packet(sisusb, 10,
955 ret |= sisusb_send_bulk_msg(sisusb,
959 bytes_written, 0, 1);
960 userbuffer += (*bytes_written);
961 }
else if (fromkern) {
962 ret |= sisusb_send_bulk_msg(sisusb,
966 bytes_written, 0, 1);
967 kernbuffer += (*bytes_written);
969 ret |= sisusb_send_bulk_msg(sisusb,
973 bytes_written, 0, 1);
974 kernbuffer += ((*bytes_written) &
982 *bytes_written, length, ret);
983 else if (msgcount == 500)
986 addr += (*bytes_written);
987 length -= (*bytes_written);
995 return ret ? -
EIO : 0;
1002 static int sisusb_read_memio_byte(
struct sisusb_usb_data *sisusb,
int type,
1009 packet.
header = (1 << (addr & 3)) | (type << 6);
1011 ret = sisusb_send_packet(sisusb, 6, &packet);
1012 *data = (
u8)(packet.
data >> ((addr & 3) << 3));
1016 static int sisusb_read_memio_word(
struct sisusb_usb_data *sisusb,
int type,
1028 packet.
header = (type << 6) | 0x0003;
1029 ret = sisusb_send_packet(sisusb, 6, &packet);
1033 packet.
header = (type << 6) | 0x0006;
1034 ret = sisusb_send_packet(sisusb, 6, &packet);
1035 *data = (
u16)(packet.
data >> 8);
1038 packet.
header = (type << 6) | 0x000c;
1039 ret = sisusb_send_packet(sisusb, 6, &packet);
1040 *data = (
u16)(packet.
data >> 16);
1043 packet.
header = (type << 6) | 0x0008;
1044 ret = sisusb_send_packet(sisusb, 6, &packet);
1045 *data = (
u16)(packet.
data >> 24);
1046 packet.
header = (type << 6) | 0x0001;
1047 packet.
address = (addr & ~3) + 4;
1048 ret |= sisusb_send_packet(sisusb, 6, &packet);
1049 *data |= (
u16)(packet.
data << 8);
1055 static int sisusb_read_memio_24bit(
struct sisusb_usb_data *sisusb,
int type,
1065 packet.
header = (type << 6) | 0x0007;
1066 ret = sisusb_send_packet(sisusb, 6, &packet);
1067 *data = packet.
data & 0x00ffffff;
1070 packet.
header = (type << 6) | 0x000e;
1071 ret = sisusb_send_packet(sisusb, 6, &packet);
1072 *data = packet.
data >> 8;
1075 packet.
header = (type << 6) | 0x000c;
1076 ret = sisusb_send_packet(sisusb, 6, &packet);
1077 *data = packet.
data >> 16;
1078 packet.
header = (type << 6) | 0x0001;
1079 packet.
address = (addr & ~3) + 4;
1080 ret |= sisusb_send_packet(sisusb, 6, &packet);
1081 *data |= ((packet.
data & 0xff) << 16);
1084 packet.
header = (type << 6) | 0x0008;
1085 ret = sisusb_send_packet(sisusb, 6, &packet);
1086 *data = packet.
data >> 24;
1087 packet.
header = (type << 6) | 0x0003;
1088 packet.
address = (addr & ~3) + 4;
1089 ret |= sisusb_send_packet(sisusb, 6, &packet);
1090 *data |= ((packet.
data & 0xffff) << 8);
1096 static int sisusb_read_memio_long(
struct sisusb_usb_data *sisusb,
int type,
1106 packet.
header = (type << 6) | 0x000f;
1107 ret = sisusb_send_packet(sisusb, 6, &packet);
1108 *data = packet.
data;
1111 packet.
header = (type << 6) | 0x000e;
1112 ret = sisusb_send_packet(sisusb, 6, &packet);
1113 *data = packet.
data >> 8;
1114 packet.
header = (type << 6) | 0x0001;
1115 packet.
address = (addr & ~3) + 4;
1116 ret |= sisusb_send_packet(sisusb, 6, &packet);
1117 *data |= (packet.
data << 24);
1120 packet.
header = (type << 6) | 0x000c;
1121 ret = sisusb_send_packet(sisusb, 6, &packet);
1122 *data = packet.
data >> 16;
1123 packet.
header = (type << 6) | 0x0003;
1124 packet.
address = (addr & ~3) + 4;
1125 ret |= sisusb_send_packet(sisusb, 6, &packet);
1126 *data |= (packet.
data << 16);
1129 packet.
header = (type << 6) | 0x0008;
1130 ret = sisusb_send_packet(sisusb, 6, &packet);
1131 *data = packet.
data >> 24;
1132 packet.
header = (type << 6) | 0x0007;
1133 packet.
address = (addr & ~3) + 4;
1134 ret |= sisusb_send_packet(sisusb, 6, &packet);
1135 *data |= (packet.
data << 8);
1142 char *kernbuffer,
int length,
1143 char __user *userbuffer,
ssize_t *bytes_read)
1152 length &= 0x00ffffff;
1166 (
u8 __user *)userbuffer)) {
1170 kernbuffer[0] = buf[0];
1182 (
u16 __user *)userbuffer))
1185 *((
u16 *)kernbuffer) = swap16;
1196 buf[0] = (swap32 >> 16) & 0xff;
1197 buf[1] = (swap32 >> 8) & 0xff;
1198 buf[2] = swap32 & 0xff;
1200 buf[2] = (swap32 >> 16) & 0xff;
1201 buf[1] = (swap32 >> 8) & 0xff;
1202 buf[0] = swap32 & 0xff;
1208 kernbuffer[0] = buf[0];
1209 kernbuffer[1] = buf[1];
1210 kernbuffer[2] = buf[2];
1222 (
u32 __user *)userbuffer))
1227 *((
u32 *)kernbuffer) = swap32;
1244 #ifdef INCL_SISUSB_CON
1248 return sisusb_write_memio_byte(sisusb,
SISUSB_TYPE_IO, port, data);
1254 return sisusb_read_memio_byte(sisusb,
SISUSB_TYPE_IO, port, data);
1262 ret = sisusb_write_memio_byte(sisusb,
SISUSB_TYPE_IO, port, index);
1263 ret |= sisusb_write_memio_byte(sisusb,
SISUSB_TYPE_IO, port + 1, data);
1271 ret = sisusb_write_memio_byte(sisusb,
SISUSB_TYPE_IO, port, index);
1272 ret |= sisusb_read_memio_byte(sisusb,
SISUSB_TYPE_IO, port + 1, data);
1283 ret = sisusb_write_memio_byte(sisusb,
SISUSB_TYPE_IO, port, idx);
1284 ret |= sisusb_read_memio_byte(sisusb,
SISUSB_TYPE_IO, port + 1, &tmp);
1287 ret |= sisusb_write_memio_byte(sisusb,
SISUSB_TYPE_IO, port + 1, tmp);
1297 ret = sisusb_write_memio_byte(sisusb,
SISUSB_TYPE_IO, port, idx);
1298 ret |= sisusb_read_memio_byte(sisusb,
SISUSB_TYPE_IO, port + 1, &tmp);
1300 tmp |= (data &
mask);
1301 ret |= sisusb_write_memio_byte(sisusb,
SISUSB_TYPE_IO, port + 1, tmp);
1319 #ifdef INCL_SISUSB_CON
1334 u32 dest,
int length,
size_t *bytes_written)
1336 return(sisusb_write_mem_bulk(sisusb, dest, src, length,
NULL, 0, bytes_written));
1339 #ifdef SISUSBENDIANTEST
1342 u32 src,
int length,
size_t *bytes_written)
1344 return(sisusb_read_mem_bulk(sisusb, src, dest, length,
NULL, bytes_written));
1349 #ifdef SISUSBENDIANTEST
1353 static char srcbuffer[] = { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 };
1354 char destbuffer[10];
1360 for(i = 1; i <= 7; i++) {
1362 sisusb_read_memory(sisusb, destbuffer, sisusb->
vrambase, i, &dummy);
1363 for(j = 0; j <
i; j++) {
1379 packet.
address = regnum | 0x10000;
1381 ret = sisusb_send_packet(sisusb, 10, &packet);
1393 ret = sisusb_send_packet(sisusb, 6, &packet);
1394 *data = packet.
data;
1419 if ((i = sisusb_alloc_outbuf(sisusb)) < 0)
1427 ret = sisusb_write_mem_bulk(sisusb, address,
NULL, length,
NULL, i, &j);
1430 sisusb_free_outbuf(sisusb, i);
1440 #define GETREG(r,d) sisusb_read_memio_byte(sisusb, SISUSB_TYPE_IO, r, d)
1441 #define SETREG(r,d) sisusb_write_memio_byte(sisusb, SISUSB_TYPE_IO, r, d)
1442 #define SETIREG(r,i,d) sisusb_setidxreg(sisusb, r, i, d)
1443 #define GETIREG(r,i,d) sisusb_getidxreg(sisusb, r, i, d)
1444 #define SETIREGOR(r,i,o) sisusb_setidxregor(sisusb, r, i, o)
1445 #define SETIREGAND(r,i,a) sisusb_setidxregand(sisusb, r, i, a)
1446 #define SETIREGANDOR(r,i,a,o) sisusb_setidxregandor(sisusb, r, i, a, o)
1447 #define READL(a,d) sisusb_read_memio_long(sisusb, SISUSB_TYPE_MEM, a, d)
1448 #define WRITEL(a,d) sisusb_write_memio_long(sisusb, SISUSB_TYPE_MEM, a, d)
1449 #define READB(a,d) sisusb_read_memio_byte(sisusb, SISUSB_TYPE_MEM, a, d)
1450 #define WRITEB(a,d) sisusb_write_memio_byte(sisusb, SISUSB_TYPE_MEM, a, d)
1484 sisusb_getbuswidth(
struct sisusb_usb_data *sisusb,
int *bw,
int *chab)
1503 ret |= sisusb_triggersr16(sisusb, ramtype);
1504 ret |=
WRITEL(ramptr + 0, 0x01234567);
1505 ret |=
WRITEL(ramptr + 4, 0x456789ab);
1506 ret |=
WRITEL(ramptr + 8, 0x89abcdef);
1507 ret |=
WRITEL(ramptr + 12, 0xcdef0123);
1508 ret |=
WRITEL(ramptr + 16, 0x55555555);
1509 ret |=
WRITEL(ramptr + 20, 0x55555555);
1510 ret |=
WRITEL(ramptr + 24, 0xffffffff);
1511 ret |=
WRITEL(ramptr + 28, 0xffffffff);
1512 ret |=
READL(ramptr + 0, &t0);
1513 ret |=
READL(ramptr + 4, &t1);
1514 ret |=
READL(ramptr + 8, &t2);
1515 ret |=
READL(ramptr + 12, &t3);
1519 *chab = 0; *bw = 64;
1521 if ((t3 != 0xcdef0123) || (t2 != 0x89abcdef)) {
1522 if ((t1 == 0x456789ab) && (t0 == 0x01234567)) {
1523 *chab = 0; *bw = 64;
1527 if ((t1 != 0x456789ab) || (t0 != 0x01234567)) {
1528 *chab = 1; *bw = 64;
1531 ret |= sisusb_triggersr16(sisusb, ramtype);
1532 ret |=
WRITEL(ramptr + 0, 0x89abcdef);
1533 ret |=
WRITEL(ramptr + 4, 0xcdef0123);
1534 ret |=
WRITEL(ramptr + 8, 0x55555555);
1535 ret |=
WRITEL(ramptr + 12, 0x55555555);
1536 ret |=
WRITEL(ramptr + 16, 0xaaaaaaaa);
1537 ret |=
WRITEL(ramptr + 20, 0xaaaaaaaa);
1538 ret |=
READL(ramptr + 4, &t1);
1540 if (t1 != 0xcdef0123) {
1548 *chab = 0; *bw = 64;
1552 if (t1 == 0x456789ab) {
1553 if (t0 == 0x01234567) {
1554 *chab = 0; *bw = 64;
1558 if (t0 == 0x01234567) {
1559 *chab = 0; *bw = 32;
1567 ret |= sisusb_triggersr16(sisusb, ramtype);
1569 ret |=
WRITEL(ramptr + 0, 0x01234567);
1570 ret |=
WRITEL(ramptr + 4, 0x456789ab);
1571 ret |=
WRITEL(ramptr + 8, 0x89abcdef);
1572 ret |=
WRITEL(ramptr + 12, 0xcdef0123);
1573 ret |=
WRITEL(ramptr + 16, 0x55555555);
1574 ret |=
WRITEL(ramptr + 20, 0x55555555);
1575 ret |=
WRITEL(ramptr + 24, 0xffffffff);
1576 ret |=
WRITEL(ramptr + 28, 0xffffffff);
1577 ret |=
READL(ramptr + 0, &t0);
1578 ret |=
READL(ramptr + 4, &t1);
1580 if (t1 == 0x456789ab) {
1581 if (t0 == 0x01234567) {
1582 *chab = 1; *bw = 64;
1586 if (t0 == 0x01234567) {
1587 *chab = 1; *bw = 32;
1603 ret |=
WRITEB(ramptr, 0xaa);
1604 ret |=
WRITEB(ramptr + 16, 0x55);
1605 ret |=
READB(ramptr, &tmp1);
1606 ret |=
READB(ramptr + 16, &tmp2);
1607 if ((tmp1 != 0xaa) || (tmp2 != 0x55)) {
1608 for (i = 0, j = 16; i < 2; i++, j += 16) {
1614 ret |=
WRITEB(ramptr + 16 + j, j);
1615 ret |=
READB(ramptr + 16 + j, &tmp1);
1617 ret |=
WRITEB(ramptr + j, j);
1627 u8 rankno,
u8 chab,
const u8 dramtype[][5],
1630 int ret = 0, ranksize;
1635 if ((rankno == 2) && (dramtype[index][0] == 2))
1638 ranksize = dramtype[
index][3] / 2 * bw / 32;
1640 if ((ranksize * rankno) > 128)
1644 while ((ranksize >>= 1) > 0) tmp += 0x10;
1645 tmp |= ((rankno - 1) << 2);
1646 tmp |= ((bw / 64) & 0x02);
1647 tmp |= (chab & 0x01);
1650 ret |= sisusb_triggersr16(sisusb, 0);
1665 for (i = 0, j = 0; i < testn; i++) {
1670 for (i = 0, j = 0; i < testn; i++) {
1672 if (tmp != j)
return ret;
1681 sisusb_check_ranks(
struct sisusb_usb_data *sisusb,
int *iret,
int rankno,
1684 int ret = 0,
i, i2ret;
1689 for (i = rankno; i >= 1; i--) {
1690 inc = 1 << (rtype[
idx][2] +
1694 ret |= sisusb_check_rbc(sisusb, &i2ret, inc, 2);
1699 inc = 1 << (rtype[
idx][2] + bw / 64 + 2);
1700 ret |= sisusb_check_rbc(sisusb, &i2ret, inc, 4);
1704 inc = 1 << (10 + bw / 64);
1705 ret |= sisusb_check_rbc(sisusb, &i2ret, inc, 2);
1714 sisusb_get_sdram_size(
struct sisusb_usb_data *sisusb,
int *iret,
int bw,
1717 int ret = 0, i2ret = 0,
i,
j;
1718 static const u8 sdramtype[13][5] = {
1719 { 2, 12, 9, 64, 0x35 },
1720 { 1, 13, 9, 64, 0x44 },
1721 { 2, 12, 8, 32, 0x31 },
1722 { 2, 11, 9, 32, 0x25 },
1723 { 1, 12, 9, 32, 0x34 },
1724 { 1, 13, 8, 32, 0x40 },
1725 { 2, 11, 8, 16, 0x21 },
1726 { 1, 12, 8, 16, 0x30 },
1727 { 1, 11, 9, 16, 0x24 },
1728 { 1, 11, 8, 8, 0x20 },
1729 { 2, 9, 8, 4, 0x01 },
1730 { 1, 10, 8, 4, 0x10 },
1731 { 1, 9, 8, 2, 0x00 }
1736 for (i = 0; i < 13; i++) {
1738 for (j = 2; j > 0; j--) {
1739 ret |= sisusb_set_rank(sisusb, &i2ret, i, j,
1740 chab, sdramtype, bw);
1744 ret |= sisusb_check_ranks(sisusb, &i2ret, j, i,
1757 sisusb_setup_screen(
struct sisusb_usb_data *sisusb,
int clrall,
int drwfr)
1763 modex = 640; modey = 480; bpp = 2;
1770 length = modex * bpp * modey;
1772 ret = sisusb_clear_vram(sisusb, address, length);
1774 if (!ret && drwfr) {
1775 for (i = 0; i < modex; i++) {
1779 address += (modex * (modey-1) * bpp);
1783 for (i = 0; i < modey; i++) {
1784 address = sisusb->
vrambase + ((i * modex) * bpp);
1787 address += ((modex - 1) * bpp);
1797 sisusb_set_default_mode(
struct sisusb_usb_data *sisusb,
int touchengines)
1799 int ret = 0,
i,
j, modex, modey,
bpp, du;
1800 u8 sr31, cr63, tmp8;
1801 static const char attrdata[] = {
1802 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
1803 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
1806 static const char crtcrdata[] = {
1807 0x5f,0x4f,0x50,0x82,0x54,0x80,0x0b,0x3e,
1808 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
1809 0xea,0x8c,0xdf,0x28,0x40,0xe7,0x04,0xa3,
1812 static const char grcdata[] = {
1813 0x00,0x00,0x00,0x00,0x00,0x40,0x05,0x0f,
1816 static const char crtcdata[] = {
1817 0x5f,0x4f,0x4f,0x83,0x55,0x81,0x0b,0x3e,
1818 0xe9,0x8b,0xdf,0xe8,0x0c,0x00,0x00,0x05,
1822 modex = 640; modey = 480; bpp = 2;
1837 for (i = 0; i <= 0x18; i++) {
1840 for (i = 0; i <= 0x13; i++) {
1851 for (i = 0; i <= 0x08; i++) {
1855 for (i = 0x0A; i <= 0x0E; i++) {
1861 for (j = 0x00, i = 0; i <= 7; i++, j++) {
1864 for (j = 0x10; i <= 10; i++, j++) {
1867 for (j = 0x15; i <= 12; i++, j++) {
1870 for (j = 0x0A; i <= 15; i++, j++) {
1876 du = (modex / 16) * (bpp * 2);
1877 if (modex % 16) du +=
bpp;
1882 if (du & 0xff) tmp8++;
1934 static const char mclktable[] = {
1935 0x3b, 0x22, 0x01, 143,
1936 0x3b, 0x22, 0x01, 143,
1937 0x3b, 0x22, 0x01, 143,
1938 0x3b, 0x22, 0x01, 143
1940 static const char eclktable[] = {
1941 0x3b, 0x22, 0x01, 143,
1942 0x3b, 0x22, 0x01, 143,
1943 0x3b, 0x22, 0x01, 143,
1944 0x3b, 0x22, 0x01, 143
1946 static const char ramtypetable1[] = {
1947 0x00, 0x04, 0x60, 0x60,
1948 0x0f, 0x0f, 0x1f, 0x1f,
1949 0xba, 0xba, 0xba, 0xba,
1950 0xa9, 0xa9, 0xac, 0xac,
1951 0xa0, 0xa0, 0xa0, 0xa8,
1952 0x00, 0x00, 0x02, 0x02,
1953 0x30, 0x30, 0x40, 0x40
1955 static const char ramtypetable2[] = {
1956 0x77, 0x77, 0x44, 0x44,
1957 0x77, 0x77, 0x44, 0x44,
1958 0x00, 0x00, 0x00, 0x00,
1959 0x5b, 0x5b, 0xab, 0xab,
1960 0x00, 0x00, 0xf0, 0xf8
1982 for (i = 0x06; i <= 0x1f; i++) {
1985 for (i = 0x21; i <= 0x27; i++) {
1988 for (i = 0x31; i <= 0x3d; i++) {
1991 for (i = 0x12; i <= 0x1b; i++) {
1994 for (i = 0x79; i <= 0x7c; i++) {
2006 ret |=
SETIREG(
SISSR, 0x29, mclktable[(ramtype * 4) + 1]);
2007 ret |=
SETIREG(
SISSR, 0x2a, mclktable[(ramtype * 4) + 2]);
2010 ret |=
SETIREG(
SISSR, 0x2f, eclktable[(ramtype * 4) + 1]);
2011 ret |=
SETIREG(
SISSR, 0x30, eclktable[(ramtype * 4) + 2]);
2018 for (i = 0x15, j = 0; i <= 0x1b; i++, j++) {
2019 ret |=
SETIREG(
SISSR, i, ramtypetable1[(j*4) + ramtype]);
2021 for (i = 0x40, j = 0; i <= 0x44; i++, j++) {
2022 ret |=
SETIREG(
SISCR, i, ramtypetable2[(j*4) + ramtype]);
2049 ret |= sisusb_read_pci_config(sisusb, 0x50, &tmp32);
2050 tmp32 &= 0x00f00000;
2051 tmp8 = (tmp32 == 0x100000) ? 0x33 : 0x03;
2053 tmp8 = (tmp32 == 0x100000) ? 0xaa : 0x88;
2065 ret |= sisusb_set_default_mode(sisusb, 0);
2071 ret |= sisusb_triggersr16(sisusb, ramtype);
2077 ret |= sisusb_getbuswidth(sisusb, &bw, &chab);
2078 ret |= sisusb_verify_mclk(sisusb);
2081 ret |= sisusb_get_sdram_size(sisusb, &iret, bw, chab);
2083 dev_err(&sisusb->
sisusb_dev->dev,
"RAM size detection failed, assuming 8MB video RAM\n");
2088 dev_err(&sisusb->
sisusb_dev->dev,
"DDR RAM device found, assuming 8MB video RAM\n");
2094 ret |=
SETIREG(
SISSR, 0x16, ramtypetable1[4 + ramtype]);
2095 ret |=
SETIREG(
SISSR, 0x17, ramtypetable1[8 + ramtype]);
2096 ret |=
SETIREG(
SISSR, 0x19, ramtypetable1[16 + ramtype]);
2123 u8 tmp8, tmp82, ramtype;
2125 char *ramtypetext1 =
NULL;
2126 const char *ramtypetext2[] = {
"SDR SDRAM",
"SDR SGRAM",
2127 "DDR SDRAM",
"DDR SGRAM" };
2128 static const int busSDR[4] = {64, 64, 128, 128};
2129 static const int busDDR[4] = {32, 32, 64, 64};
2130 static const int busDDRA[4] = {64+32, 64+32 , (64+32)*2, (64+32)*2};
2135 sisusb->
vramsize = (1 << ((tmp8 & 0xf0) >> 4)) * 1024 * 1024;
2137 switch ((tmp8 >> 2) & 0x03) {
2138 case 0: ramtypetext1 =
"1 ch/1 r";
2142 bw = busSDR[(tmp8 & 0x03)];
2145 case 1: ramtypetext1 =
"1 ch/2 r";
2147 bw = busSDR[(tmp8 & 0x03)];
2149 case 2: ramtypetext1 =
"asymmeric";
2151 bw = busDDRA[(tmp8 & 0x03)];
2153 case 3: ramtypetext1 =
"2 channel";
2155 bw = busDDR[(tmp8 & 0x03)];
2160 ramtypetext2[ramtype], bw);
2173 packet.
data = 0x00000004;
2174 ret = sisusb_send_bridge_packet(sisusb, 10, &packet, 0);
2178 packet.
data = 0x00000004;
2179 ret |= sisusb_send_bridge_packet(sisusb, 10, &packet, 0);
2183 packet.
data = 0x00000004;
2184 ret |= sisusb_send_bridge_packet(sisusb, 10, &packet, 0);
2188 packet.
data = 0x00000700;
2189 ret |= sisusb_send_bridge_packet(sisusb, 10, &packet, 0);
2193 ret |= sisusb_send_bridge_packet(sisusb, 6, &packet, 0);
2194 packet.
data |= 0x17;
2195 ret |= sisusb_send_bridge_packet(sisusb, 10, &packet, 0);
2198 ret |= sisusb_read_pci_config(sisusb, 0x10, &tmp32);
2199 ret |= sisusb_write_pci_config(sisusb, 0x10, 0xfffffff0);
2200 ret |= sisusb_read_pci_config(sisusb, 0x10, &tmp32);
2203 ret |= sisusb_write_pci_config(sisusb, 0x10, tmp32);
2206 ret |= sisusb_read_pci_config(sisusb, 0x14, &tmp32);
2207 ret |= sisusb_write_pci_config(sisusb, 0x14, 0xfffffff0);
2208 ret |= sisusb_read_pci_config(sisusb, 0x14, &tmp32);
2211 ret |= sisusb_write_pci_config(sisusb, 0x14, tmp32);
2214 ret |= sisusb_read_pci_config(sisusb, 0x18, &tmp32);
2215 ret |= sisusb_write_pci_config(sisusb, 0x18, 0xfffffff0);
2216 ret |= sisusb_read_pci_config(sisusb, 0x18, &tmp32);
2219 ret |= sisusb_write_pci_config(sisusb, 0x18, tmp32);
2222 ret |= sisusb_read_pci_config(sisusb, 0x04, &tmp32);
2224 ret |= sisusb_write_pci_config(sisusb, 0x04, tmp32);
2230 packet.
data = 0x000000ff;
2231 ret |= sisusb_send_bridge_packet(sisusb, 10, &packet, 0);
2245 int ret = 0,
test = 0;
2250 ret |= sisusb_read_pci_config(sisusb, 0x10, &tmp32);
2251 if (ret)
return ret;
2254 ret |= sisusb_read_pci_config(sisusb, 0x14, &tmp32);
2255 if (ret)
return ret;
2258 ret |= sisusb_read_pci_config(sisusb, 0x18, &tmp32);
2259 if (ret)
return ret;
2266 ret |= sisusb_do_init_gfxdevice(sisusb);
2275 if (sisusb_init_gfxcore(sisusb) == 0) {
2277 sisusb_get_ramconfig(sisusb);
2278 ret |= sisusb_set_default_mode(sisusb, 1);
2279 ret |= sisusb_setup_screen(sisusb, 1, initscreen);
2287 #ifdef INCL_SISUSB_CON
2298 int ret = 0,
slot = sisusb->font_slot,
i;
2303 static const char bootstring[] =
"SiSUSB VGA text console, (C) 2005 Thomas Winischhofer.";
2304 static const char bootlogo[] =
"(o_ //\\ V_/_";
2308 if (!sisusb->SiS_Pr)
2312 sisusb->SiS_Pr->sisusb = (
void *)sisusb;
2320 if (!(tempbuf =
vmalloc(8192)))
2323 for (i = 0; i < 256; i++)
2324 memcpy(tempbuf + (i * 32), myfont->
data + (i * 16), 16);
2332 if (sisusb->font_backup) {
2334 8192, sisusb->font_backup_512, 1,
NULL,
2335 sisusb->font_backup_height, 0);
2341 if (init && !sisusb->scrbuf) {
2343 if ((tempbuf =
vmalloc(8192))) {
2346 tempbufb = (
u16 *)tempbuf;
2348 *(tempbufb++) = 0x0720;
2351 tempbufb = (
u16 *)tempbuf;
2352 while (bootlogo[i]) {
2353 *(tempbufb++) = 0x0700 | bootlogo[i++];
2359 tempbufb = (
u16 *)tempbuf + 6;
2360 while (bootstring[i])
2361 *(tempbufb++) = 0x0700 | bootstring[i++];
2370 }
else if (sisusb->scrbuf) {
2373 sisusb->
vrambase, sisusb->scrbuf_size, &written);
2377 if (sisusb->sisusb_cursor_size_from >= 0 &&
2378 sisusb->sisusb_cursor_size_to >= 0) {
2380 sisusb->sisusb_cursor_size_from);
2382 sisusb->sisusb_cursor_size_to);
2386 sisusb->sisusb_cursor_size_to = -1;
2389 slot = sisusb->sisusb_cursor_loc;
2392 sisusb->sisusb_cursor_loc = -1;
2393 sisusb->bad_cursor_pos = 1;
2400 sisusb->textmodedestroyed = 0;
2416 int subminor = iminor(inode);
2422 if (!(sisusb = usb_get_intfdata(interface))) {
2441 if (sisusb_init_gfxdevice(sisusb, 0)) {
2454 kref_get(&sisusb->
kref);
2477 sisusb_free_buffers(sisusb);
2478 sisusb_free_urbs(sisusb);
2479 #ifdef INCL_SISUSB_CON
2480 kfree(sisusb->SiS_Pr);
2486 sisusb_release(
struct inode *inode,
struct file *file)
2497 if (!sisusb_wait_all_out_complete(sisusb))
2498 sisusb_kill_all_busy(sisusb);
2513 sisusb_read(
struct file *file,
char __user *buffer,
size_t count, loff_t *ppos)
2548 if (sisusb_read_memio_byte(sisusb,
2552 else if (
put_user(buf8, (
u8 __user *)buffer))
2560 if (sisusb_read_memio_word(sisusb,
2572 if (sisusb_read_memio_long(sisusb,
2598 errno = sisusb_read_mem_bulk(sisusb, address,
2599 NULL, count, buffer, &bytes_read);
2614 errno = sisusb_read_mem_bulk(sisusb, address,
2615 NULL, count, buffer, &bytes_read);
2633 if (sisusb_read_pci_config(sisusb, address, &buf32))
2646 (*ppos) += bytes_read;
2650 return errno ? errno : bytes_read;
2654 sisusb_write(
struct file *file,
const char __user *buffer,
size_t count,
2692 else if (sisusb_write_memio_byte(sisusb,
2704 else if (sisusb_write_memio_word(sisusb,
2716 else if (sisusb_write_memio_long(sisusb,
2742 errno = sisusb_write_mem_bulk(sisusb, address,
NULL,
2743 count, buffer, 0, &bytes_written);
2746 errno = bytes_written;
2760 errno = sisusb_write_mem_bulk(sisusb, address,
NULL,
2761 count, buffer, 0, &bytes_written);
2764 errno = bytes_written;
2766 }
else if ((*ppos) >= SISUSB_PCI_PSEUDO_PCIBASE &&
2781 else if (sisusb_write_pci_config(sisusb, address, buf32))
2794 (*ppos) += bytes_written;
2798 return errno ? errno : bytes_written;
2802 sisusb_lseek(
struct file *file, loff_t
offset,
int orig)
2887 retval = sisusb_setidxregmask(sisusb, port,
2897 address = y->
data3 -
2900 retval = sisusb_clear_vram(sisusb, address, length);
2905 #ifdef INCL_SISUSB_CON
2907 if (!sisusb->
gfxinit || !sisusb->SiS_Pr)
2915 sisusb->textmodedestroyed = 1;
2921 #ifdef INCL_SISUSB_CON
2924 if (!sisusb->
gfxinit || !sisusb->SiS_Pr)
2929 sisusb->SiS_Pr->IOAddress = SISUSB_PCI_IOPORTBASE + 0x30;
2930 sisusb->SiS_Pr->sisusb = (
void *)sisusb;
2939 if (!sisusb->
gfxinit || !sisusb->SiS_Pr)
2944 sisusb->SiS_Pr->IOAddress = SISUSB_PCI_IOPORTBASE + 0x30;
2945 sisusb->SiS_Pr->sisusb = (
void *)sisusb;
2964 sisusb_ioctl(
struct file *file,
unsigned int cmd,
unsigned long arg)
2998 x.sisusb_gfxinit = sisusb->
gfxinit;
3004 x.sisusb_minor = sisusb->
minor;
3005 x.sisusb_fbdevactive= 0;
3006 #ifdef INCL_SISUSB_CON
3007 x.sisusb_conactive = sisusb->haveconsole ? 1 : 0;
3009 x.sisusb_conactive = 0;
3011 memset(
x.sisusb_reserved, 0,
sizeof(
x.sisusb_reserved));
3023 retval = sisusb_handle_command(sisusb, &y, arg);
3037 #ifdef SISUSB_NEW_CONFIG_COMPAT
3039 sisusb_compat_ioctl(
struct file *
f,
unsigned int cmd,
unsigned long arg)
3047 retval = sisusb_ioctl(f, cmd, arg);
3058 .open = sisusb_open,
3059 .release = sisusb_release,
3060 .read = sisusb_read,
3061 .write = sisusb_write,
3062 .llseek = sisusb_lseek,
3063 #ifdef SISUSB_NEW_CONFIG_COMPAT
3064 .compat_ioctl = sisusb_compat_ioctl,
3066 .unlocked_ioctl = sisusb_ioctl
3069 static struct usb_class_driver usb_sisusb_class = {
3070 .name =
"sisusbvga%d",
3071 .fops = &usb_sisusb_fops,
3078 struct usb_device *
dev = interface_to_usbdev(intf);
3082 dev_info(&dev->dev,
"USB2VGA dongle found at address %d\n",
3086 if (!(sisusb = kzalloc(
sizeof(*sisusb),
GFP_KERNEL))) {
3087 dev_err(&sisusb->
sisusb_dev->dev,
"Failed to allocate memory for private data\n");
3090 kref_init(&sisusb->
kref);
3103 sisusb->
minor = intf->minor;
3113 dev_err(&sisusb->
sisusb_dev->dev,
"Failed to allocate memory for input buffer");
3123 dev_err(&sisusb->
sisusb_dev->dev,
"Failed to allocate memory for output buffer\n");
3141 for (i = 0; i < sisusb->
numobufs; i++) {
3154 #ifdef INCL_SISUSB_CON
3165 usb_set_intfdata(intf, sisusb);
3173 #ifdef INCL_SISUSB_CON
3174 if (sisusb_first_vc > 0 &&
3175 sisusb_last_vc > 0 &&
3176 sisusb_first_vc <= sisusb_last_vc &&
3180 if (sisusb_init_gfxdevice(sisusb, initscreen))
3188 #ifdef SISUSBENDIANTEST
3190 sisusb_testreadwrite(sisusb);
3194 #ifdef INCL_SISUSB_CON
3201 sisusb_free_urbs(sisusb);
3203 sisusb_free_buffers(sisusb);
3216 if (!(sisusb = usb_get_intfdata(intf)))
3219 #ifdef INCL_SISUSB_CON
3228 if (!sisusb_wait_all_out_complete(sisusb))
3229 sisusb_kill_all_busy(sisusb);
3231 usb_set_intfdata(intf,
NULL);
3243 { USB_DEVICE(0x0711, 0x0550) },
3244 { USB_DEVICE(0x0711, 0x0900) },
3245 { USB_DEVICE(0x0711, 0x0901) },
3246 { USB_DEVICE(0x0711, 0x0902) },
3247 { USB_DEVICE(0x0711, 0x0903) },
3248 { USB_DEVICE(0x0711, 0x0918) },
3249 { USB_DEVICE(0x0711, 0x0920) },
3250 { USB_DEVICE(0x182d, 0x021c) },
3251 { USB_DEVICE(0x182d, 0x0269) },
3257 static struct usb_driver sisusb_driver = {
3259 .probe = sisusb_probe,
3260 .disconnect = sisusb_disconnect,
3261 .id_table = sisusb_table,
3264 static int __init usb_sisusb_init(
void)
3267 #ifdef INCL_SISUSB_CON
3271 return usb_register(&sisusb_driver);
3274 static void __exit usb_sisusb_exit(
void)