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