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/cdefs.h> 32 __FBSDID("$FreeBSD$"); 33 34 #include <sys/param.h> 35 #include <sys/systm.h> 36 #include <sys/kernel.h> 37 #include <sys/module.h> 38 #include <sys/bus.h> 39 #include <sys/bio.h> 40 #include <sys/malloc.h> 41 #include <sys/lock.h> 42 #include <sys/mutex.h> 43 #include <vm/vm.h> 44 #include <vm/pmap.h> 45 #include <machine/stdarg.h> 46 #include <machine/resource.h> 47 #include <machine/bus.h> 48 #include <sys/rman.h> 49 #include <dev/pci/pcivar.h> 50 #include <dev/pci/pcireg.h> 51 52 #include "dev/pst/pst-iop.h" 53 54 struct iop_request { 55 struct i2o_single_reply *reply; 56 u_int32_t mfa; 57 }; 58 59 /* local vars */ 60 MALLOC_DEFINE(M_PSTIOP, "PSTIOP", "Promise SuperTrak IOP driver"); 61 62 int 63 iop_init(struct iop_softc *sc) 64 { 65 int mfa, timeout = 10000; 66 67 while ((mfa = sc->reg->iqueue) == 0xffffffff && --timeout) 68 DELAY(1000); 69 if (!timeout) { 70 printf("pstiop: no free mfa\n"); 71 return 0; 72 } 73 iop_free_mfa(sc, mfa); 74 75 sc->reg->oqueue_intr_mask = 0xffffffff; 76 77 if (!iop_reset(sc)) { 78 printf("pstiop: no reset response\n"); 79 return 0; 80 } 81 82 if (!iop_init_outqueue(sc)) { 83 printf("pstiop: init outbound queue failed\n"); 84 return 0; 85 } 86 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"); 92 return 0; 93 } 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); 99 } 100 return 1; 101 } 102 103 void 104 iop_attach(void *arg) 105 { 106 struct iop_softc *sc; 107 int i; 108 109 sc = arg; 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; 114 } 115 116 if (!iop_get_lct(sc)) { 117 printf("pstiop: get LCT failed\n"); 118 return; 119 } 120 121 /* figure out what devices are here and config as needed */ 122 for (i = 0; sc->lct[i].entry_size == I2O_LCT_ENTRYSIZE; i++) { 123 #ifdef PSTDEBUG 124 struct i2o_get_param_reply *reply; 125 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); 132 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); 143 } 144 #endif 145 146 if (sc->lct[i].user_tid != I2O_TID_NONE && 147 sc->lct[i].user_tid != I2O_TID_HOST) 148 continue; 149 150 switch (sc->lct[i].class) { 151 case I2O_CLASS_DDM: 152 if (sc->lct[i].sub_class == I2O_SUBCLASS_ISM) 153 sc->ism = sc->lct[i].local_tid; 154 break; 155 156 case I2O_CLASS_RANDOM_BLOCK_STORAGE: 157 pst_add_raid(sc, &sc->lct[i]); 158 break; 159 } 160 } 161 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; 166 } 167 168 void 169 iop_intr(void *data) 170 { 171 struct iop_softc *sc = (struct iop_softc *)data; 172 struct i2o_single_reply *reply; 173 u_int32_t mfa; 174 175 /* we might get more than one finished request pr interrupt */ 176 mtx_lock(&sc->mtx); 177 while (1) { 178 if ((mfa = sc->reg->oqueue) == 0xffffffff) 179 if ((mfa = sc->reg->oqueue) == 0xffffffff) 180 break; 181 182 reply = (struct i2o_single_reply *)(sc->obase + (mfa - sc->phys_obase)); 183 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; 188 189 printf("pstiop: EVENT!! idx=%08x data=%08x\n", 190 event->event_mask, event->event_data[0]); 191 break; 192 } 193 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); 197 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); 201 } 202 mtx_unlock(&sc->mtx); 203 } 204 205 int 206 iop_reset(struct iop_softc *sc) 207 { 208 struct i2o_exec_iop_reset_message *msg; 209 int mfa, timeout = 5000; 210 volatile u_int32_t reply = 0; 211 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; 223 224 sc->reg->iqueue = mfa; 225 226 while (--timeout && !reply) 227 DELAY(1000); 228 229 /* wait for iqueue ready */ 230 timeout = 10000; 231 while ((mfa = sc->reg->iqueue) == 0xffffffff && --timeout) 232 DELAY(1000); 233 234 iop_free_mfa(sc, mfa); 235 return reply; 236 } 237 238 int 239 iop_init_outqueue(struct iop_softc *sc) 240 { 241 struct i2o_exec_init_outqueue_message *msg; 242 int i, mfa, timeout = 5000; 243 volatile u_int32_t reply = 0; 244 245 if (!(sc->obase = contigmalloc(I2O_IOP_OUTBOUND_FRAME_COUNT * 246 I2O_IOP_OUTBOUND_FRAME_SIZE, 247 M_PSTIOP, M_NOWAIT, 248 0x00010000, 0xFFFFFFFF, 249 PAGE_SIZE, 0))) { 250 printf("pstiop: contigmalloc of outqueue buffers failed!\n"); 251 return 0; 252 } 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; 272 273 sc->reg->iqueue = mfa; 274 275 /* wait for init to complete */ 276 while (--timeout && reply != I2O_EXEC_OUTBOUND_INIT_COMPLETE) 277 DELAY(1000); 278 279 if (!timeout) { 280 printf("pstiop: timeout waiting for init-complete response\n"); 281 iop_free_mfa(sc, mfa); 282 return 0; 283 } 284 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); 288 DELAY(1000); 289 } 290 291 return 1; 292 } 293 294 int 295 iop_get_lct(struct iop_softc *sc) 296 { 297 struct i2o_exec_get_lct_message *msg; 298 struct i2o_get_lct_reply *reply; 299 int mfa; 300 #define ALLOCSIZE (PAGE_SIZE + (256 * sizeof(struct i2o_lct_entry))) 301 302 if (!(reply = contigmalloc(ALLOCSIZE, M_PSTIOP, M_NOWAIT | M_ZERO, 303 0x00010000, 0xFFFFFFFF, PAGE_SIZE, 0))) 304 return 0; 305 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; 317 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); 321 322 if (iop_queue_wait_msg(sc, mfa, (struct i2o_basic_message *)msg)) { 323 contigfree(reply, ALLOCSIZE, M_PSTIOP); 324 return 0; 325 } 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); 329 return 0; 330 } 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); 335 return 1; 336 } 337 338 struct i2o_get_param_reply * 339 iop_get_util_params(struct iop_softc *sc, int target, int operation, int group) 340 { 341 struct i2o_util_get_param_message *msg; 342 struct i2o_get_param_operation *param; 343 struct i2o_get_param_reply *reply; 344 int mfa; 345 346 if (!(param = contigmalloc(PAGE_SIZE, M_PSTIOP, M_NOWAIT | M_ZERO, 347 0x00010000, 0xFFFFFFFF, PAGE_SIZE, 0))) 348 return NULL; 349 350 if (!(reply = contigmalloc(PAGE_SIZE, M_PSTIOP, M_NOWAIT | M_ZERO, 351 0x00010000, 0xFFFFFFFF, PAGE_SIZE, 0))) 352 return NULL; 353 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; 364 365 param->operation_count = 1; 366 param->operation[0].operation = operation; 367 param->operation[0].group = group; 368 param->operation[0].field_count = 0xffff; 369 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); 373 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); 377 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); 381 reply = NULL; 382 } 383 contigfree(param, PAGE_SIZE, M_PSTIOP); 384 return reply; 385 } 386 387 u_int32_t 388 iop_get_mfa(struct iop_softc *sc) 389 { 390 u_int32_t mfa; 391 int timeout = 10000; 392 393 while ((mfa = sc->reg->iqueue) == 0xffffffff && timeout) { 394 DELAY(1000); 395 timeout--; 396 } 397 if (!timeout) 398 printf("pstiop: no free mfa\n"); 399 return mfa; 400 } 401 402 void 403 iop_free_mfa(struct iop_softc *sc, int mfa) 404 { 405 struct i2o_basic_message *msg = (struct i2o_basic_message *)(sc->ibase+mfa); 406 407 bzero(msg, sizeof(struct i2o_basic_message)); 408 msg->version = 0x01; 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; 415 } 416 417 static void 418 iop_done(struct iop_softc *sc, u_int32_t mfa, struct i2o_single_reply *reply) 419 { 420 struct iop_request *request = 421 (struct iop_request *)reply->transaction_context; 422 423 request->reply = reply; 424 request->mfa = mfa; 425 wakeup(request); 426 } 427 428 int 429 iop_queue_wait_msg(struct iop_softc *sc, int mfa, struct i2o_basic_message *msg) 430 { 431 struct i2o_single_reply *reply; 432 struct iop_request request; 433 u_int32_t out_mfa; 434 int status, timeout = 10000; 435 436 mtx_lock(&sc->mtx); 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); 445 return -1; 446 } 447 status = request.reply->status; 448 sc->reg->oqueue = request.mfa; 449 } 450 else { 451 sc->reg->iqueue = mfa; 452 while (--timeout && ((out_mfa = sc->reg->oqueue) == 0xffffffff)) 453 DELAY(1000); 454 if (!timeout) { 455 printf("pstiop: timeout waiting for message response\n"); 456 iop_free_mfa(sc, mfa); 457 mtx_unlock(&sc->mtx); 458 return -1; 459 } 460 reply = (struct i2o_single_reply *)(sc->obase+(out_mfa-sc->phys_obase)); 461 status = reply->status; 462 sc->reg->oqueue = out_mfa; 463 } 464 mtx_unlock(&sc->mtx); 465 return status; 466 } 467 468 int 469 iop_create_sgl(struct i2o_basic_message *msg, caddr_t data, int count, int dir) 470 { 471 struct i2o_sgl *sgl = (struct i2o_sgl *)((int32_t *)msg + msg->offset); 472 u_int32_t sgl_count, sgl_phys; 473 int i = 0; 474 475 if (((uintptr_t)data & 3) || (count & 3)) { 476 printf("pstiop: non aligned DMA transfer attempted\n"); 477 return 0; 478 } 479 if (!count) { 480 printf("pstiop: zero length DMA transfer attempted\n"); 481 return 0; 482 } 483 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; 487 sgl->count = count; 488 data += sgl_count; 489 count -= sgl_count; 490 491 while (count) { 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"); 498 return 0; 499 } 500 } 501 sgl->phys_addr[i] = sgl_phys; 502 msg->message_size += i; 503 return 1; 504 } 505