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