Deleted Added
full compact
1/*-
2 * Copyright (c) 1999,2000 Michael Smith
3 * Copyright (c) 2000 BSDi
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 *
27 * Copyright (c) 2002 Eric Moore
28 * Copyright (c) 2002 LSI Logic Corporation
29 * All rights reserved.
30 *
31 * Redistribution and use in source and binary forms, with or without
32 * modification, are permitted provided that the following conditions
33 * are met:
34 * 1. Redistributions of source code must retain the above copyright
35 * notice, this list of conditions and the following disclaimer.
36 * 2. Redistributions in binary form must reproduce the above copyright
37 * notice, this list of conditions and the following disclaimer in the
38 * documentation and/or other materials provided with the distribution.
39 * 3. The party using or redistributing the source code and binary forms
40 * agrees to the disclaimer below and the terms and conditions set forth
41 * herein.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
44 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
45 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
46 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
47 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
48 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
49 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
50 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
51 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
52 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
53 * SUCH DAMAGE.
54 *
55 *
56 * $FreeBSD: head/sys/dev/amr/amrvar.h 120988 2003-10-10 22:49:40Z ps $
56 * $FreeBSD: head/sys/dev/amr/amrvar.h 125975 2004-02-18 21:36:53Z phk $
57 */
58
59#if __FreeBSD_version >= 500005
60# include <sys/taskqueue.h>
61# include <geom/geom_disk.h>
62#endif
63
64#ifdef AMR_DEBUG
65# define debug(level, fmt, args...) do {if (level <= AMR_DEBUG) printf("%s: " fmt "\n", __func__ , ##args);} while(0)
66# define debug_called(level) do {if (level <= AMR_DEBUG) printf("%s: called\n", __func__);} while(0)
67#else
68# define debug(level, fmt, args...)
69# define debug_called(level)
70#endif
71#define xdebug(fmt, args...) printf("%s: " fmt "\n", __func__ , ##args)
72
73/*
74 * Per-logical-drive datastructure
75 */
76struct amr_logdrive
77{
78 u_int32_t al_size;
79 int al_state;
80 int al_properties;
81
82 /* synthetic geometry */
83 int al_cylinders;
84 int al_heads;
85 int al_sectors;
86
87 /* driver */
88 device_t al_disk;
89};
90
91/*
92 * Due to the difficulty of using the zone allocator to create a new
93 * zone from within a module, we use our own clustering to reduce
94 * memory wastage due to allocating lots of these small structures.
95 *
96 * 16k gives us a little under 200 command structures, which should
97 * normally be plenty. We will grab more if we need them.
98 */
99
100#define AMR_CMD_CLUSTERSIZE (16 * 1024)
101
102/*
103 * Per-command control structure.
104 */
105struct amr_command
106{
107 TAILQ_ENTRY(amr_command) ac_link;
108
109 struct amr_softc *ac_sc;
110 u_int8_t ac_slot;
111 int ac_status; /* command completion status */
112 struct amr_mailbox ac_mailbox;
113 int ac_flags;
114#define AMR_CMD_DATAIN (1<<0)
115#define AMR_CMD_DATAOUT (1<<1)
116#define AMR_CMD_CCB_DATAIN (1<<2)
117#define AMR_CMD_CCB_DATAOUT (1<<3)
118#define AMR_CMD_PRIORITY (1<<4)
119#define AMR_CMD_MAPPED (1<<5)
120#define AMR_CMD_SLEEP (1<<6)
121#define AMR_CMD_BUSY (1<<7)
122
123 struct bio *ac_bio;
124
125 void *ac_data;
126 size_t ac_length;
127 bus_dmamap_t ac_dmamap;
128 u_int32_t ac_dataphys;
129
130 void *ac_ccb_data;
131 size_t ac_ccb_length;
132 bus_dmamap_t ac_ccb_dmamap;
133 u_int32_t ac_ccb_dataphys;
134
135 void (* ac_complete)(struct amr_command *ac);
136 void *ac_private;
137};
138
139struct amr_command_cluster
140{
141 TAILQ_ENTRY(amr_command_cluster) acc_link;
142 struct amr_command acc_command[0];
143};
144
145#define AMR_CMD_CLUSTERCOUNT ((AMR_CMD_CLUSTERSIZE - sizeof(struct amr_command_cluster)) / \
146 sizeof(struct amr_command))
147
148/*
149 * Per-controller-instance data
150 */
151struct amr_softc
152{
153 /* bus attachments */
154 device_t amr_dev;
155 struct resource *amr_reg; /* control registers */
156 bus_space_handle_t amr_bhandle;
157 bus_space_tag_t amr_btag;
158 bus_dma_tag_t amr_parent_dmat; /* parent DMA tag */
159 bus_dma_tag_t amr_buffer_dmat; /* data buffer DMA tag */
160 struct resource *amr_irq; /* interrupt */
161 void *amr_intr;
162
163 /* mailbox */
164 volatile struct amr_mailbox *amr_mailbox;
165 volatile struct amr_mailbox64 *amr_mailbox64;
166 u_int32_t amr_mailboxphys;
167 bus_dma_tag_t amr_mailbox_dmat;
168 bus_dmamap_t amr_mailbox_dmamap;
169
170 /* scatter/gather lists and their controller-visible mappings */
171 struct amr_sgentry *amr_sgtable; /* s/g lists */
172 u_int32_t amr_sgbusaddr; /* s/g table base address in bus space */
173 bus_dma_tag_t amr_sg_dmat; /* s/g buffer DMA tag */
174 bus_dmamap_t amr_sg_dmamap; /* map for s/g buffers */
175
176 /* controller limits and features */
177 int amr_maxio; /* maximum number of I/O transactions */
178 int amr_maxdrives; /* max number of logical drives */
179 int amr_maxchan; /* count of SCSI channels */
180
181 /* connected logical drives */
182 struct amr_logdrive amr_drive[AMR_MAXLD];
183
184 /* controller state */
185 int amr_state;
186#define AMR_STATE_OPEN (1<<0)
187#define AMR_STATE_SUSPEND (1<<1)
188#define AMR_STATE_INTEN (1<<2)
189#define AMR_STATE_SHUTDOWN (1<<3)
190
191 /* per-controller queues */
192 struct bio_queue_head amr_bioq; /* pending I/O with no commands */
193 TAILQ_HEAD(,amr_command) amr_ready; /* commands ready to be submitted */
194 struct amr_command *amr_busycmd[AMR_MAXCMD];
195 int amr_busyslots;
196 TAILQ_HEAD(,amr_command) amr_completed;
197 TAILQ_HEAD(,amr_command) amr_freecmds;
198 TAILQ_HEAD(,amr_command_cluster) amr_cmd_clusters;
199
200 /* CAM attachments for passthrough */
201 struct cam_sim *amr_cam_sim[AMR_MAX_CHANNELS];
202 TAILQ_HEAD(, ccb_hdr) amr_cam_ccbq;
203
204 /* control device */
205 dev_t amr_dev_t;
206
207 /* controller type-specific support */
208 int amr_type;
209#define AMR_TYPE_QUARTZ (1<<0)
210#define AMR_IS_QUARTZ(sc) ((sc)->amr_type & AMR_TYPE_QUARTZ)
211#define AMR_TYPE_40LD (1<<1)
212#define AMR_IS_40LD(sc) ((sc)->amr_type & AMR_TYPE_40LD)
213 int (* amr_submit_command)(struct amr_softc *sc);
214 int (* amr_get_work)(struct amr_softc *sc, struct amr_mailbox *mbsave);
215 int (*amr_poll_command)(struct amr_command *ac);
216 int support_ext_cdb; /* greater than 10 byte cdb support */
217
218 /* misc glue */
219 struct intr_config_hook amr_ich; /* wait-for-interrupts probe hook */
220 struct callout_handle amr_timeout; /* periodic status check */
221#if __FreeBSD_version >= 500005
222 struct task amr_task_complete; /* deferred-completion task */
223#endif
224};
225
226/*
227 * Interface between bus connections and driver core.
228 */
229extern int amr_attach(struct amr_softc *sc);
230extern void amr_free(struct amr_softc *sc);
231extern int amr_flush(struct amr_softc *sc);
232extern int amr_done(struct amr_softc *sc);
233extern void amr_startio(struct amr_softc *sc);
234
235/*
236 * Command buffer allocation.
237 */
238extern struct amr_command *amr_alloccmd(struct amr_softc *sc);
239extern void amr_releasecmd(struct amr_command *ac);
240
241/*
242 * CAM interface
243 */
244extern int amr_cam_attach(struct amr_softc *sc);
245extern void amr_cam_detach(struct amr_softc *sc);
246extern int amr_cam_command(struct amr_softc *sc, struct amr_command **acp);
247
248/*
249 * MegaRAID logical disk driver
250 */
251struct amrd_softc
252{
253 device_t amrd_dev;
254 struct amr_softc *amrd_controller;
255 struct amr_logdrive *amrd_drive;
256 struct disk amrd_disk;
256 struct disk *amrd_disk;
257 int amrd_unit;
258};
259
260/*
261 * Interface between driver core and disk driver (should be using a bus?)
262 */
263extern int amr_submit_bio(struct amr_softc *sc, struct bio *bio);
264extern int amr_dump_blocks(struct amr_softc *sc, int unit, u_int32_t lba, void *data, int blks);
265extern void amrd_intr(void *data);
266
267/********************************************************************************
268 * Enqueue/dequeue functions
269 */
270static __inline void
271amr_enqueue_bio(struct amr_softc *sc, struct bio *bio)
272{
273 int s;
274
275 s = splbio();
276 bioq_insert_tail(&sc->amr_bioq, bio);
277 splx(s);
278}
279
280static __inline struct bio *
281amr_dequeue_bio(struct amr_softc *sc)
282{
283 struct bio *bio;
284 int s;
285
286 s = splbio();
287 if ((bio = bioq_first(&sc->amr_bioq)) != NULL)
288 bioq_remove(&sc->amr_bioq, bio);
289 splx(s);
290 return(bio);
291}
292
293static __inline void
294amr_enqueue_ready(struct amr_command *ac)
295{
296 int s;
297
298 s = splbio();
299 TAILQ_INSERT_TAIL(&ac->ac_sc->amr_ready, ac, ac_link);
300 splx(s);
301}
302
303static __inline void
304amr_requeue_ready(struct amr_command *ac)
305{
306 int s;
307
308 s = splbio();
309 TAILQ_INSERT_HEAD(&ac->ac_sc->amr_ready, ac, ac_link);
310 splx(s);
311}
312
313static __inline struct amr_command *
314amr_dequeue_ready(struct amr_softc *sc)
315{
316 struct amr_command *ac;
317 int s;
318
319 s = splbio();
320 if ((ac = TAILQ_FIRST(&sc->amr_ready)) != NULL)
321 TAILQ_REMOVE(&sc->amr_ready, ac, ac_link);
322 splx(s);
323 return(ac);
324}
325
326static __inline void
327amr_enqueue_completed(struct amr_command *ac)
328{
329 int s;
330
331 s = splbio();
332 TAILQ_INSERT_TAIL(&ac->ac_sc->amr_completed, ac, ac_link);
333 splx(s);
334}
335
336static __inline struct amr_command *
337amr_dequeue_completed(struct amr_softc *sc)
338{
339 struct amr_command *ac;
340 int s;
341
342 s = splbio();
343 if ((ac = TAILQ_FIRST(&sc->amr_completed)) != NULL)
344 TAILQ_REMOVE(&sc->amr_completed, ac, ac_link);
345 splx(s);
346 return(ac);
347}
348
349static __inline void
350amr_enqueue_free(struct amr_command *ac)
351{
352 int s;
353
354 s = splbio();
355 TAILQ_INSERT_TAIL(&ac->ac_sc->amr_freecmds, ac, ac_link);
356 splx(s);
357}
358
359static __inline struct amr_command *
360amr_dequeue_free(struct amr_softc *sc)
361{
362 struct amr_command *ac;
363 int s;
364
365 s = splbio();
366 if ((ac = TAILQ_FIRST(&sc->amr_freecmds)) != NULL)
367 TAILQ_REMOVE(&sc->amr_freecmds, ac, ac_link);
368 splx(s);
369 return(ac);
370}