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