Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
aha152x_stub.c
Go to the documentation of this file.
1 /*======================================================================
2 
3  A driver for Adaptec AHA152X-compatible PCMCIA SCSI cards.
4 
5  This driver supports the Adaptec AHA-1460, the New Media Bus
6  Toaster, and the New Media Toast & Jam.
7 
8  aha152x_cs.c 1.54 2000/06/12 21:27:25
9 
10  The contents of this file are subject to the Mozilla Public
11  License Version 1.1 (the "License"); you may not use this file
12  except in compliance with the License. You may obtain a copy of
13  the License at http://www.mozilla.org/MPL/
14 
15  Software distributed under the License is distributed on an "AS
16  IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
17  implied. See the License for the specific language governing
18  rights and limitations under the License.
19 
20  The initial developer of the original code is David A. Hinds
21  <[email protected]>. Portions created by David A. Hinds
22  are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
23 
24  Alternatively, the contents of this file may be used under the
25  terms of the GNU General Public License version 2 (the "GPL"), in which
26  case the provisions of the GPL are applicable instead of the
27  above. If you wish to allow the use of your version of this file
28  only under the terms of the GPL and not to allow others to use
29  your version of this file under the MPL, indicate your decision
30  by deleting the provisions above and replace them with the notice
31  and other provisions required by the GPL. If you do not delete
32  the provisions above, a recipient may use your version of this
33  file under either the MPL or the GPL.
34 
35 ======================================================================*/
36 
37 #include <linux/module.h>
38 #include <linux/init.h>
39 #include <linux/kernel.h>
40 #include <linux/slab.h>
41 #include <linux/string.h>
42 #include <linux/ioport.h>
43 #include <scsi/scsi.h>
44 #include <linux/major.h>
45 #include <linux/blkdev.h>
46 #include <scsi/scsi_ioctl.h>
47 
48 #include "scsi.h"
49 #include <scsi/scsi_host.h>
50 #include "aha152x.h"
51 
52 #include <pcmcia/cistpl.h>
53 #include <pcmcia/ds.h>
54 
55 
56 /*====================================================================*/
57 
58 /* Parameters that can be set with 'insmod' */
59 
60 /* SCSI bus setup options */
61 static int host_id = 7;
62 static int reconnect = 1;
63 static int parity = 1;
64 static int synchronous = 1;
65 static int reset_delay = 100;
66 static int ext_trans = 0;
67 
68 module_param(host_id, int, 0);
69 module_param(reconnect, int, 0);
70 module_param(parity, int, 0);
71 module_param(synchronous, int, 0);
72 module_param(reset_delay, int, 0);
73 module_param(ext_trans, int, 0);
74 
75 MODULE_LICENSE("Dual MPL/GPL");
76 
77 /*====================================================================*/
78 
79 typedef struct scsi_info_t {
80  struct pcmcia_device *p_dev;
81  struct Scsi_Host *host;
82 } scsi_info_t;
83 
84 static void aha152x_release_cs(struct pcmcia_device *link);
85 static void aha152x_detach(struct pcmcia_device *p_dev);
86 static int aha152x_config_cs(struct pcmcia_device *link);
87 
88 static int aha152x_probe(struct pcmcia_device *link)
89 {
91 
92  dev_dbg(&link->dev, "aha152x_attach()\n");
93 
94  /* Create new SCSI device */
95  info = kzalloc(sizeof(*info), GFP_KERNEL);
96  if (!info) return -ENOMEM;
97  info->p_dev = link;
98  link->priv = info;
99 
100  link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
101  link->config_regs = PRESENT_OPTION;
102 
103  return aha152x_config_cs(link);
104 } /* aha152x_attach */
105 
106 /*====================================================================*/
107 
108 static void aha152x_detach(struct pcmcia_device *link)
109 {
110  dev_dbg(&link->dev, "aha152x_detach\n");
111 
112  aha152x_release_cs(link);
113 
114  /* Unlink device structure, free bits */
115  kfree(link->priv);
116 } /* aha152x_detach */
117 
118 /*====================================================================*/
119 
120 static int aha152x_config_check(struct pcmcia_device *p_dev, void *priv_data)
121 {
122  p_dev->io_lines = 10;
123 
124  /* For New Media T&J, look for a SCSI window */
125  if ((p_dev->resource[0]->end < 0x20) &&
126  (p_dev->resource[1]->end >= 0x20))
127  p_dev->resource[0]->start = p_dev->resource[1]->start;
128 
129  if (p_dev->resource[0]->start >= 0xffff)
130  return -EINVAL;
131 
132  p_dev->resource[1]->start = p_dev->resource[1]->end = 0;
133  p_dev->resource[0]->end = 0x20;
134  p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
135  p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
136 
137  return pcmcia_request_io(p_dev);
138 }
139 
140 static int aha152x_config_cs(struct pcmcia_device *link)
141 {
142  scsi_info_t *info = link->priv;
143  struct aha152x_setup s;
144  int ret;
145  struct Scsi_Host *host;
146 
147  dev_dbg(&link->dev, "aha152x_config\n");
148 
149  ret = pcmcia_loop_config(link, aha152x_config_check, NULL);
150  if (ret)
151  goto failed;
152 
153  if (!link->irq)
154  goto failed;
155 
156  ret = pcmcia_enable_device(link);
157  if (ret)
158  goto failed;
159 
160  /* Set configuration options for the aha152x driver */
161  memset(&s, 0, sizeof(s));
162  s.conf = "PCMCIA setup";
163  s.io_port = link->resource[0]->start;
164  s.irq = link->irq;
165  s.scsiid = host_id;
166  s.reconnect = reconnect;
167  s.parity = parity;
168  s.synchronous = synchronous;
169  s.delay = reset_delay;
170  if (ext_trans)
171  s.ext_trans = ext_trans;
172 
173  host = aha152x_probe_one(&s);
174  if (host == NULL) {
175  printk(KERN_INFO "aha152x_cs: no SCSI devices found\n");
176  goto failed;
177  }
178 
179  info->host = host;
180 
181  return 0;
182 
183 failed:
184  aha152x_release_cs(link);
185  return -ENODEV;
186 }
187 
188 static void aha152x_release_cs(struct pcmcia_device *link)
189 {
190  scsi_info_t *info = link->priv;
191 
192  aha152x_release(info->host);
193  pcmcia_disable_device(link);
194 }
195 
196 static int aha152x_resume(struct pcmcia_device *link)
197 {
198  scsi_info_t *info = link->priv;
199 
201 
202  return 0;
203 }
204 
205 static const struct pcmcia_device_id aha152x_ids[] = {
206  PCMCIA_DEVICE_PROD_ID123("New Media", "SCSI", "Bus Toaster", 0xcdf7e4cc, 0x35f26476, 0xa8851d6e),
207  PCMCIA_DEVICE_PROD_ID123("NOTEWORTHY", "SCSI", "Bus Toaster", 0xad89c6e8, 0x35f26476, 0xa8851d6e),
208  PCMCIA_DEVICE_PROD_ID12("Adaptec, Inc.", "APA-1460 SCSI Host Adapter", 0x24ba9738, 0x3a3c3d20),
209  PCMCIA_DEVICE_PROD_ID12("New Media Corporation", "Multimedia Sound/SCSI", 0x085a850b, 0x80a6535c),
210  PCMCIA_DEVICE_PROD_ID12("NOTEWORTHY", "NWCOMB02 SCSI/AUDIO COMBO CARD", 0xad89c6e8, 0x5f9a615b),
211  PCMCIA_DEVICE_NULL,
212 };
213 MODULE_DEVICE_TABLE(pcmcia, aha152x_ids);
214 
215 static struct pcmcia_driver aha152x_cs_driver = {
216  .owner = THIS_MODULE,
217  .name = "aha152x_cs",
218  .probe = aha152x_probe,
219  .remove = aha152x_detach,
220  .id_table = aha152x_ids,
221  .resume = aha152x_resume,
222 };
223 
224 static int __init init_aha152x_cs(void)
225 {
226  return pcmcia_register_driver(&aha152x_cs_driver);
227 }
228 
229 static void __exit exit_aha152x_cs(void)
230 {
231  pcmcia_unregister_driver(&aha152x_cs_driver);
232 }
233 
234 module_init(init_aha152x_cs);
235 module_exit(exit_aha152x_cs);