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