1 /*- 2 * SPDX-License-Identifier: BSD-3-Clause 3 * 4 * Copyright (c) 2001,2002,2003 Søren Schmidt <sos@FreeBSD.org> 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 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. 18 * 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. 29 */ 30 31 #include <sys/param.h> 32 #include <sys/systm.h> 33 #include <sys/kernel.h> 34 #include <sys/module.h> 35 #include <sys/bus.h> 36 #include <sys/bio.h> 37 #include <sys/malloc.h> 38 #include <sys/lock.h> 39 #include <sys/mutex.h> 40 #include <vm/vm.h> 41 #include <vm/pmap.h> 42 #include <machine/stdarg.h> 43 #include <machine/resource.h> 44 #include <machine/bus.h> 45 #include <sys/rman.h> 46 #include <dev/pci/pcivar.h> 47 #include <dev/pci/pcireg.h> 48 49 #include "dev/pst/pst-iop.h" 50 51 struct iop_request { 52 struct i2o_single_reply *reply; 53 u_int32_t mfa; 54 }; 55 56 /* local vars */ 57 MALLOC_DEFINE(M_PSTIOP, "PSTIOP", "Promise SuperTrak IOP driver"); 58 59 int 60 iop_init(struct iop_softc *sc) 61 { 62 int mfa, timeout = 10000; 63 64 while ((mfa = sc->reg->iqueue) == 0xffffffff && --timeout) 65 DELAY(1000); 66 if (!timeout) { 67 printf("pstiop: no free mfa\n"); 68 return 0; 69 } 70 iop_free_mfa(sc, mfa); 71 72 sc->reg->oqueue_intr_mask = 0xffffffff; 73 74 if (!iop_reset(sc)) { 75 printf("pstiop: no reset response\n"); 76 return 0; 77 } 78 79 if (!iop_init_outqueue(sc)) { 80 printf("pstiop: init outbound queue failed\n"); 81 return 0; 82 } 83 84 /* register iop_attach to be run when interrupts are enabled */ 85 if (!(sc->iop_delayed_attach = (struct intr_config_hook *) 86 malloc(sizeof(struct intr_config_hook), 87 M_PSTIOP, M_NOWAIT | M_ZERO))) { 88 printf("pstiop: malloc of delayed attach hook failed\n"); 89 return 0; 90 } 91 sc->iop_delayed_attach->ich_func = iop_attach; 92 sc->iop_delayed_attach->ich_arg = sc; 93 if (config_intrhook_establish(sc->iop_delayed_attach)) { 94 printf("pstiop: config_intrhook_establish failed\n"); 95 free(sc->iop_delayed_attach, M_PSTIOP); 96 } 97 return 1; 98 } 99 100 void 101 iop_attach(void *arg) 102 { 103 struct iop_softc *sc; 104 int i; 105 106 sc = arg; 107 if (sc->iop_delayed_attach) { 108 config_intrhook_disestablish(sc->iop_delayed_attach); 109 free(sc->iop_delayed_attach, M_PSTIOP); 110 sc->iop_delayed_attach = NULL; 111 } 112 113 if (!iop_get_lct(sc)) { 114 printf("pstiop: get LCT failed\n"); 115 return; 116 } 117 118 /* figure out what devices are here and config as needed */ 119 for (i = 0; sc->lct[i].entry_size == I2O_LCT_ENTRYSIZE; i++) { 120 #ifdef PSTDEBUG 121 struct i2o_get_param_reply *reply; 122 123 printf("pstiop: LCT entry %d ", i); 124 printf("class=%04x ", sc->lct[i].class); 125 printf("sub=%04x ", sc->lct[i].sub_class); 126 printf("localtid=%04x ", sc->lct[i].local_tid); 127 printf("usertid=%04x ", sc->lct[i].user_tid); 128 printf("parentid=%04x\n", sc->lct[i].parent_tid); 129 130 if ((reply = iop_get_util_params(sc, sc->lct[i].local_tid, 131 I2O_PARAMS_OPERATION_FIELD_GET, 132 I2O_UTIL_DEVICE_IDENTITY_GROUP_NO))) { 133 struct i2o_device_identity *ident = 134 (struct i2o_device_identity *)reply->result; 135 printf("pstiop: vendor=<%.16s> product=<%.16s>\n", 136 ident->vendor, ident->product); 137 printf("pstiop: description=<%.16s> revision=<%.8s>\n", 138 ident->description, ident->revision); 139 free(reply, M_PSTIOP); 140 } 141 #endif 142 143 if (sc->lct[i].user_tid != I2O_TID_NONE && 144 sc->lct[i].user_tid != I2O_TID_HOST) 145 continue; 146 147 switch (sc->lct[i].class) { 148 case I2O_CLASS_DDM: 149 if (sc->lct[i].sub_class == I2O_SUBCLASS_ISM) 150 sc->ism = sc->lct[i].local_tid; 151 break; 152 153 case I2O_CLASS_RANDOM_BLOCK_STORAGE: 154 pst_add_raid(sc, &sc->lct[i]); 155 break; 156 } 157 } 158 159 /* setup and enable interrupts */ 160 bus_setup_intr(sc->dev, sc->r_irq, INTR_TYPE_BIO|INTR_ENTROPY|INTR_MPSAFE, 161 NULL, iop_intr, sc, &sc->handle); 162 sc->reg->oqueue_intr_mask = 0x0; 163 } 164 165 void 166 iop_intr(void *data) 167 { 168 struct iop_softc *sc = (struct iop_softc *)data; 169 struct i2o_single_reply *reply; 170 u_int32_t mfa; 171 172 /* we might get more than one finished request pr interrupt */ 173 mtx_lock(&sc->mtx); 174 while (1) { 175 if ((mfa = sc->reg->oqueue) == 0xffffffff) 176 if ((mfa = sc->reg->oqueue) == 0xffffffff) 177 break; 178 179 reply = (struct i2o_single_reply *)(sc->obase + (mfa - sc->phys_obase)); 180 181 /* if this is an event register reply, shout! */ 182 if (reply->function == I2O_UTIL_EVENT_REGISTER) { 183 struct i2o_util_event_reply_message *event = 184 (struct i2o_util_event_reply_message *)reply; 185 186 printf("pstiop: EVENT!! idx=%08x data=%08x\n", 187 event->event_mask, event->event_data[0]); 188 break; 189 } 190 191 /* if reply is a failurenotice we need to free the original mfa */ 192 if (reply->message_flags & I2O_MESSAGE_FLAGS_FAIL) 193 iop_free_mfa(sc,((struct i2o_fault_reply *)(reply))->preserved_mfa); 194 195 /* reply->initiator_context points to the service routine */ 196 ((void (*)(struct iop_softc *, u_int32_t, struct i2o_single_reply *)) 197 (reply->initiator_context))(sc, mfa, reply); 198 } 199 mtx_unlock(&sc->mtx); 200 } 201 202 int 203 iop_reset(struct iop_softc *sc) 204 { 205 struct i2o_exec_iop_reset_message *msg; 206 int mfa, timeout = 5000; 207 volatile u_int32_t reply = 0; 208 209 mfa = iop_get_mfa(sc); 210 msg = (struct i2o_exec_iop_reset_message *)(sc->ibase + mfa); 211 bzero(msg, sizeof(struct i2o_exec_iop_reset_message)); 212 msg->version_offset = 0x1; 213 msg->message_flags = 0x0; 214 msg->message_size = sizeof(struct i2o_exec_iop_reset_message) >> 2; 215 msg->target_address = I2O_TID_IOP; 216 msg->initiator_address = I2O_TID_HOST; 217 msg->function = I2O_EXEC_IOP_RESET; 218 msg->status_word_low_addr = vtophys(&reply); 219 msg->status_word_high_addr = 0; 220 221 sc->reg->iqueue = mfa; 222 223 while (--timeout && !reply) 224 DELAY(1000); 225 226 /* wait for iqueue ready */ 227 timeout = 10000; 228 while ((mfa = sc->reg->iqueue) == 0xffffffff && --timeout) 229 DELAY(1000); 230 231 iop_free_mfa(sc, mfa); 232 return reply; 233 } 234 235 int 236 iop_init_outqueue(struct iop_softc *sc) 237 { 238 struct i2o_exec_init_outqueue_message *msg; 239 int i, mfa, timeout = 5000; 240 volatile u_int32_t reply = 0; 241 242 if (!(sc->obase = contigmalloc(I2O_IOP_OUTBOUND_FRAME_COUNT * 243 I2O_IOP_OUTBOUND_FRAME_SIZE, 244 M_PSTIOP, M_NOWAIT, 245 0x00010000, 0xFFFFFFFF, 246 PAGE_SIZE, 0))) { 247 printf("pstiop: contigmalloc of outqueue buffers failed!\n"); 248 return 0; 249 } 250 sc->phys_obase = vtophys(sc->obase); 251 mfa = iop_get_mfa(sc); 252 msg = (struct i2o_exec_init_outqueue_message *)(sc->ibase + mfa); 253 bzero(msg, sizeof(struct i2o_exec_init_outqueue_message)); 254 msg->version_offset = 0x61; 255 msg->message_flags = 0x0; 256 msg->message_size = sizeof(struct i2o_exec_init_outqueue_message) >> 2; 257 msg->target_address = I2O_TID_IOP; 258 msg->initiator_address = I2O_TID_HOST; 259 msg->function = I2O_EXEC_OUTBOUND_INIT; 260 msg->host_pagesize = PAGE_SIZE; 261 msg->init_code = 0x00; /* SOS XXX should be 0x80 == OS */ 262 msg->queue_framesize = I2O_IOP_OUTBOUND_FRAME_SIZE / sizeof(u_int32_t); 263 msg->sgl[0].flags = I2O_SGL_SIMPLE | I2O_SGL_END | I2O_SGL_EOB; 264 msg->sgl[0].count = sizeof(reply); 265 msg->sgl[0].phys_addr[0] = vtophys(&reply); 266 msg->sgl[1].flags = I2O_SGL_END | I2O_SGL_EOB; 267 msg->sgl[1].count = 1; 268 msg->sgl[1].phys_addr[0] = 0; 269 270 sc->reg->iqueue = mfa; 271 272 /* wait for init to complete */ 273 while (--timeout && reply != I2O_EXEC_OUTBOUND_INIT_COMPLETE) 274 DELAY(1000); 275 276 if (!timeout) { 277 printf("pstiop: timeout waiting for init-complete response\n"); 278 iop_free_mfa(sc, mfa); 279 return 0; 280 } 281 282 /* now init our oqueue bufs */ 283 for (i = 0; i < I2O_IOP_OUTBOUND_FRAME_COUNT; i++) { 284 sc->reg->oqueue = sc->phys_obase + (i * I2O_IOP_OUTBOUND_FRAME_SIZE); 285 DELAY(1000); 286 } 287 288 return 1; 289 } 290 291 int 292 iop_get_lct(struct iop_softc *sc) 293 { 294 struct i2o_exec_get_lct_message *msg; 295 struct i2o_get_lct_reply *reply; 296 int mfa; 297 #define ALLOCSIZE (PAGE_SIZE + (256 * sizeof(struct i2o_lct_entry))) 298 299 if (!(reply = contigmalloc(ALLOCSIZE, M_PSTIOP, M_NOWAIT | M_ZERO, 300 0x00010000, 0xFFFFFFFF, PAGE_SIZE, 0))) 301 return 0; 302 303 mfa = iop_get_mfa(sc); 304 msg = (struct i2o_exec_get_lct_message *)(sc->ibase + mfa); 305 bzero(msg, sizeof(struct i2o_exec_get_lct_message)); 306 msg->version_offset = 0x61; 307 msg->message_flags = 0x0; 308 msg->message_size = sizeof(struct i2o_exec_get_lct_message) >> 2; 309 msg->target_address = I2O_TID_IOP; 310 msg->initiator_address = I2O_TID_HOST; 311 msg->function = I2O_EXEC_LCT_NOTIFY; 312 msg->class = I2O_CLASS_MATCH_ANYCLASS; 313 msg->last_change_id = 0; 314 315 msg->sgl.flags = I2O_SGL_SIMPLE | I2O_SGL_END | I2O_SGL_EOB; 316 msg->sgl.count = ALLOCSIZE; 317 msg->sgl.phys_addr[0] = vtophys(reply); 318 319 if (iop_queue_wait_msg(sc, mfa, (struct i2o_basic_message *)msg)) { 320 free(reply, M_PSTIOP); 321 return 0; 322 } 323 if (!(sc->lct = malloc(reply->table_size * sizeof(struct i2o_lct_entry), 324 M_PSTIOP, M_NOWAIT | M_ZERO))) { 325 free(reply, M_PSTIOP); 326 return 0; 327 } 328 bcopy(&reply->entry[0], sc->lct, 329 reply->table_size * sizeof(struct i2o_lct_entry)); 330 sc->lct_count = reply->table_size; 331 free(reply, M_PSTIOP); 332 return 1; 333 } 334 335 struct i2o_get_param_reply * 336 iop_get_util_params(struct iop_softc *sc, int target, int operation, int group) 337 { 338 struct i2o_util_get_param_message *msg; 339 struct i2o_get_param_operation *param; 340 struct i2o_get_param_reply *reply; 341 int mfa; 342 343 if (!(param = contigmalloc(PAGE_SIZE, M_PSTIOP, M_NOWAIT | M_ZERO, 344 0x00010000, 0xFFFFFFFF, PAGE_SIZE, 0))) 345 return NULL; 346 347 if (!(reply = contigmalloc(PAGE_SIZE, M_PSTIOP, M_NOWAIT | M_ZERO, 348 0x00010000, 0xFFFFFFFF, PAGE_SIZE, 0))) 349 return NULL; 350 351 mfa = iop_get_mfa(sc); 352 msg = (struct i2o_util_get_param_message *)(sc->ibase + mfa); 353 bzero(msg, sizeof(struct i2o_util_get_param_message)); 354 msg->version_offset = 0x51; 355 msg->message_flags = 0x0; 356 msg->message_size = sizeof(struct i2o_util_get_param_message) >> 2; 357 msg->target_address = target; 358 msg->initiator_address = I2O_TID_HOST; 359 msg->function = I2O_UTIL_PARAMS_GET; 360 msg->operation_flags = 0; 361 362 param->operation_count = 1; 363 param->operation[0].operation = operation; 364 param->operation[0].group = group; 365 param->operation[0].field_count = 0xffff; 366 367 msg->sgl[0].flags = I2O_SGL_SIMPLE | I2O_SGL_DIR | I2O_SGL_EOB; 368 msg->sgl[0].count = sizeof(struct i2o_get_param_operation); 369 msg->sgl[0].phys_addr[0] = vtophys(param); 370 371 msg->sgl[1].flags = I2O_SGL_SIMPLE | I2O_SGL_END | I2O_SGL_EOB; 372 msg->sgl[1].count = PAGE_SIZE; 373 msg->sgl[1].phys_addr[0] = vtophys(reply); 374 375 if (iop_queue_wait_msg(sc, mfa, (struct i2o_basic_message *)msg) || 376 reply->error_info_size) { 377 free(reply, M_PSTIOP); 378 reply = NULL; 379 } 380 free(param, M_PSTIOP); 381 return reply; 382 } 383 384 u_int32_t 385 iop_get_mfa(struct iop_softc *sc) 386 { 387 u_int32_t mfa; 388 int timeout = 10000; 389 390 while ((mfa = sc->reg->iqueue) == 0xffffffff && timeout) { 391 DELAY(1000); 392 timeout--; 393 } 394 if (!timeout) 395 printf("pstiop: no free mfa\n"); 396 return mfa; 397 } 398 399 void 400 iop_free_mfa(struct iop_softc *sc, int mfa) 401 { 402 struct i2o_basic_message *msg = (struct i2o_basic_message *)(sc->ibase+mfa); 403 404 bzero(msg, sizeof(struct i2o_basic_message)); 405 msg->version = 0x01; 406 msg->message_flags = 0x0; 407 msg->message_size = sizeof(struct i2o_basic_message) >> 2; 408 msg->target_address = I2O_TID_IOP; 409 msg->initiator_address = I2O_TID_HOST; 410 msg->function = I2O_UTIL_NOP; 411 sc->reg->iqueue = mfa; 412 } 413 414 static void 415 iop_done(struct iop_softc *sc, u_int32_t mfa, struct i2o_single_reply *reply) 416 { 417 struct iop_request *request = 418 (struct iop_request *)reply->transaction_context; 419 420 request->reply = reply; 421 request->mfa = mfa; 422 wakeup(request); 423 } 424 425 int 426 iop_queue_wait_msg(struct iop_softc *sc, int mfa, struct i2o_basic_message *msg) 427 { 428 struct i2o_single_reply *reply; 429 struct iop_request request; 430 u_int32_t out_mfa; 431 int status, timeout = 10000; 432 433 mtx_lock(&sc->mtx); 434 if ((sc->reg->oqueue_intr_mask & I2O_OUT_INTR_QUEUE) == 0) { 435 msg->transaction_context = (u_int32_t)&request; 436 msg->initiator_context = (u_int32_t)iop_done; 437 sc->reg->iqueue = mfa; 438 if (msleep(&request, &sc->mtx, PRIBIO, "pstwt", 10 * hz)) { 439 printf("pstiop: timeout waiting for message response\n"); 440 iop_free_mfa(sc, mfa); 441 mtx_unlock(&sc->mtx); 442 return -1; 443 } 444 status = request.reply->status; 445 sc->reg->oqueue = request.mfa; 446 } 447 else { 448 sc->reg->iqueue = mfa; 449 while (--timeout && ((out_mfa = sc->reg->oqueue) == 0xffffffff)) 450 DELAY(1000); 451 if (!timeout) { 452 printf("pstiop: timeout waiting for message response\n"); 453 iop_free_mfa(sc, mfa); 454 mtx_unlock(&sc->mtx); 455 return -1; 456 } 457 reply = (struct i2o_single_reply *)(sc->obase+(out_mfa-sc->phys_obase)); 458 status = reply->status; 459 sc->reg->oqueue = out_mfa; 460 } 461 mtx_unlock(&sc->mtx); 462 return status; 463 } 464 465 int 466 iop_create_sgl(struct i2o_basic_message *msg, caddr_t data, int count, int dir) 467 { 468 struct i2o_sgl *sgl = (struct i2o_sgl *)((int32_t *)msg + msg->offset); 469 u_int32_t sgl_count, sgl_phys; 470 int i = 0; 471 472 if (((uintptr_t)data & 3) || (count & 3)) { 473 printf("pstiop: non aligned DMA transfer attempted\n"); 474 return 0; 475 } 476 if (!count) { 477 printf("pstiop: zero length DMA transfer attempted\n"); 478 return 0; 479 } 480 481 sgl_count = min(count, (PAGE_SIZE - ((uintptr_t)data & PAGE_MASK))); 482 sgl_phys = vtophys(data); 483 sgl->flags = dir | I2O_SGL_PAGELIST | I2O_SGL_EOB | I2O_SGL_END; 484 sgl->count = count; 485 data += sgl_count; 486 count -= sgl_count; 487 488 while (count) { 489 sgl->phys_addr[i] = sgl_phys; 490 sgl_phys = vtophys(data); 491 data += min(count, PAGE_SIZE); 492 count -= min(count, PAGE_SIZE); 493 if (++i >= I2O_SGL_MAX_SEGS) { 494 printf("pstiop: too many segments in SGL\n"); 495 return 0; 496 } 497 } 498 sgl->phys_addr[i] = sgl_phys; 499 msg->message_size += i; 500 return 1; 501 } 502