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 	static const char ram_datarate[4] = {'S', 'S', 'D', 'D'};
2127 	static const char ram_dynamictype[4] = {'D', 'G', 'D', 'G'};
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 
2160 	dev_info(&sisusb->sisusb_dev->dev, "%dMB %s %cDR S%cRAM, bus width %d\n",
2161 		 sisusb->vramsize >> 20, ramtypetext1,
2162 		 ram_datarate[ramtype], ram_dynamictype[ramtype], bw);
2163 }
2164 
2165 static int
sisusb_do_init_gfxdevice(struct sisusb_usb_data * sisusb)2166 sisusb_do_init_gfxdevice(struct sisusb_usb_data *sisusb)
2167 {
2168 	struct sisusb_packet packet;
2169 	int ret;
2170 	u32 tmp32;
2171 
2172 	/* Do some magic */
2173 	packet.header  = 0x001f;
2174 	packet.address = 0x00000324;
2175 	packet.data    = 0x00000004;
2176 	ret = sisusb_send_bridge_packet(sisusb, 10, &packet, 0);
2177 
2178 	packet.header  = 0x001f;
2179 	packet.address = 0x00000364;
2180 	packet.data    = 0x00000004;
2181 	ret |= sisusb_send_bridge_packet(sisusb, 10, &packet, 0);
2182 
2183 	packet.header  = 0x001f;
2184 	packet.address = 0x00000384;
2185 	packet.data    = 0x00000004;
2186 	ret |= sisusb_send_bridge_packet(sisusb, 10, &packet, 0);
2187 
2188 	packet.header  = 0x001f;
2189 	packet.address = 0x00000100;
2190 	packet.data    = 0x00000700;
2191 	ret |= sisusb_send_bridge_packet(sisusb, 10, &packet, 0);
2192 
2193 	packet.header  = 0x000f;
2194 	packet.address = 0x00000004;
2195 	ret |= sisusb_send_bridge_packet(sisusb, 6, &packet, 0);
2196 	packet.data |= 0x17;
2197 	ret |= sisusb_send_bridge_packet(sisusb, 10, &packet, 0);
2198 
2199 	/* Init BAR 0 (VRAM) */
2200 	ret |= sisusb_read_pci_config(sisusb, 0x10, &tmp32);
2201 	ret |= sisusb_write_pci_config(sisusb, 0x10, 0xfffffff0);
2202 	ret |= sisusb_read_pci_config(sisusb, 0x10, &tmp32);
2203 	tmp32 &= 0x0f;
2204 	tmp32 |= SISUSB_PCI_MEMBASE;
2205 	ret |= sisusb_write_pci_config(sisusb, 0x10, tmp32);
2206 
2207 	/* Init BAR 1 (MMIO) */
2208 	ret |= sisusb_read_pci_config(sisusb, 0x14, &tmp32);
2209 	ret |= sisusb_write_pci_config(sisusb, 0x14, 0xfffffff0);
2210 	ret |= sisusb_read_pci_config(sisusb, 0x14, &tmp32);
2211 	tmp32 &= 0x0f;
2212 	tmp32 |= SISUSB_PCI_MMIOBASE;
2213 	ret |= sisusb_write_pci_config(sisusb, 0x14, tmp32);
2214 
2215 	/* Init BAR 2 (i/o ports) */
2216 	ret |= sisusb_read_pci_config(sisusb, 0x18, &tmp32);
2217 	ret |= sisusb_write_pci_config(sisusb, 0x18, 0xfffffff0);
2218 	ret |= sisusb_read_pci_config(sisusb, 0x18, &tmp32);
2219 	tmp32 &= 0x0f;
2220 	tmp32 |= SISUSB_PCI_IOPORTBASE;
2221 	ret |= sisusb_write_pci_config(sisusb, 0x18, tmp32);
2222 
2223 	/* Enable memory and i/o access */
2224 	ret |= sisusb_read_pci_config(sisusb, 0x04, &tmp32);
2225 	tmp32 |= 0x3;
2226 	ret |= sisusb_write_pci_config(sisusb, 0x04, tmp32);
2227 
2228 	if (ret == 0) {
2229 		/* Some further magic */
2230 		packet.header  = 0x001f;
2231 		packet.address = 0x00000050;
2232 		packet.data    = 0x000000ff;
2233 		ret |= sisusb_send_bridge_packet(sisusb, 10, &packet, 0);
2234 	}
2235 
2236 	return ret;
2237 }
2238 
2239 /* Initialize the graphics device (return 0 on success)
2240  * This initializes the net2280 as well as the PCI registers
2241  * of the graphics board.
2242  */
2243 
2244 static int
sisusb_init_gfxdevice(struct sisusb_usb_data * sisusb,int initscreen)2245 sisusb_init_gfxdevice(struct sisusb_usb_data *sisusb, int initscreen)
2246 {
2247 	int ret = 0, test = 0;
2248 	u32 tmp32;
2249 
2250 	if (sisusb->devinit == 1) {
2251 		/* Read PCI BARs and see if they have been set up */
2252 		ret |= sisusb_read_pci_config(sisusb, 0x10, &tmp32);
2253 		if (ret) return ret;
2254 		if ((tmp32 & 0xfffffff0) == SISUSB_PCI_MEMBASE) test++;
2255 
2256 		ret |= sisusb_read_pci_config(sisusb, 0x14, &tmp32);
2257 		if (ret) return ret;
2258 		if ((tmp32 & 0xfffffff0) == SISUSB_PCI_MMIOBASE) test++;
2259 
2260 		ret |= sisusb_read_pci_config(sisusb, 0x18, &tmp32);
2261 		if (ret) return ret;
2262 		if ((tmp32 & 0xfffffff0) == SISUSB_PCI_IOPORTBASE) test++;
2263 	}
2264 
2265 	/* No? So reset the device */
2266 	if ((sisusb->devinit == 0) || (test != 3)) {
2267 
2268 		ret |= sisusb_do_init_gfxdevice(sisusb);
2269 
2270 		if (ret == 0)
2271 			sisusb->devinit = 1;
2272 
2273 	}
2274 
2275 	if (sisusb->devinit) {
2276 		/* Initialize the graphics core */
2277 		if (sisusb_init_gfxcore(sisusb) == 0) {
2278 			sisusb->gfxinit = 1;
2279 			sisusb_get_ramconfig(sisusb);
2280 			ret |= sisusb_set_default_mode(sisusb, 1);
2281 			ret |= sisusb_setup_screen(sisusb, 1, initscreen);
2282 		}
2283 	}
2284 
2285 	return ret;
2286 }
2287 
2288 
2289 #ifdef INCL_SISUSB_CON
2290 
2291 /* Set up default text mode:
2292    - Set text mode (0x03)
2293    - Upload default font
2294    - Upload user font (if available)
2295 */
2296 
2297 int
sisusb_reset_text_mode(struct sisusb_usb_data * sisusb,int init)2298 sisusb_reset_text_mode(struct sisusb_usb_data *sisusb, int init)
2299 {
2300 	int ret = 0, slot = sisusb->font_slot, i;
2301 	const struct font_desc *myfont;
2302 	u8 *tempbuf;
2303 	u16 *tempbufb;
2304 	size_t written;
2305 	static const char bootstring[] = "SiSUSB VGA text console, (C) 2005 Thomas Winischhofer.";
2306 	static const char bootlogo[] = "(o_ //\\ V_/_";
2307 
2308 	/* sisusb->lock is down */
2309 
2310 	if (!sisusb->SiS_Pr)
2311 		return 1;
2312 
2313 	sisusb->SiS_Pr->IOAddress = SISUSB_PCI_IOPORTBASE + 0x30;
2314 	sisusb->SiS_Pr->sisusb = (void *)sisusb;
2315 
2316 	/* Set mode 0x03 */
2317 	SiSUSBSetMode(sisusb->SiS_Pr, 0x03);
2318 
2319 	myfont = find_font("VGA8x16");
2320 	if (!myfont)
2321 		return 1;
2322 
2323 	tempbuf = vmalloc(8192);
2324 	if (!tempbuf)
2325 		return 1;
2326 
2327 	for (i = 0; i < 256; i++)
2328 		memcpy(tempbuf + (i * 32), myfont->data + (i * 16), 16);
2329 
2330 	/* Upload default font */
2331 	ret = sisusbcon_do_font_op(sisusb, 1, 0, tempbuf, 8192, 0, 1, NULL, 16, 0);
2332 
2333 	vfree(tempbuf);
2334 
2335 	/* Upload user font (and reset current slot) */
2336 	if (sisusb->font_backup) {
2337 		ret |= sisusbcon_do_font_op(sisusb, 1, 2, sisusb->font_backup,
2338 				8192, sisusb->font_backup_512, 1, NULL,
2339 				sisusb->font_backup_height, 0);
2340 		if (slot != 2)
2341 			sisusbcon_do_font_op(sisusb, 1, 0, NULL, 0, 0, 1,
2342 					NULL, 16, 0);
2343 	}
2344 
2345 	if (init && !sisusb->scrbuf) {
2346 
2347 		tempbuf = vmalloc(8192);
2348 		if (tempbuf) {
2349 
2350 			i = 4096;
2351 			tempbufb = (u16 *)tempbuf;
2352 			while (i--)
2353 				*(tempbufb++) = 0x0720;
2354 
2355 			i = 0;
2356 			tempbufb = (u16 *)tempbuf;
2357 			while (bootlogo[i]) {
2358 				*(tempbufb++) = 0x0700 | bootlogo[i++];
2359 				if (!(i % 4))
2360 					tempbufb += 76;
2361 			}
2362 
2363 			i = 0;
2364 			tempbufb = (u16 *)tempbuf + 6;
2365 			while (bootstring[i])
2366 				*(tempbufb++) = 0x0700 | bootstring[i++];
2367 
2368 			ret |= sisusb_copy_memory(sisusb, tempbuf,
2369 				sisusb->vrambase, 8192, &written);
2370 
2371 			vfree(tempbuf);
2372 
2373 		}
2374 
2375 	} else if (sisusb->scrbuf) {
2376 
2377 		ret |= sisusb_copy_memory(sisusb, (char *)sisusb->scrbuf,
2378 				sisusb->vrambase, sisusb->scrbuf_size, &written);
2379 
2380 	}
2381 
2382 	if (sisusb->sisusb_cursor_size_from >= 0 &&
2383 	    sisusb->sisusb_cursor_size_to >= 0) {
2384 		sisusb_setidxreg(sisusb, SISCR, 0x0a,
2385 				sisusb->sisusb_cursor_size_from);
2386 		sisusb_setidxregandor(sisusb, SISCR, 0x0b, 0xe0,
2387 				sisusb->sisusb_cursor_size_to);
2388 	} else {
2389 		sisusb_setidxreg(sisusb, SISCR, 0x0a, 0x2d);
2390 		sisusb_setidxreg(sisusb, SISCR, 0x0b, 0x0e);
2391 		sisusb->sisusb_cursor_size_to = -1;
2392 	}
2393 
2394 	slot = sisusb->sisusb_cursor_loc;
2395 	if(slot < 0) slot = 0;
2396 
2397 	sisusb->sisusb_cursor_loc = -1;
2398 	sisusb->bad_cursor_pos = 1;
2399 
2400 	sisusb_set_cursor(sisusb, slot);
2401 
2402 	sisusb_setidxreg(sisusb, SISCR, 0x0c, (sisusb->cur_start_addr >> 8));
2403 	sisusb_setidxreg(sisusb, SISCR, 0x0d, (sisusb->cur_start_addr & 0xff));
2404 
2405 	sisusb->textmodedestroyed = 0;
2406 
2407 	/* sisusb->lock is down */
2408 
2409 	return ret;
2410 }
2411 
2412 #endif
2413 
2414 /* fops */
2415 
2416 static int
sisusb_open(struct inode * inode,struct file * file)2417 sisusb_open(struct inode *inode, struct file *file)
2418 {
2419 	struct sisusb_usb_data *sisusb;
2420 	struct usb_interface *interface;
2421 	int subminor = iminor(inode);
2422 
2423 	interface = usb_find_interface(&sisusb_driver, subminor);
2424 	if (!interface) {
2425 		return -ENODEV;
2426 	}
2427 
2428 	sisusb = usb_get_intfdata(interface);
2429 	if (!sisusb) {
2430 		return -ENODEV;
2431 	}
2432 
2433 	mutex_lock(&sisusb->lock);
2434 
2435 	if (!sisusb->present || !sisusb->ready) {
2436 		mutex_unlock(&sisusb->lock);
2437 		return -ENODEV;
2438 	}
2439 
2440 	if (sisusb->isopen) {
2441 		mutex_unlock(&sisusb->lock);
2442 		return -EBUSY;
2443 	}
2444 
2445 	if (!sisusb->devinit) {
2446 		if (sisusb->sisusb_dev->speed == USB_SPEED_HIGH ||
2447 		    sisusb->sisusb_dev->speed == USB_SPEED_SUPER) {
2448 			if (sisusb_init_gfxdevice(sisusb, 0)) {
2449 				mutex_unlock(&sisusb->lock);
2450 				dev_err(&sisusb->sisusb_dev->dev, "Failed to initialize device\n");
2451 				return -EIO;
2452 			}
2453 		} else {
2454 			mutex_unlock(&sisusb->lock);
2455 			dev_err(&sisusb->sisusb_dev->dev, "Device not attached to USB 2.0 hub\n");
2456 			return -EIO;
2457 		}
2458 	}
2459 
2460 	/* Increment usage count for our sisusb */
2461 	kref_get(&sisusb->kref);
2462 
2463 	sisusb->isopen = 1;
2464 
2465 	file->private_data = sisusb;
2466 
2467 	mutex_unlock(&sisusb->lock);
2468 
2469 	return 0;
2470 }
2471 
2472 void
sisusb_delete(struct kref * kref)2473 sisusb_delete(struct kref *kref)
2474 {
2475 	struct sisusb_usb_data *sisusb = to_sisusb_dev(kref);
2476 
2477 	if (!sisusb)
2478 		return;
2479 
2480 	usb_put_dev(sisusb->sisusb_dev);
2481 
2482 	sisusb->sisusb_dev = NULL;
2483 	sisusb_free_buffers(sisusb);
2484 	sisusb_free_urbs(sisusb);
2485 #ifdef INCL_SISUSB_CON
2486 	kfree(sisusb->SiS_Pr);
2487 #endif
2488 	kfree(sisusb);
2489 }
2490 
2491 static int
sisusb_release(struct inode * inode,struct file * file)2492 sisusb_release(struct inode *inode, struct file *file)
2493 {
2494 	struct sisusb_usb_data *sisusb;
2495 
2496 	sisusb = file->private_data;
2497 	if (!sisusb)
2498 		return -ENODEV;
2499 
2500 	mutex_lock(&sisusb->lock);
2501 
2502 	if (sisusb->present) {
2503 		/* Wait for all URBs to finish if device still present */
2504 		if (!sisusb_wait_all_out_complete(sisusb))
2505 			sisusb_kill_all_busy(sisusb);
2506 	}
2507 
2508 	sisusb->isopen = 0;
2509 	file->private_data = NULL;
2510 
2511 	mutex_unlock(&sisusb->lock);
2512 
2513 	/* decrement the usage count on our device */
2514 	kref_put(&sisusb->kref, sisusb_delete);
2515 
2516 	return 0;
2517 }
2518 
2519 static ssize_t
sisusb_read(struct file * file,char __user * buffer,size_t count,loff_t * ppos)2520 sisusb_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
2521 {
2522 	struct sisusb_usb_data *sisusb;
2523 	ssize_t bytes_read = 0;
2524 	int errno = 0;
2525 	u8 buf8;
2526 	u16 buf16;
2527 	u32 buf32, address;
2528 
2529 	sisusb = file->private_data;
2530 	if (!sisusb)
2531 		return -ENODEV;
2532 
2533 	mutex_lock(&sisusb->lock);
2534 
2535 	/* Sanity check */
2536 	if (!sisusb->present || !sisusb->ready || !sisusb->sisusb_dev) {
2537 		mutex_unlock(&sisusb->lock);
2538 		return -ENODEV;
2539 	}
2540 
2541 	if ((*ppos) >= SISUSB_PCI_PSEUDO_IOPORTBASE &&
2542 	    (*ppos) <  SISUSB_PCI_PSEUDO_IOPORTBASE + 128) {
2543 
2544 		address = (*ppos) -
2545 			SISUSB_PCI_PSEUDO_IOPORTBASE +
2546 			SISUSB_PCI_IOPORTBASE;
2547 
2548 		/* Read i/o ports
2549 		 * Byte, word and long(32) can be read. As this
2550 		 * emulates inX instructions, the data returned is
2551 		 * in machine-endianness.
2552 		 */
2553 		switch (count) {
2554 
2555 			case 1:
2556 				if (sisusb_read_memio_byte(sisusb,
2557 							SISUSB_TYPE_IO,
2558 							address, &buf8))
2559 					errno = -EIO;
2560 				else if (put_user(buf8, (u8 __user *)buffer))
2561 					errno = -EFAULT;
2562 				else
2563 					bytes_read = 1;
2564 
2565 				break;
2566 
2567 			case 2:
2568 				if (sisusb_read_memio_word(sisusb,
2569 							SISUSB_TYPE_IO,
2570 							address, &buf16))
2571 					errno = -EIO;
2572 				else if (put_user(buf16, (u16 __user *)buffer))
2573 					errno = -EFAULT;
2574 				else
2575 					bytes_read = 2;
2576 
2577 				break;
2578 
2579 			case 4:
2580 				if (sisusb_read_memio_long(sisusb,
2581 							SISUSB_TYPE_IO,
2582 							address, &buf32))
2583 					errno = -EIO;
2584 				else if (put_user(buf32, (u32 __user *)buffer))
2585 					errno = -EFAULT;
2586 				else
2587 					bytes_read = 4;
2588 
2589 				break;
2590 
2591 			default:
2592 				errno = -EIO;
2593 
2594 		}
2595 
2596 	} else if ((*ppos) >= SISUSB_PCI_PSEUDO_MEMBASE &&
2597 		   (*ppos) <  SISUSB_PCI_PSEUDO_MEMBASE + sisusb->vramsize) {
2598 
2599 		address = (*ppos) -
2600 			SISUSB_PCI_PSEUDO_MEMBASE +
2601 			SISUSB_PCI_MEMBASE;
2602 
2603 		/* Read video ram
2604 		 * Remember: Data delivered is never endian-corrected
2605 		 */
2606 		errno = sisusb_read_mem_bulk(sisusb, address,
2607 					NULL, count, buffer, &bytes_read);
2608 
2609 		if (bytes_read)
2610 			errno = bytes_read;
2611 
2612 	} else  if ((*ppos) >= SISUSB_PCI_PSEUDO_MMIOBASE &&
2613 		    (*ppos) <  SISUSB_PCI_PSEUDO_MMIOBASE + SISUSB_PCI_MMIOSIZE) {
2614 
2615 		address = (*ppos) -
2616 			SISUSB_PCI_PSEUDO_MMIOBASE +
2617 			SISUSB_PCI_MMIOBASE;
2618 
2619 		/* Read MMIO
2620 		 * Remember: Data delivered is never endian-corrected
2621 		 */
2622 		errno = sisusb_read_mem_bulk(sisusb, address,
2623 					NULL, count, buffer, &bytes_read);
2624 
2625 		if (bytes_read)
2626 			errno = bytes_read;
2627 
2628 	} else  if ((*ppos) >= SISUSB_PCI_PSEUDO_PCIBASE &&
2629 		    (*ppos) <= SISUSB_PCI_PSEUDO_PCIBASE + 0x5c) {
2630 
2631 		if (count != 4) {
2632 			mutex_unlock(&sisusb->lock);
2633 			return -EINVAL;
2634 		}
2635 
2636 		address = (*ppos) - SISUSB_PCI_PSEUDO_PCIBASE;
2637 
2638 		/* Read PCI config register
2639 		 * Return value delivered in machine endianness.
2640 		 */
2641 		if (sisusb_read_pci_config(sisusb, address, &buf32))
2642 			errno = -EIO;
2643 		else if (put_user(buf32, (u32 __user *)buffer))
2644 			errno = -EFAULT;
2645 		else
2646 			bytes_read = 4;
2647 
2648 	} else {
2649 
2650 		errno = -EBADFD;
2651 
2652 	}
2653 
2654 	(*ppos) += bytes_read;
2655 
2656 	mutex_unlock(&sisusb->lock);
2657 
2658 	return errno ? errno : bytes_read;
2659 }
2660 
2661 static ssize_t
sisusb_write(struct file * file,const char __user * buffer,size_t count,loff_t * ppos)2662 sisusb_write(struct file *file, const char __user *buffer, size_t count,
2663 								loff_t *ppos)
2664 {
2665 	struct sisusb_usb_data *sisusb;
2666 	int errno = 0;
2667 	ssize_t bytes_written = 0;
2668 	u8 buf8;
2669 	u16 buf16;
2670 	u32 buf32, address;
2671 
2672 	sisusb = file->private_data;
2673 	if (!sisusb)
2674 		return -ENODEV;
2675 
2676 	mutex_lock(&sisusb->lock);
2677 
2678 	/* Sanity check */
2679 	if (!sisusb->present || !sisusb->ready || !sisusb->sisusb_dev) {
2680 		mutex_unlock(&sisusb->lock);
2681 		return -ENODEV;
2682 	}
2683 
2684 	if ((*ppos) >= SISUSB_PCI_PSEUDO_IOPORTBASE &&
2685 	    (*ppos) <  SISUSB_PCI_PSEUDO_IOPORTBASE + 128) {
2686 
2687 		address = (*ppos) -
2688 			SISUSB_PCI_PSEUDO_IOPORTBASE +
2689 			SISUSB_PCI_IOPORTBASE;
2690 
2691 		/* Write i/o ports
2692 		 * Byte, word and long(32) can be written. As this
2693 		 * emulates outX instructions, the data is expected
2694 		 * in machine-endianness.
2695 		 */
2696 		switch (count) {
2697 
2698 			case 1:
2699 				if (get_user(buf8, (u8 __user *)buffer))
2700 					errno = -EFAULT;
2701 				else if (sisusb_write_memio_byte(sisusb,
2702 							SISUSB_TYPE_IO,
2703 							address, buf8))
2704 					errno = -EIO;
2705 				else
2706 					bytes_written = 1;
2707 
2708 				break;
2709 
2710 			case 2:
2711 				if (get_user(buf16, (u16 __user *)buffer))
2712 					errno = -EFAULT;
2713 				else if (sisusb_write_memio_word(sisusb,
2714 							SISUSB_TYPE_IO,
2715 							address, buf16))
2716 					errno = -EIO;
2717 				else
2718 					bytes_written = 2;
2719 
2720 				break;
2721 
2722 			case 4:
2723 				if (get_user(buf32, (u32 __user *)buffer))
2724 					errno = -EFAULT;
2725 				else if (sisusb_write_memio_long(sisusb,
2726 							SISUSB_TYPE_IO,
2727 							address, buf32))
2728 					errno = -EIO;
2729 				else
2730 					bytes_written = 4;
2731 
2732 				break;
2733 
2734 			default:
2735 				errno = -EIO;
2736 		}
2737 
2738 	} else if ((*ppos) >= SISUSB_PCI_PSEUDO_MEMBASE &&
2739 		   (*ppos) <  SISUSB_PCI_PSEUDO_MEMBASE + sisusb->vramsize) {
2740 
2741 		address = (*ppos) -
2742 			SISUSB_PCI_PSEUDO_MEMBASE +
2743 			SISUSB_PCI_MEMBASE;
2744 
2745 		/* Write video ram.
2746 		 * Buffer is copied 1:1, therefore, on big-endian
2747 		 * machines, the data must be swapped by userland
2748 		 * in advance (if applicable; no swapping in 8bpp
2749 		 * mode or if YUV data is being transferred).
2750 		 */
2751 		errno = sisusb_write_mem_bulk(sisusb, address, NULL,
2752 					count, buffer, 0, &bytes_written);
2753 
2754 		if (bytes_written)
2755 			errno = bytes_written;
2756 
2757 	} else  if ((*ppos) >= SISUSB_PCI_PSEUDO_MMIOBASE &&
2758 		    (*ppos) <  SISUSB_PCI_PSEUDO_MMIOBASE + SISUSB_PCI_MMIOSIZE) {
2759 
2760 		address = (*ppos) -
2761 			SISUSB_PCI_PSEUDO_MMIOBASE +
2762 			SISUSB_PCI_MMIOBASE;
2763 
2764 		/* Write MMIO.
2765 		 * Buffer is copied 1:1, therefore, on big-endian
2766 		 * machines, the data must be swapped by userland
2767 		 * in advance.
2768 		 */
2769 		errno = sisusb_write_mem_bulk(sisusb, address, NULL,
2770 					count, buffer, 0, &bytes_written);
2771 
2772 		if (bytes_written)
2773 			errno = bytes_written;
2774 
2775 	} else  if ((*ppos) >= SISUSB_PCI_PSEUDO_PCIBASE &&
2776 		    (*ppos) <= SISUSB_PCI_PSEUDO_PCIBASE + SISUSB_PCI_PCONFSIZE) {
2777 
2778 		if (count != 4) {
2779 			mutex_unlock(&sisusb->lock);
2780 			return -EINVAL;
2781 		}
2782 
2783 		address = (*ppos) - SISUSB_PCI_PSEUDO_PCIBASE;
2784 
2785 		/* Write PCI config register.
2786 		 * Given value expected in machine endianness.
2787 		 */
2788 		if (get_user(buf32, (u32 __user *)buffer))
2789 			errno = -EFAULT;
2790 		else if (sisusb_write_pci_config(sisusb, address, buf32))
2791 			errno = -EIO;
2792 		else
2793 			bytes_written = 4;
2794 
2795 
2796 	} else {
2797 
2798 		/* Error */
2799 		errno = -EBADFD;
2800 
2801 	}
2802 
2803 	(*ppos) += bytes_written;
2804 
2805 	mutex_unlock(&sisusb->lock);
2806 
2807 	return errno ? errno : bytes_written;
2808 }
2809 
2810 static loff_t
sisusb_lseek(struct file * file,loff_t offset,int orig)2811 sisusb_lseek(struct file *file, loff_t offset, int orig)
2812 {
2813 	struct sisusb_usb_data *sisusb;
2814 	loff_t ret;
2815 
2816 	sisusb = file->private_data;
2817 	if (!sisusb)
2818 		return -ENODEV;
2819 
2820 	mutex_lock(&sisusb->lock);
2821 
2822 	/* Sanity check */
2823 	if (!sisusb->present || !sisusb->ready || !sisusb->sisusb_dev) {
2824 		mutex_unlock(&sisusb->lock);
2825 		return -ENODEV;
2826 	}
2827 
2828 	switch (orig) {
2829 		case 0:
2830 			file->f_pos = offset;
2831 			ret = file->f_pos;
2832 			/* never negative, no force_successful_syscall needed */
2833 			break;
2834 		case 1:
2835 			file->f_pos += offset;
2836 			ret = file->f_pos;
2837 			/* never negative, no force_successful_syscall needed */
2838 			break;
2839 		default:
2840 			/* seeking relative to "end of file" is not supported */
2841 			ret = -EINVAL;
2842 	}
2843 
2844 	mutex_unlock(&sisusb->lock);
2845 	return ret;
2846 }
2847 
2848 static int
sisusb_handle_command(struct sisusb_usb_data * sisusb,struct sisusb_command * y,unsigned long arg)2849 sisusb_handle_command(struct sisusb_usb_data *sisusb, struct sisusb_command *y,
2850 							unsigned long arg)
2851 {
2852 	int	retval, port, length;
2853 	u32	address;
2854 
2855 	/* All our commands require the device
2856 	 * to be initialized.
2857 	 */
2858 	if (!sisusb->devinit)
2859 		return -ENODEV;
2860 
2861 	port = y->data3 -
2862 		SISUSB_PCI_PSEUDO_IOPORTBASE +
2863 		SISUSB_PCI_IOPORTBASE;
2864 
2865 	switch (y->operation) {
2866 		case SUCMD_GET:
2867 			retval = sisusb_getidxreg(sisusb, port,
2868 							 y->data0, &y->data1);
2869 			if (!retval) {
2870 				if (copy_to_user((void __user *)arg, y,
2871 							sizeof(*y)))
2872 					retval = -EFAULT;
2873 			}
2874 			break;
2875 
2876 		case SUCMD_SET:
2877 			retval = sisusb_setidxreg(sisusb, port,
2878 						y->data0, y->data1);
2879 			break;
2880 
2881 		case SUCMD_SETOR:
2882 			retval = sisusb_setidxregor(sisusb, port,
2883 						y->data0, y->data1);
2884 			break;
2885 
2886 		case SUCMD_SETAND:
2887 			retval = sisusb_setidxregand(sisusb, port,
2888 						y->data0, y->data1);
2889 			break;
2890 
2891 		case SUCMD_SETANDOR:
2892 			retval = sisusb_setidxregandor(sisusb, port,
2893 						y->data0, y->data1, y->data2);
2894 			break;
2895 
2896 		case SUCMD_SETMASK:
2897 			retval = sisusb_setidxregmask(sisusb, port,
2898 						y->data0, y->data1, y->data2);
2899 			break;
2900 
2901 		case SUCMD_CLRSCR:
2902 			/* Gfx core must be initialized */
2903 			if (!sisusb->gfxinit)
2904 				return -ENODEV;
2905 
2906 			length = (y->data0 << 16) | (y->data1 << 8) | y->data2;
2907 			address = y->data3 -
2908 				SISUSB_PCI_PSEUDO_MEMBASE +
2909 				SISUSB_PCI_MEMBASE;
2910 			retval = sisusb_clear_vram(sisusb, address, length);
2911 			break;
2912 
2913 		case SUCMD_HANDLETEXTMODE:
2914 			retval = 0;
2915 #ifdef INCL_SISUSB_CON
2916 			/* Gfx core must be initialized, SiS_Pr must exist */
2917 			if (!sisusb->gfxinit || !sisusb->SiS_Pr)
2918 				return -ENODEV;
2919 
2920 			switch (y->data0) {
2921 			case 0:
2922 				retval = sisusb_reset_text_mode(sisusb, 0);
2923 				break;
2924 			case 1:
2925 				sisusb->textmodedestroyed = 1;
2926 				break;
2927 			}
2928 #endif
2929 			break;
2930 
2931 #ifdef INCL_SISUSB_CON
2932 		case SUCMD_SETMODE:
2933 			/* Gfx core must be initialized, SiS_Pr must exist */
2934 			if (!sisusb->gfxinit || !sisusb->SiS_Pr)
2935 				return -ENODEV;
2936 
2937 			retval = 0;
2938 
2939 			sisusb->SiS_Pr->IOAddress = SISUSB_PCI_IOPORTBASE + 0x30;
2940 			sisusb->SiS_Pr->sisusb = (void *)sisusb;
2941 
2942 			if (SiSUSBSetMode(sisusb->SiS_Pr, y->data3))
2943 				retval = -EINVAL;
2944 
2945 			break;
2946 
2947 		case SUCMD_SETVESAMODE:
2948 			/* Gfx core must be initialized, SiS_Pr must exist */
2949 			if (!sisusb->gfxinit || !sisusb->SiS_Pr)
2950 				return -ENODEV;
2951 
2952 			retval = 0;
2953 
2954 			sisusb->SiS_Pr->IOAddress = SISUSB_PCI_IOPORTBASE + 0x30;
2955 			sisusb->SiS_Pr->sisusb = (void *)sisusb;
2956 
2957 			if (SiSUSBSetVESAMode(sisusb->SiS_Pr, y->data3))
2958 				retval = -EINVAL;
2959 
2960 			break;
2961 #endif
2962 
2963 		default:
2964 			retval = -EINVAL;
2965 	}
2966 
2967 	if (retval > 0)
2968 		retval = -EIO;
2969 
2970 	return retval;
2971 }
2972 
2973 static long
sisusb_ioctl(struct file * file,unsigned int cmd,unsigned long arg)2974 sisusb_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
2975 {
2976 	struct sisusb_usb_data *sisusb;
2977 	struct sisusb_info x;
2978 	struct sisusb_command y;
2979 	long retval = 0;
2980 	u32 __user *argp = (u32 __user *)arg;
2981 
2982 	sisusb = file->private_data;
2983 	if (!sisusb)
2984 		return -ENODEV;
2985 
2986 	mutex_lock(&sisusb->lock);
2987 
2988 	/* Sanity check */
2989 	if (!sisusb->present || !sisusb->ready || !sisusb->sisusb_dev) {
2990 		retval = -ENODEV;
2991 		goto err_out;
2992 	}
2993 
2994 	switch (cmd) {
2995 
2996 		case SISUSB_GET_CONFIG_SIZE:
2997 
2998 			if (put_user(sizeof(x), argp))
2999 				retval = -EFAULT;
3000 
3001 			break;
3002 
3003 		case SISUSB_GET_CONFIG:
3004 
3005 			x.sisusb_id	    = SISUSB_ID;
3006 			x.sisusb_version    = SISUSB_VERSION;
3007 			x.sisusb_revision   = SISUSB_REVISION;
3008 			x.sisusb_patchlevel = SISUSB_PATCHLEVEL;
3009 			x.sisusb_gfxinit    = sisusb->gfxinit;
3010 			x.sisusb_vrambase   = SISUSB_PCI_PSEUDO_MEMBASE;
3011 			x.sisusb_mmiobase   = SISUSB_PCI_PSEUDO_MMIOBASE;
3012 			x.sisusb_iobase     = SISUSB_PCI_PSEUDO_IOPORTBASE;
3013 			x.sisusb_pcibase    = SISUSB_PCI_PSEUDO_PCIBASE;
3014 			x.sisusb_vramsize   = sisusb->vramsize;
3015 			x.sisusb_minor	    = sisusb->minor;
3016 			x.sisusb_fbdevactive= 0;
3017 #ifdef INCL_SISUSB_CON
3018 			x.sisusb_conactive  = sisusb->haveconsole ? 1 : 0;
3019 #else
3020 			x.sisusb_conactive  = 0;
3021 #endif
3022 			memset(x.sisusb_reserved, 0, sizeof(x.sisusb_reserved));
3023 
3024 			if (copy_to_user((void __user *)arg, &x, sizeof(x)))
3025 				retval = -EFAULT;
3026 
3027 			break;
3028 
3029 		case SISUSB_COMMAND:
3030 
3031 			if (copy_from_user(&y, (void __user *)arg, sizeof(y)))
3032 				retval = -EFAULT;
3033 			else
3034 				retval = sisusb_handle_command(sisusb, &y, arg);
3035 
3036 			break;
3037 
3038 		default:
3039 			retval = -ENOTTY;
3040 			break;
3041 	}
3042 
3043 err_out:
3044 	mutex_unlock(&sisusb->lock);
3045 	return retval;
3046 }
3047 
3048 #ifdef SISUSB_NEW_CONFIG_COMPAT
3049 static long
sisusb_compat_ioctl(struct file * f,unsigned int cmd,unsigned long arg)3050 sisusb_compat_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
3051 {
3052 	long retval;
3053 
3054 	switch (cmd) {
3055 		case SISUSB_GET_CONFIG_SIZE:
3056 		case SISUSB_GET_CONFIG:
3057 		case SISUSB_COMMAND:
3058 			retval = sisusb_ioctl(f, cmd, arg);
3059 			return retval;
3060 
3061 		default:
3062 			return -ENOIOCTLCMD;
3063 	}
3064 }
3065 #endif
3066 
3067 static const struct file_operations usb_sisusb_fops = {
3068 	.owner =	THIS_MODULE,
3069 	.open =		sisusb_open,
3070 	.release =	sisusb_release,
3071 	.read =		sisusb_read,
3072 	.write =	sisusb_write,
3073 	.llseek =	sisusb_lseek,
3074 #ifdef SISUSB_NEW_CONFIG_COMPAT
3075 	.compat_ioctl = sisusb_compat_ioctl,
3076 #endif
3077 	.unlocked_ioctl = sisusb_ioctl
3078 };
3079 
3080 static struct usb_class_driver usb_sisusb_class = {
3081 	.name =		"sisusbvga%d",
3082 	.fops =		&usb_sisusb_fops,
3083 	.minor_base =	SISUSB_MINOR
3084 };
3085 
sisusb_probe(struct usb_interface * intf,const struct usb_device_id * id)3086 static int sisusb_probe(struct usb_interface *intf,
3087 			const struct usb_device_id *id)
3088 {
3089 	struct usb_device *dev = interface_to_usbdev(intf);
3090 	struct sisusb_usb_data *sisusb;
3091 	int retval = 0, i;
3092 
3093 	dev_info(&dev->dev, "USB2VGA dongle found at address %d\n",
3094 		dev->devnum);
3095 
3096 	/* Allocate memory for our private */
3097 	sisusb = kzalloc(sizeof(*sisusb), GFP_KERNEL);
3098 	if (!sisusb) {
3099 		dev_err(&dev->dev, "Failed to allocate memory for private data\n");
3100 		return -ENOMEM;
3101 	}
3102 	kref_init(&sisusb->kref);
3103 
3104 	mutex_init(&(sisusb->lock));
3105 
3106 	/* Register device */
3107 	retval = usb_register_dev(intf, &usb_sisusb_class);
3108 	if (retval) {
3109 		dev_err(&sisusb->sisusb_dev->dev, "Failed to get a minor for device %d\n",
3110 			dev->devnum);
3111 		retval = -ENODEV;
3112 		goto error_1;
3113 	}
3114 
3115 	sisusb->sisusb_dev = dev;
3116 	sisusb->minor      = intf->minor;
3117 	sisusb->vrambase   = SISUSB_PCI_MEMBASE;
3118 	sisusb->mmiobase   = SISUSB_PCI_MMIOBASE;
3119 	sisusb->mmiosize   = SISUSB_PCI_MMIOSIZE;
3120 	sisusb->ioportbase = SISUSB_PCI_IOPORTBASE;
3121 	/* Everything else is zero */
3122 
3123 	/* Allocate buffers */
3124 	sisusb->ibufsize = SISUSB_IBUF_SIZE;
3125 	if (!(sisusb->ibuf = kmalloc(SISUSB_IBUF_SIZE, GFP_KERNEL))) {
3126 		dev_err(&sisusb->sisusb_dev->dev, "Failed to allocate memory for input buffer");
3127 		retval = -ENOMEM;
3128 		goto error_2;
3129 	}
3130 
3131 	sisusb->numobufs = 0;
3132 	sisusb->obufsize = SISUSB_OBUF_SIZE;
3133 	for (i = 0; i < NUMOBUFS; i++) {
3134 		if (!(sisusb->obuf[i] = kmalloc(SISUSB_OBUF_SIZE, GFP_KERNEL))) {
3135 			if (i == 0) {
3136 				dev_err(&sisusb->sisusb_dev->dev, "Failed to allocate memory for output buffer\n");
3137 				retval = -ENOMEM;
3138 				goto error_3;
3139 			}
3140 			break;
3141 		} else
3142 			sisusb->numobufs++;
3143 
3144 	}
3145 
3146 	/* Allocate URBs */
3147 	if (!(sisusb->sisurbin = usb_alloc_urb(0, GFP_KERNEL))) {
3148 		dev_err(&sisusb->sisusb_dev->dev, "Failed to allocate URBs\n");
3149 		retval = -ENOMEM;
3150 		goto error_3;
3151 	}
3152 	sisusb->completein = 1;
3153 
3154 	for (i = 0; i < sisusb->numobufs; i++) {
3155 		if (!(sisusb->sisurbout[i] = usb_alloc_urb(0, GFP_KERNEL))) {
3156 			dev_err(&sisusb->sisusb_dev->dev, "Failed to allocate URBs\n");
3157 			retval = -ENOMEM;
3158 			goto error_4;
3159 		}
3160 		sisusb->urbout_context[i].sisusb = (void *)sisusb;
3161 		sisusb->urbout_context[i].urbindex = i;
3162 		sisusb->urbstatus[i] = 0;
3163 	}
3164 
3165 	dev_info(&sisusb->sisusb_dev->dev, "Allocated %d output buffers\n", sisusb->numobufs);
3166 
3167 #ifdef INCL_SISUSB_CON
3168 	/* Allocate our SiS_Pr */
3169 	if (!(sisusb->SiS_Pr = kmalloc(sizeof(struct SiS_Private), GFP_KERNEL))) {
3170 		dev_err(&sisusb->sisusb_dev->dev, "Failed to allocate SiS_Pr\n");
3171 	}
3172 #endif
3173 
3174 	/* Do remaining init stuff */
3175 
3176 	init_waitqueue_head(&sisusb->wait_q);
3177 
3178 	usb_set_intfdata(intf, sisusb);
3179 
3180 	usb_get_dev(sisusb->sisusb_dev);
3181 
3182 	sisusb->present = 1;
3183 
3184 	if (dev->speed == USB_SPEED_HIGH || dev->speed == USB_SPEED_SUPER) {
3185 		int initscreen = 1;
3186 #ifdef INCL_SISUSB_CON
3187 		if (sisusb_first_vc > 0 &&
3188 		    sisusb_last_vc > 0 &&
3189 		    sisusb_first_vc <= sisusb_last_vc &&
3190 		    sisusb_last_vc <= MAX_NR_CONSOLES)
3191 			initscreen = 0;
3192 #endif
3193 		if (sisusb_init_gfxdevice(sisusb, initscreen))
3194 			dev_err(&sisusb->sisusb_dev->dev, "Failed to early initialize device\n");
3195 
3196 	} else
3197 		dev_info(&sisusb->sisusb_dev->dev, "Not attached to USB 2.0 hub, deferring init\n");
3198 
3199 	sisusb->ready = 1;
3200 
3201 #ifdef SISUSBENDIANTEST
3202 	dev_dbg(&sisusb->sisusb_dev->dev, "*** RWTEST ***\n");
3203 	sisusb_testreadwrite(sisusb);
3204 	dev_dbg(&sisusb->sisusb_dev->dev, "*** RWTEST END ***\n");
3205 #endif
3206 
3207 #ifdef INCL_SISUSB_CON
3208 	sisusb_console_init(sisusb, sisusb_first_vc, sisusb_last_vc);
3209 #endif
3210 
3211 	return 0;
3212 
3213 error_4:
3214 	sisusb_free_urbs(sisusb);
3215 error_3:
3216 	sisusb_free_buffers(sisusb);
3217 error_2:
3218 	usb_deregister_dev(intf, &usb_sisusb_class);
3219 error_1:
3220 	kfree(sisusb);
3221 	return retval;
3222 }
3223 
sisusb_disconnect(struct usb_interface * intf)3224 static void sisusb_disconnect(struct usb_interface *intf)
3225 {
3226 	struct sisusb_usb_data *sisusb;
3227 
3228 	/* This should *not* happen */
3229 	sisusb = usb_get_intfdata(intf);
3230 	if (!sisusb)
3231 		return;
3232 
3233 #ifdef INCL_SISUSB_CON
3234 	sisusb_console_exit(sisusb);
3235 #endif
3236 
3237 	usb_deregister_dev(intf, &usb_sisusb_class);
3238 
3239 	mutex_lock(&sisusb->lock);
3240 
3241 	/* Wait for all URBs to complete and kill them in case (MUST do) */
3242 	if (!sisusb_wait_all_out_complete(sisusb))
3243 		sisusb_kill_all_busy(sisusb);
3244 
3245 	usb_set_intfdata(intf, NULL);
3246 
3247 	sisusb->present = 0;
3248 	sisusb->ready = 0;
3249 
3250 	mutex_unlock(&sisusb->lock);
3251 
3252 	/* decrement our usage count */
3253 	kref_put(&sisusb->kref, sisusb_delete);
3254 }
3255 
3256 static const struct usb_device_id sisusb_table[] = {
3257 	{ USB_DEVICE(0x0711, 0x0550) },
3258 	{ USB_DEVICE(0x0711, 0x0900) },
3259 	{ USB_DEVICE(0x0711, 0x0901) },
3260 	{ USB_DEVICE(0x0711, 0x0902) },
3261 	{ USB_DEVICE(0x0711, 0x0903) },
3262 	{ USB_DEVICE(0x0711, 0x0918) },
3263 	{ USB_DEVICE(0x0711, 0x0920) },
3264 	{ USB_DEVICE(0x0711, 0x0950) },
3265 	{ USB_DEVICE(0x0711, 0x5200) },
3266 	{ USB_DEVICE(0x182d, 0x021c) },
3267 	{ USB_DEVICE(0x182d, 0x0269) },
3268 	{ }
3269 };
3270 
3271 MODULE_DEVICE_TABLE (usb, sisusb_table);
3272 
3273 static struct usb_driver sisusb_driver = {
3274 	.name =		"sisusb",
3275 	.probe =	sisusb_probe,
3276 	.disconnect =	sisusb_disconnect,
3277 	.id_table =	sisusb_table,
3278 };
3279 
usb_sisusb_init(void)3280 static int __init usb_sisusb_init(void)
3281 {
3282 
3283 #ifdef INCL_SISUSB_CON
3284 	sisusb_init_concode();
3285 #endif
3286 
3287 	return usb_register(&sisusb_driver);
3288 }
3289 
usb_sisusb_exit(void)3290 static void __exit usb_sisusb_exit(void)
3291 {
3292 	usb_deregister(&sisusb_driver);
3293 }
3294 
3295 module_init(usb_sisusb_init);
3296 module_exit(usb_sisusb_exit);
3297 
3298 MODULE_AUTHOR("Thomas Winischhofer <thomas@winischhofer.net>");
3299 MODULE_DESCRIPTION("sisusbvga - Driver for Net2280/SiS315-based USB2VGA dongles");
3300 MODULE_LICENSE("GPL");
3301 
3302