2 * SPDX-License-Identifier: BSD-3-Clause
4 * Copyright (c) 2001,2002,2003 Søren Schmidt <sos@FreeBSD.org>
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer,
12 * without modification, immediately at the beginning of the file.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. The name of the author may not be used to endorse or promote products
17 * derived from this software without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 #include <sys/cdefs.h>
32 __FBSDID("$FreeBSD$");
34 #include <sys/param.h>
35 #include <sys/systm.h>
36 #include <sys/kernel.h>
37 #include <sys/module.h>
40 #include <sys/malloc.h>
42 #include <sys/mutex.h>
45 #include <machine/stdarg.h>
46 #include <machine/resource.h>
47 #include <machine/bus.h>
49 #include <dev/pci/pcivar.h>
50 #include <dev/pci/pcireg.h>
52 #include "dev/pst/pst-iop.h"
55 struct i2o_single_reply *reply;
60 MALLOC_DEFINE(M_PSTIOP, "PSTIOP", "Promise SuperTrak IOP driver");
63 iop_init(struct iop_softc *sc)
65 int mfa, timeout = 10000;
67 while ((mfa = sc->reg->iqueue) == 0xffffffff && --timeout)
70 printf("pstiop: no free mfa\n");
73 iop_free_mfa(sc, mfa);
75 sc->reg->oqueue_intr_mask = 0xffffffff;
78 printf("pstiop: no reset response\n");
82 if (!iop_init_outqueue(sc)) {
83 printf("pstiop: init outbound queue failed\n");
87 /* register iop_attach to be run when interrupts are enabled */
88 if (!(sc->iop_delayed_attach = (struct intr_config_hook *)
89 malloc(sizeof(struct intr_config_hook),
90 M_PSTIOP, M_NOWAIT | M_ZERO))) {
91 printf("pstiop: malloc of delayed attach hook failed\n");
94 sc->iop_delayed_attach->ich_func = iop_attach;
95 sc->iop_delayed_attach->ich_arg = sc;
96 if (config_intrhook_establish(sc->iop_delayed_attach)) {
97 printf("pstiop: config_intrhook_establish failed\n");
98 free(sc->iop_delayed_attach, M_PSTIOP);
104 iop_attach(void *arg)
106 struct iop_softc *sc;
110 if (sc->iop_delayed_attach) {
111 config_intrhook_disestablish(sc->iop_delayed_attach);
112 free(sc->iop_delayed_attach, M_PSTIOP);
113 sc->iop_delayed_attach = NULL;
116 if (!iop_get_lct(sc)) {
117 printf("pstiop: get LCT failed\n");
121 /* figure out what devices are here and config as needed */
122 for (i = 0; sc->lct[i].entry_size == I2O_LCT_ENTRYSIZE; i++) {
124 struct i2o_get_param_reply *reply;
126 printf("pstiop: LCT entry %d ", i);
127 printf("class=%04x ", sc->lct[i].class);
128 printf("sub=%04x ", sc->lct[i].sub_class);
129 printf("localtid=%04x ", sc->lct[i].local_tid);
130 printf("usertid=%04x ", sc->lct[i].user_tid);
131 printf("parentid=%04x\n", sc->lct[i].parent_tid);
133 if ((reply = iop_get_util_params(sc, sc->lct[i].local_tid,
134 I2O_PARAMS_OPERATION_FIELD_GET,
135 I2O_UTIL_DEVICE_IDENTITY_GROUP_NO))) {
136 struct i2o_device_identity *ident =
137 (struct i2o_device_identity *)reply->result;
138 printf("pstiop: vendor=<%.16s> product=<%.16s>\n",
139 ident->vendor, ident->product);
140 printf("pstiop: description=<%.16s> revision=<%.8s>\n",
141 ident->description, ident->revision);
142 contigfree(reply, PAGE_SIZE, M_PSTIOP);
146 if (sc->lct[i].user_tid != I2O_TID_NONE &&
147 sc->lct[i].user_tid != I2O_TID_HOST)
150 switch (sc->lct[i].class) {
152 if (sc->lct[i].sub_class == I2O_SUBCLASS_ISM)
153 sc->ism = sc->lct[i].local_tid;
156 case I2O_CLASS_RANDOM_BLOCK_STORAGE:
157 pst_add_raid(sc, &sc->lct[i]);
162 /* setup and enable interrupts */
163 bus_setup_intr(sc->dev, sc->r_irq, INTR_TYPE_BIO|INTR_ENTROPY|INTR_MPSAFE,
164 NULL, iop_intr, sc, &sc->handle);
165 sc->reg->oqueue_intr_mask = 0x0;
171 struct iop_softc *sc = (struct iop_softc *)data;
172 struct i2o_single_reply *reply;
175 /* we might get more than one finished request pr interrupt */
178 if ((mfa = sc->reg->oqueue) == 0xffffffff)
179 if ((mfa = sc->reg->oqueue) == 0xffffffff)
182 reply = (struct i2o_single_reply *)(sc->obase + (mfa - sc->phys_obase));
184 /* if this is an event register reply, shout! */
185 if (reply->function == I2O_UTIL_EVENT_REGISTER) {
186 struct i2o_util_event_reply_message *event =
187 (struct i2o_util_event_reply_message *)reply;
189 printf("pstiop: EVENT!! idx=%08x data=%08x\n",
190 event->event_mask, event->event_data[0]);
194 /* if reply is a failurenotice we need to free the original mfa */
195 if (reply->message_flags & I2O_MESSAGE_FLAGS_FAIL)
196 iop_free_mfa(sc,((struct i2o_fault_reply *)(reply))->preserved_mfa);
198 /* reply->initiator_context points to the service routine */
199 ((void (*)(struct iop_softc *, u_int32_t, struct i2o_single_reply *))
200 (reply->initiator_context))(sc, mfa, reply);
202 mtx_unlock(&sc->mtx);
206 iop_reset(struct iop_softc *sc)
208 struct i2o_exec_iop_reset_message *msg;
209 int mfa, timeout = 5000;
210 volatile u_int32_t reply = 0;
212 mfa = iop_get_mfa(sc);
213 msg = (struct i2o_exec_iop_reset_message *)(sc->ibase + mfa);
214 bzero(msg, sizeof(struct i2o_exec_iop_reset_message));
215 msg->version_offset = 0x1;
216 msg->message_flags = 0x0;
217 msg->message_size = sizeof(struct i2o_exec_iop_reset_message) >> 2;
218 msg->target_address = I2O_TID_IOP;
219 msg->initiator_address = I2O_TID_HOST;
220 msg->function = I2O_EXEC_IOP_RESET;
221 msg->status_word_low_addr = vtophys(&reply);
222 msg->status_word_high_addr = 0;
224 sc->reg->iqueue = mfa;
226 while (--timeout && !reply)
229 /* wait for iqueue ready */
231 while ((mfa = sc->reg->iqueue) == 0xffffffff && --timeout)
234 iop_free_mfa(sc, mfa);
239 iop_init_outqueue(struct iop_softc *sc)
241 struct i2o_exec_init_outqueue_message *msg;
242 int i, mfa, timeout = 5000;
243 volatile u_int32_t reply = 0;
245 if (!(sc->obase = contigmalloc(I2O_IOP_OUTBOUND_FRAME_COUNT *
246 I2O_IOP_OUTBOUND_FRAME_SIZE,
248 0x00010000, 0xFFFFFFFF,
250 printf("pstiop: contigmalloc of outqueue buffers failed!\n");
253 sc->phys_obase = vtophys(sc->obase);
254 mfa = iop_get_mfa(sc);
255 msg = (struct i2o_exec_init_outqueue_message *)(sc->ibase + mfa);
256 bzero(msg, sizeof(struct i2o_exec_init_outqueue_message));
257 msg->version_offset = 0x61;
258 msg->message_flags = 0x0;
259 msg->message_size = sizeof(struct i2o_exec_init_outqueue_message) >> 2;
260 msg->target_address = I2O_TID_IOP;
261 msg->initiator_address = I2O_TID_HOST;
262 msg->function = I2O_EXEC_OUTBOUND_INIT;
263 msg->host_pagesize = PAGE_SIZE;
264 msg->init_code = 0x00; /* SOS XXX should be 0x80 == OS */
265 msg->queue_framesize = I2O_IOP_OUTBOUND_FRAME_SIZE / sizeof(u_int32_t);
266 msg->sgl[0].flags = I2O_SGL_SIMPLE | I2O_SGL_END | I2O_SGL_EOB;
267 msg->sgl[0].count = sizeof(reply);
268 msg->sgl[0].phys_addr[0] = vtophys(&reply);
269 msg->sgl[1].flags = I2O_SGL_END | I2O_SGL_EOB;
270 msg->sgl[1].count = 1;
271 msg->sgl[1].phys_addr[0] = 0;
273 sc->reg->iqueue = mfa;
275 /* wait for init to complete */
276 while (--timeout && reply != I2O_EXEC_OUTBOUND_INIT_COMPLETE)
280 printf("pstiop: timeout waiting for init-complete response\n");
281 iop_free_mfa(sc, mfa);
285 /* now init our oqueue bufs */
286 for (i = 0; i < I2O_IOP_OUTBOUND_FRAME_COUNT; i++) {
287 sc->reg->oqueue = sc->phys_obase + (i * I2O_IOP_OUTBOUND_FRAME_SIZE);
295 iop_get_lct(struct iop_softc *sc)
297 struct i2o_exec_get_lct_message *msg;
298 struct i2o_get_lct_reply *reply;
300 #define ALLOCSIZE (PAGE_SIZE + (256 * sizeof(struct i2o_lct_entry)))
302 if (!(reply = contigmalloc(ALLOCSIZE, M_PSTIOP, M_NOWAIT | M_ZERO,
303 0x00010000, 0xFFFFFFFF, PAGE_SIZE, 0)))
306 mfa = iop_get_mfa(sc);
307 msg = (struct i2o_exec_get_lct_message *)(sc->ibase + mfa);
308 bzero(msg, sizeof(struct i2o_exec_get_lct_message));
309 msg->version_offset = 0x61;
310 msg->message_flags = 0x0;
311 msg->message_size = sizeof(struct i2o_exec_get_lct_message) >> 2;
312 msg->target_address = I2O_TID_IOP;
313 msg->initiator_address = I2O_TID_HOST;
314 msg->function = I2O_EXEC_LCT_NOTIFY;
315 msg->class = I2O_CLASS_MATCH_ANYCLASS;
316 msg->last_change_id = 0;
318 msg->sgl.flags = I2O_SGL_SIMPLE | I2O_SGL_END | I2O_SGL_EOB;
319 msg->sgl.count = ALLOCSIZE;
320 msg->sgl.phys_addr[0] = vtophys(reply);
322 if (iop_queue_wait_msg(sc, mfa, (struct i2o_basic_message *)msg)) {
323 contigfree(reply, ALLOCSIZE, M_PSTIOP);
326 if (!(sc->lct = malloc(reply->table_size * sizeof(struct i2o_lct_entry),
327 M_PSTIOP, M_NOWAIT | M_ZERO))) {
328 contigfree(reply, ALLOCSIZE, M_PSTIOP);
331 bcopy(&reply->entry[0], sc->lct,
332 reply->table_size * sizeof(struct i2o_lct_entry));
333 sc->lct_count = reply->table_size;
334 contigfree(reply, ALLOCSIZE, M_PSTIOP);
338 struct i2o_get_param_reply *
339 iop_get_util_params(struct iop_softc *sc, int target, int operation, int group)
341 struct i2o_util_get_param_message *msg;
342 struct i2o_get_param_operation *param;
343 struct i2o_get_param_reply *reply;
346 if (!(param = contigmalloc(PAGE_SIZE, M_PSTIOP, M_NOWAIT | M_ZERO,
347 0x00010000, 0xFFFFFFFF, PAGE_SIZE, 0)))
350 if (!(reply = contigmalloc(PAGE_SIZE, M_PSTIOP, M_NOWAIT | M_ZERO,
351 0x00010000, 0xFFFFFFFF, PAGE_SIZE, 0)))
354 mfa = iop_get_mfa(sc);
355 msg = (struct i2o_util_get_param_message *)(sc->ibase + mfa);
356 bzero(msg, sizeof(struct i2o_util_get_param_message));
357 msg->version_offset = 0x51;
358 msg->message_flags = 0x0;
359 msg->message_size = sizeof(struct i2o_util_get_param_message) >> 2;
360 msg->target_address = target;
361 msg->initiator_address = I2O_TID_HOST;
362 msg->function = I2O_UTIL_PARAMS_GET;
363 msg->operation_flags = 0;
365 param->operation_count = 1;
366 param->operation[0].operation = operation;
367 param->operation[0].group = group;
368 param->operation[0].field_count = 0xffff;
370 msg->sgl[0].flags = I2O_SGL_SIMPLE | I2O_SGL_DIR | I2O_SGL_EOB;
371 msg->sgl[0].count = sizeof(struct i2o_get_param_operation);
372 msg->sgl[0].phys_addr[0] = vtophys(param);
374 msg->sgl[1].flags = I2O_SGL_SIMPLE | I2O_SGL_END | I2O_SGL_EOB;
375 msg->sgl[1].count = PAGE_SIZE;
376 msg->sgl[1].phys_addr[0] = vtophys(reply);
378 if (iop_queue_wait_msg(sc, mfa, (struct i2o_basic_message *)msg) ||
379 reply->error_info_size) {
380 contigfree(reply, PAGE_SIZE, M_PSTIOP);
383 contigfree(param, PAGE_SIZE, M_PSTIOP);
388 iop_get_mfa(struct iop_softc *sc)
393 while ((mfa = sc->reg->iqueue) == 0xffffffff && timeout) {
398 printf("pstiop: no free mfa\n");
403 iop_free_mfa(struct iop_softc *sc, int mfa)
405 struct i2o_basic_message *msg = (struct i2o_basic_message *)(sc->ibase+mfa);
407 bzero(msg, sizeof(struct i2o_basic_message));
409 msg->message_flags = 0x0;
410 msg->message_size = sizeof(struct i2o_basic_message) >> 2;
411 msg->target_address = I2O_TID_IOP;
412 msg->initiator_address = I2O_TID_HOST;
413 msg->function = I2O_UTIL_NOP;
414 sc->reg->iqueue = mfa;
418 iop_done(struct iop_softc *sc, u_int32_t mfa, struct i2o_single_reply *reply)
420 struct iop_request *request =
421 (struct iop_request *)reply->transaction_context;
423 request->reply = reply;
429 iop_queue_wait_msg(struct iop_softc *sc, int mfa, struct i2o_basic_message *msg)
431 struct i2o_single_reply *reply;
432 struct iop_request request;
434 int status, timeout = 10000;
437 if (!(sc->reg->oqueue_intr_mask & 0x08)) {
438 msg->transaction_context = (u_int32_t)&request;
439 msg->initiator_context = (u_int32_t)iop_done;
440 sc->reg->iqueue = mfa;
441 if (msleep(&request, &sc->mtx, PRIBIO, "pstwt", 10 * hz)) {
442 printf("pstiop: timeout waiting for message response\n");
443 iop_free_mfa(sc, mfa);
444 mtx_unlock(&sc->mtx);
447 status = request.reply->status;
448 sc->reg->oqueue = request.mfa;
451 sc->reg->iqueue = mfa;
452 while (--timeout && ((out_mfa = sc->reg->oqueue) == 0xffffffff))
455 printf("pstiop: timeout waiting for message response\n");
456 iop_free_mfa(sc, mfa);
457 mtx_unlock(&sc->mtx);
460 reply = (struct i2o_single_reply *)(sc->obase+(out_mfa-sc->phys_obase));
461 status = reply->status;
462 sc->reg->oqueue = out_mfa;
464 mtx_unlock(&sc->mtx);
469 iop_create_sgl(struct i2o_basic_message *msg, caddr_t data, int count, int dir)
471 struct i2o_sgl *sgl = (struct i2o_sgl *)((int32_t *)msg + msg->offset);
472 u_int32_t sgl_count, sgl_phys;
475 if (((uintptr_t)data & 3) || (count & 3)) {
476 printf("pstiop: non aligned DMA transfer attempted\n");
480 printf("pstiop: zero length DMA transfer attempted\n");
484 sgl_count = min(count, (PAGE_SIZE - ((uintptr_t)data & PAGE_MASK)));
485 sgl_phys = vtophys(data);
486 sgl->flags = dir | I2O_SGL_PAGELIST | I2O_SGL_EOB | I2O_SGL_END;
492 sgl->phys_addr[i] = sgl_phys;
493 sgl_phys = vtophys(data);
494 data += min(count, PAGE_SIZE);
495 count -= min(count, PAGE_SIZE);
496 if (++i >= I2O_SGL_MAX_SEGS) {
497 printf("pstiop: too many segments in SGL\n");
501 sgl->phys_addr[i] = sgl_phys;
502 msg->message_size += i;