1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2003 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 /* 29 * USBA: Solaris USB Architecture support 30 * 31 * ISSUES: 32 */ 33 #define USBA_FRAMEWORK 34 #include <sys/usb/usba.h> 35 #include <sys/usb/usba/hcdi.h> 36 #include <sys/usb/usba/genconsole.h> 37 #include <sys/usb/usba/usba_types.h> 38 #include <sys/usb/usba/usba_impl.h> 39 40 /* 41 * Initialize USB OBP support. This routine calls down to the lower 42 * layers to initialize any state information. 43 */ 44 int 45 usb_console_input_init(dev_info_t *dip, 46 usb_pipe_handle_t pipe_handle, 47 uchar_t **obp_buf, 48 usb_console_info_t *console_input_info) 49 { 50 int ret; 51 usba_device_t *usba_device; 52 usb_console_info_impl_t *usb_console_input = kmem_zalloc( 53 sizeof (struct usb_console_info_impl), KM_SLEEP); 54 55 /* 56 * Save the dip 57 */ 58 usb_console_input->uci_dip = dip; 59 60 /* 61 * Translate the dip into a device. 62 */ 63 usba_device = usba_get_usba_device(dip); 64 65 /* 66 * Call the lower layer to initialize any state information 67 */ 68 ret = usba_device->usb_hcdi_ops->usba_hcdi_console_input_init( 69 usba_get_ph_data(pipe_handle), obp_buf, usb_console_input); 70 71 if (ret != USB_SUCCESS) { 72 kmem_free(usb_console_input, 73 sizeof (struct usb_console_info_impl)); 74 } else { 75 *console_input_info = (usb_console_info_t)usb_console_input; 76 } 77 78 return (ret); 79 } 80 81 82 /* 83 * Free up any resources that we allocated in the above initialization 84 * routine. 85 */ 86 int 87 usb_console_input_fini(usb_console_info_t console_input_info) 88 { 89 usb_console_info_impl_t *usb_console_input; 90 usba_device_t *usba_device; 91 int ret; 92 93 usb_console_input = (usb_console_info_impl_t *)console_input_info; 94 95 /* 96 * Translate the dip into a device. 97 */ 98 usba_device = usba_get_usba_device(usb_console_input->uci_dip); 99 100 /* 101 * Call the lower layer to free any state information. 102 */ 103 ret = usba_device->usb_hcdi_ops->usba_hcdi_console_input_fini( 104 usb_console_input); 105 106 if (ret == USB_FAILURE) { 107 108 return (ret); 109 } 110 111 /* 112 * We won't be needing this information anymore. 113 */ 114 kmem_free(usb_console_input, sizeof (struct usb_console_info_impl)); 115 116 return (USB_SUCCESS); 117 } 118 119 120 /* 121 * This is the routine that OBP calls to save the USB state information 122 * before using the USB keyboard as an input device. This routine, 123 * and all of the routines that it calls, are responsible for saving 124 * any state information so that it can be restored when OBP mode is 125 * over. At this layer, this code is mainly just a pass through. 126 * 127 * Warning: this code runs in polled mode. 128 */ 129 int 130 usb_console_input_enter(usb_console_info_t console_input_info) 131 { 132 usba_device_t *usba_device; 133 usb_console_info_impl_t *usb_console_input; 134 135 usb_console_input = (usb_console_info_impl_t *)console_input_info; 136 137 /* 138 * Translate the dip into a device. 139 * Do this by directly looking at the dip, do not call 140 * usba_get_usba_device() because this function calls into the DDI. 141 * The ddi then tries to acquire a mutex and the machine hard hangs. 142 */ 143 usba_device = usba_polled_get_usba_device(usb_console_input->uci_dip); 144 145 /* 146 * Call the lower layer to save state information. 147 */ 148 usba_device->usb_hcdi_ops->usba_hcdi_console_input_enter( 149 usb_console_input); 150 151 return (USB_SUCCESS); 152 } 153 154 155 /* 156 * This is the routine that OBP calls when it wants to read a character. 157 * We will call to the lower layers to see if there is any input data 158 * available. At this layer, this code is mainly just a pass through. 159 * 160 * Warning: This code runs in polled mode. 161 */ 162 int 163 usb_console_read(usb_console_info_t console_input_info, uint_t *num_characters) 164 { 165 usba_device_t *usba_device; 166 usb_console_info_impl_t *usb_console_input; 167 168 usb_console_input = (usb_console_info_impl_t *)console_input_info; 169 170 /* 171 * Translate the dip into a device. 172 * Do this by directly looking at the dip, do not call 173 * usba_get_usba_device() because this function calls into the DDI. 174 * The ddi then tries to acquire a mutex and the machine hard hangs. 175 */ 176 usba_device = usba_polled_get_usba_device(usb_console_input->uci_dip); 177 178 /* 179 * Call the lower layer to get a a character. Return the number 180 * of characters read into the buffer. 181 */ 182 return (usba_device->usb_hcdi_ops->usba_hcdi_console_read( 183 usb_console_input, num_characters)); 184 } 185 186 187 /* 188 * This is the routine that OBP calls when it is giving up control of the 189 * USB keyboard. This routine, and the lower layer routines that it calls, 190 * are responsible for restoring the controller state to the state it was 191 * in before OBP took control. At this layer, this code is mainly just a 192 * pass through. 193 * 194 * Warning: This code runs in polled mode. 195 */ 196 int 197 usb_console_input_exit(usb_console_info_t console_input_info) 198 { 199 usba_device_t *usba_device; 200 usb_console_info_impl_t *usb_console_input; 201 202 usb_console_input = (usb_console_info_impl_t *)console_input_info; 203 204 /* 205 * Translate the dip into a device. 206 * Do this by directly looking at the dip, do not call 207 * usba_get_usba_device() because this function calls into the DDI. 208 * The ddi then tries to acquire a mutex and the machine hard hangs. 209 */ 210 usba_device = usba_polled_get_usba_device(usb_console_input->uci_dip); 211 212 /* 213 * Restore the state information. 214 */ 215 usba_device->usb_hcdi_ops->usba_hcdi_console_input_exit( 216 usb_console_input); 217 218 return (USB_SUCCESS); 219 } 220