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 (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 27 /* 28 * This driver supports Prolific PL-2303H/HX/X USB-to-serial adapters. It is a 29 * device-specific driver (DSD) working with USB generic serial driver (GSD). It 30 * implements the USB-to-serial device-specific driver interface (DSDI) which is 31 * offered by GSD. The interface is defined by ds_ops_t structure. 32 * 33 * 34 * PL-2303HX and PL-2303X devices have different hardware, but from the 35 * perspective of device driver, they have the same software interface. 36 */ 37 38 /* 39 * 40 * USB Prolific PL2303 driver glue code 41 * 42 */ 43 #include <sys/types.h> 44 #include <sys/param.h> 45 #include <sys/stream.h> 46 #include <sys/conf.h> 47 #include <sys/ddi.h> 48 #include <sys/sunddi.h> 49 50 #include <sys/usb/clients/usbser/usbser.h> 51 #include <sys/usb/clients/usbser/usbsprl/pl2303_var.h> 52 53 54 /* configuration entry points */ 55 static int usbser_pl2303_attach(dev_info_t *, ddi_attach_cmd_t); 56 static int usbser_pl2303_detach(dev_info_t *, ddi_detach_cmd_t); 57 static int usbser_pl2303_getinfo(dev_info_t *, ddi_info_cmd_t, void *, 58 void **); 59 static int usbser_pl2303_open(queue_t *, dev_t *, int, int, cred_t *); 60 static void *usbser_pl2303_statep; /* soft state */ 61 62 extern ds_ops_t pl2303_ds_ops; /* DSD operations */ 63 64 65 /* 66 * STREAMS structures 67 */ 68 struct module_info usbser_pl2303_modinfo = { 69 0, /* module id */ 70 "usbsprl", /* module name */ 71 USBSER_MIN_PKTSZ, /* min pkt size */ 72 USBSER_MAX_PKTSZ, /* max pkt size */ 73 USBSER_HIWAT, /* hi watermark */ 74 USBSER_LOWAT /* low watermark */ 75 }; 76 77 78 static struct qinit usbser_pl2303_rinit = { 79 putq, 80 usbser_rsrv, 81 usbser_pl2303_open, 82 usbser_close, 83 NULL, 84 &usbser_pl2303_modinfo, 85 NULL 86 }; 87 88 89 static struct qinit usbser_pl2303_winit = { 90 usbser_wput, 91 usbser_wsrv, 92 NULL, 93 NULL, 94 NULL, 95 &usbser_pl2303_modinfo, 96 NULL 97 }; 98 99 100 struct streamtab usbser_pl2303_str_info = { 101 &usbser_pl2303_rinit, &usbser_pl2303_winit, NULL, NULL 102 }; 103 104 105 static struct cb_ops usbser_pl2303_cb_ops = { 106 nodev, /* cb_open */ 107 nodev, /* cb_close */ 108 nodev, /* cb_strategy */ 109 nodev, /* cb_print */ 110 nodev, /* cb_dump */ 111 nodev, /* cb_read */ 112 nodev, /* cb_write */ 113 nodev, /* cb_ioctl */ 114 nodev, /* cb_devmap */ 115 nodev, /* cb_mmap */ 116 nodev, /* cb_segmap */ 117 nochpoll, /* cb_chpoll */ 118 ddi_prop_op, /* cb_prop_op */ 119 &usbser_pl2303_str_info, /* cb_stream */ 120 (int)(D_64BIT | D_NEW | D_MP | D_HOTPLUG) /* cb_flag */ 121 }; 122 123 124 /* 125 * auto configuration ops 126 */ 127 struct dev_ops usbser_pl2303_ops = { 128 DEVO_REV, /* devo_rev */ 129 0, /* devo_refcnt */ 130 usbser_pl2303_getinfo, /* devo_getinfo */ 131 nulldev, /* devo_identify */ 132 nulldev, /* devo_probe */ 133 usbser_pl2303_attach, /* devo_attach */ 134 usbser_pl2303_detach, /* devo_detach */ 135 nodev, /* devo_reset */ 136 &usbser_pl2303_cb_ops, /* devo_cb_ops */ 137 (struct bus_ops *)NULL, /* devo_bus_ops */ 138 usbser_power, /* devo_power */ 139 ddi_quiesce_not_needed, /* devo_quiesce */ 140 }; 141 142 143 extern struct mod_ops mod_driverops; 144 145 146 static struct modldrv modldrv = { 147 &mod_driverops, /* type of module - driver */ 148 "USB Prolific PL2303 driver", 149 &usbser_pl2303_ops, 150 }; 151 152 153 static struct modlinkage modlinkage = { 154 MODREV_1, { &modldrv, NULL } 155 }; 156 157 158 /* 159 * entry points 160 * ------------ 161 * 162 */ 163 int 164 _init(void) 165 { 166 int error; 167 168 if ((error = mod_install(&modlinkage)) == 0) { 169 error = ddi_soft_state_init(&usbser_pl2303_statep, 170 usbser_soft_state_size(), 1); 171 } 172 173 return (error); 174 } 175 176 177 int 178 _fini(void) 179 { 180 int error; 181 182 if ((error = mod_remove(&modlinkage)) == 0) { 183 ddi_soft_state_fini(&usbser_pl2303_statep); 184 } 185 186 return (error); 187 } 188 189 190 int 191 _info(struct modinfo *modinfop) 192 { 193 return (mod_info(&modlinkage, modinfop)); 194 } 195 196 197 int 198 usbser_pl2303_getinfo(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, 199 void **result) 200 { 201 return (usbser_getinfo(dip, infocmd, arg, result, 202 usbser_pl2303_statep)); 203 } 204 205 206 static int 207 usbser_pl2303_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) 208 { 209 return (usbser_attach(dip, cmd, usbser_pl2303_statep, &pl2303_ds_ops)); 210 } 211 212 213 static int 214 usbser_pl2303_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) 215 { 216 return (usbser_detach(dip, cmd, usbser_pl2303_statep)); 217 } 218 219 220 static int 221 usbser_pl2303_open(queue_t *rq, dev_t *dev, int flag, int sflag, cred_t *cr) 222 { 223 return (usbser_open(rq, dev, flag, sflag, cr, usbser_pl2303_statep)); 224 }