diff options
author | sos <sos@FreeBSD.org> | 2003-04-28 08:10:27 +0000 |
---|---|---|
committer | sos <sos@FreeBSD.org> | 2003-04-28 08:10:27 +0000 |
commit | e4d0be5799de5eb1f1f39497ae6f59ba0be217f7 (patch) | |
tree | 5898bc19a4e88c6f75e85b4d29759a242d7ce1ff /sys/dev/pst | |
parent | 1b6624b99947fc439495bb677aefb00a9b89872f (diff) | |
download | FreeBSD-src-e4d0be5799de5eb1f1f39497ae6f59ba0be217f7.zip FreeBSD-src-e4d0be5799de5eb1f1f39497ae6f59ba0be217f7.tar.gz |
Pull the pst driver out from under GAINT.
Diffstat (limited to 'sys/dev/pst')
-rw-r--r-- | sys/dev/pst/pst-iop.c | 91 | ||||
-rw-r--r-- | sys/dev/pst/pst-iop.h | 23 | ||||
-rw-r--r-- | sys/dev/pst/pst-pci.c | 19 | ||||
-rw-r--r-- | sys/dev/pst/pst-raid.c | 93 |
4 files changed, 151 insertions, 75 deletions
diff --git a/sys/dev/pst/pst-iop.c b/sys/dev/pst/pst-iop.c index 98c2f1d..dd372ef 100644 --- a/sys/dev/pst/pst-iop.c +++ b/sys/dev/pst/pst-iop.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2001,2002 Søren Schmidt <sos@FreeBSD.org> + * Copyright (c) 2001,2002,2003 Søren Schmidt <sos@FreeBSD.org> * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -35,6 +35,8 @@ #include <sys/bus.h> #include <sys/bio.h> #include <sys/malloc.h> +#include <sys/lock.h> +#include <sys/mutex.h> #include <vm/vm.h> #include <vm/pmap.h> #include <machine/stdarg.h> @@ -46,6 +48,11 @@ #include "dev/pst/pst-iop.h" +struct iop_request { + struct i2o_single_reply *reply; + u_int32_t mfa; +}; + /* local vars */ MALLOC_DEFINE(M_PSTIOP, "PSTIOP", "Promise SuperTrak IOP driver"); @@ -136,13 +143,19 @@ iop_attach(struct iop_softc *sc) continue; switch (sc->lct[i].class) { + case I2O_CLASS_DDM: + if (sc->lct[i].sub_class == I2O_SUBCLASS_ISM) + sc->ism = sc->lct[i].local_tid; + break; + case I2O_CLASS_RANDOM_BLOCK_STORAGE: pst_add_raid(sc, &sc->lct[i]); break; } } + /* setup and enable interrupts */ - bus_setup_intr(sc->dev, sc->r_irq, INTR_TYPE_BIO | INTR_ENTROPY, + bus_setup_intr(sc->dev, sc->r_irq, INTR_TYPE_BIO|INTR_ENTROPY|INTR_MPSAFE, iop_intr, sc, &sc->handle); sc->reg->oqueue_intr_mask = 0x0; } @@ -155,21 +168,22 @@ iop_intr(void *data) u_int32_t mfa; /* we might get more than one finished request pr interrupt */ + mtx_lock(&sc->mtx); while (1) { if ((mfa = sc->reg->oqueue) == 0xffffffff) if ((mfa = sc->reg->oqueue) == 0xffffffff) - return; + break; reply = (struct i2o_single_reply *)(sc->obase + (mfa - sc->phys_obase)); - /* If this is an event register reply, shout! */ + /* if this is an event register reply, shout! */ if (reply->function == I2O_UTIL_EVENT_REGISTER) { struct i2o_util_event_reply_message *event = (struct i2o_util_event_reply_message *)reply; printf("pstiop: EVENT!! idx=%08x data=%08x\n", event->event_mask, event->event_data[0]); - return; + break; } /* if reply is a failurenotice we need to free the original mfa */ @@ -180,6 +194,7 @@ iop_intr(void *data) ((void (*)(struct iop_softc *, u_int32_t, struct i2o_single_reply *)) (reply->initiator_context))(sc, mfa, reply); } + mtx_unlock(&sc->mtx); } int @@ -226,7 +241,7 @@ iop_init_outqueue(struct iop_softc *sc) I2O_IOP_OUTBOUND_FRAME_SIZE, M_PSTIOP, M_NOWAIT, 0x00010000, 0xFFFFFFFF, - sizeof(u_int32_t), 0))) { + PAGE_SIZE, 0))) { printf("pstiop: contigmalloc of outqueue buffers failed!\n"); return 0; } @@ -268,7 +283,6 @@ iop_init_outqueue(struct iop_softc *sc) DELAY(1000); } - iop_free_mfa(sc, mfa); return 1; } @@ -281,7 +295,7 @@ iop_get_lct(struct iop_softc *sc) #define ALLOCSIZE (PAGE_SIZE + (256 * sizeof(struct i2o_lct_entry))) if (!(reply = contigmalloc(ALLOCSIZE, M_PSTIOP, M_NOWAIT | M_ZERO, - 0x00010000, 0xFFFFFFFF, sizeof(u_int32_t), 0))) + 0x00010000, 0xFFFFFFFF, PAGE_SIZE, 0))) return 0; mfa = iop_get_mfa(sc); @@ -325,11 +339,11 @@ iop_get_util_params(struct iop_softc *sc, int target, int operation, int group) int mfa; if (!(param = contigmalloc(PAGE_SIZE, M_PSTIOP, M_NOWAIT | M_ZERO, - 0x00010000, 0xFFFFFFFF, sizeof(u_int32_t), 0))) + 0x00010000, 0xFFFFFFFF, PAGE_SIZE, 0))) return NULL; if (!(reply = contigmalloc(PAGE_SIZE, M_PSTIOP, M_NOWAIT | M_ZERO, - 0x00010000, 0xFFFFFFFF, sizeof(u_int32_t), 0))) + 0x00010000, 0xFFFFFFFF, PAGE_SIZE, 0))) return NULL; mfa = iop_get_mfa(sc); @@ -395,25 +409,54 @@ iop_free_mfa(struct iop_softc *sc, int mfa) sc->reg->iqueue = mfa; } +static void +iop_done(struct iop_softc *sc, u_int32_t mfa, struct i2o_single_reply *reply) +{ + struct iop_request *request = + (struct iop_request *)reply->transaction_context; + + request->reply = reply; + request->mfa = mfa; + wakeup(request); +} + int iop_queue_wait_msg(struct iop_softc *sc, int mfa, struct i2o_basic_message *msg) { struct i2o_single_reply *reply; - int out_mfa, status, timeout = 10000; - - sc->reg->iqueue = mfa; - - while (--timeout && ((out_mfa = sc->reg->oqueue) == 0xffffffff)) - DELAY(1000); - if (!timeout) { - printf("pstiop: timeout waiting for message response\n"); - iop_free_mfa(sc, mfa); - return -1; + struct iop_request request; + u_int32_t out_mfa; + int status, timeout = 10000; + + mtx_lock(&sc->mtx); + if (!(sc->reg->oqueue_intr_mask & 0x08)) { + msg->transaction_context = (u_int32_t)&request; + msg->initiator_context = (u_int32_t)iop_done; + sc->reg->iqueue = mfa; + if (msleep(&request, &sc->mtx, PRIBIO, "pstwt", 10 * hz)) { + printf("pstiop: timeout waiting for message response\n"); + iop_free_mfa(sc, mfa); + mtx_unlock(&sc->mtx); + return -1; + } + status = request.reply->status; + sc->reg->oqueue = request.mfa; } - - reply = (struct i2o_single_reply *)(sc->obase + (out_mfa - sc->phys_obase)); - status = reply->status; - sc->reg->oqueue = out_mfa; + else { + sc->reg->iqueue = mfa; + while (--timeout && ((out_mfa = sc->reg->oqueue) == 0xffffffff)) + DELAY(1000); + if (!timeout) { + printf("pstiop: timeout waiting for message response\n"); + iop_free_mfa(sc, mfa); + mtx_unlock(&sc->mtx); + return -1; + } + reply = (struct i2o_single_reply *)(sc->obase+(out_mfa-sc->phys_obase)); + status = reply->status; + sc->reg->oqueue = out_mfa; + } + mtx_unlock(&sc->mtx); return status; } diff --git a/sys/dev/pst/pst-iop.h b/sys/dev/pst/pst-iop.h index 3b45d89..9badbf8 100644 --- a/sys/dev/pst/pst-iop.h +++ b/sys/dev/pst/pst-iop.h @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2001,2002 Søren Schmidt <sos@FreeBSD.org> + * Copyright (c) 2001,2002,2003 Søren Schmidt <sos@FreeBSD.org> * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -49,7 +49,10 @@ struct iop_softc { struct i2o_status_get_reply *status; int lct_count; struct i2o_lct_entry *lct; + int ism; device_t dev; + struct mtx mtx; + int outstanding; void *handle; struct intr_config_hook *iop_delayed_attach; }; @@ -121,6 +124,7 @@ struct i2o_sgl { #define I2O_EXEC_SYSTAB_SET 0xa3 #define I2O_EXEC_IOP_RESET 0xbd #define I2O_EXEC_SYS_ENABLE 0xd1 +#define I2O_PRIVATE_MESSAGE 0xff /* basic message layout */ struct i2o_basic_message { @@ -498,7 +502,7 @@ struct i2o_get_param_operation { } __packed; struct i2o_get_param_reply { - u_int16_t result_count;; + u_int16_t result_count; u_int16_t reserved; u_int16_t block_size; u_int8_t block_status; @@ -580,6 +584,21 @@ struct i2o_util_config_dialog_message { struct i2o_sgl sgl[2]; } __packed; +struct i2o_private_message { + u_int8_t version_offset; + u_int8_t message_flags; + u_int16_t message_size; + u_int32_t target_address:12; + u_int32_t initiator_address:12; + u_int32_t function:8; + u_int32_t initiator_context; + u_int32_t transaction_context; + u_int16_t function_code; + u_int16_t organization_id; + struct i2o_sgl in_sgl; + struct i2o_sgl out_sgl; +} __packed; + struct i2o_bsa_rw_block_message { u_int8_t version_offset; u_int8_t message_flags; diff --git a/sys/dev/pst/pst-pci.c b/sys/dev/pst/pst-pci.c index 0955450..47272dc 100644 --- a/sys/dev/pst/pst-pci.c +++ b/sys/dev/pst/pst-pci.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2001,2002 Søren Schmidt <sos@FreeBSD.org> + * Copyright (c) 2001,2002,2003 Søren Schmidt <sos@FreeBSD.org> * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -35,6 +35,8 @@ #include <sys/bus.h> #include <sys/bio.h> #include <sys/malloc.h> +#include <sys/lock.h> +#include <sys/mutex.h> #include <vm/vm.h> #include <vm/pmap.h> #include <machine/stdarg.h> @@ -93,16 +95,29 @@ iop_pci_attach(device_t dev) sc->phys_ibase = vtophys(sc->ibase); sc->reg = (struct i2o_registers *)sc->ibase; sc->dev = dev; + mtx_init(&sc->mtx, "pst lock", MTX_DEF, 0); if (!iop_init(sc)) return 0; - return bus_generic_attach(dev); } +static int +iop_pci_detach(device_t dev) +{ + struct iop_softc *sc = device_get_softc(dev); + + bus_teardown_intr(dev, sc->r_irq, sc->handle); + bus_release_resource(dev, SYS_RES_IRQ, 0x00, sc->r_irq); + bus_release_resource(dev, SYS_RES_MEMORY, 0x10, sc->r_mem); + return bus_generic_detach(dev); +} + + static device_method_t pst_pci_methods[] = { DEVMETHOD(device_probe, iop_pci_probe), DEVMETHOD(device_attach, iop_pci_attach), + DEVMETHOD(device_detach, iop_pci_detach), { 0, 0 } }; diff --git a/sys/dev/pst/pst-raid.c b/sys/dev/pst/pst-raid.c index b7c96de..957d3b7 100644 --- a/sys/dev/pst/pst-raid.c +++ b/sys/dev/pst/pst-raid.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2001,2002 Søren Schmidt <sos@FreeBSD.org> + * Copyright (c) 2001,2002,2003 Søren Schmidt <sos@FreeBSD.org> * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -57,8 +57,6 @@ struct pst_softc { struct i2o_bsa_device *info; struct disk disk; struct bio_queue_head queue; - struct mtx mtx; - int outstanding; }; struct pst_request { @@ -149,13 +147,12 @@ pst_attach(device_t dev) contigfree(reply, PAGE_SIZE, M_PSTRAID); bioq_init(&psc->queue); - mtx_init(&psc->mtx, "pst lock", MTX_DEF, 0); psc->disk.d_name = "pst"; psc->disk.d_strategy = pststrategy; psc->disk.d_maxsize = 64 * 1024; /*I2O_SGL_MAX_SEGS * PAGE_SIZE;*/ psc->disk.d_drv1 = psc; - disk_create(lun, &psc->disk, 0, NULL, NULL); + disk_create(lun, &psc->disk, DISKFLAG_NOGIANT, NULL, NULL); psc->disk.d_sectorsize = psc->info->block_size; psc->disk.d_mediasize = psc->info->capacity; @@ -199,10 +196,10 @@ pststrategy(struct bio *bp) { struct pst_softc *psc = bp->bio_disk->d_drv1; - mtx_lock(&psc->mtx); + mtx_lock(&psc->iop->mtx); bioq_disksort(&psc->queue, bp); pst_start(psc); - mtx_unlock(&psc->mtx); + mtx_unlock(&psc->iop->mtx); } static void @@ -212,7 +209,7 @@ pst_start(struct pst_softc *psc) struct bio *bp; u_int32_t mfa; - if (psc->outstanding < (I2O_IOP_OUTBOUND_FRAME_COUNT - 1) && + if (psc->iop->outstanding < (I2O_IOP_OUTBOUND_FRAME_COUNT - 1) && (bp = bioq_first(&psc->queue))) { if ((mfa = iop_get_mfa(psc->iop)) != 0xffffffff) { bioq_remove(&psc->queue, bp); @@ -223,19 +220,14 @@ pst_start(struct pst_softc *psc) iop_free_mfa(psc->iop, mfa); return; } - psc->outstanding++; + psc->iop->outstanding++; request->psc = psc; request->mfa = mfa; request->bp = bp; - if (dumping) - request->timeout_handle.callout = NULL; - else - request->timeout_handle = - timeout((timeout_t*)pst_timeout, request, 10 * hz); if (pst_rw(request)) { biofinish(request->bp, NULL, EIO); iop_free_mfa(request->psc->iop, request->mfa); - psc->outstanding--; + psc->iop->outstanding--; free(request, M_PSTRAID); } } @@ -253,38 +245,9 @@ pst_done(struct iop_softc *sc, u_int32_t mfa, struct i2o_single_reply *reply) request->bp->bio_resid = request->bp->bio_bcount - reply->donecount; biofinish(request->bp, NULL, reply->status ? EIO : 0); free(request, M_PSTRAID); - mtx_lock(&psc->mtx); psc->iop->reg->oqueue = mfa; - psc->outstanding--; + psc->iop->outstanding--; pst_start(psc); - mtx_unlock(&psc->mtx); -} - -static void -pst_timeout(struct pst_request *request) -{ - printf("pst: timeout mfa=0x%08x cmd=0x%02x\n", - request->mfa, request->bp->bio_cmd); - mtx_lock(&request->psc->mtx); - iop_free_mfa(request->psc->iop, request->mfa); - if ((request->mfa = iop_get_mfa(request->psc->iop)) == 0xffffffff) { - printf("pst: timeout no mfa possible\n"); - biofinish(request->bp, NULL, EIO); - request->psc->outstanding--; - mtx_unlock(&request->psc->mtx); - return; - } - if (dumping) - request->timeout_handle.callout = NULL; - else - request->timeout_handle = - timeout((timeout_t*)pst_timeout, request, 10 * hz); - if (pst_rw(request)) { - iop_free_mfa(request->psc->iop, request->mfa); - biofinish(request->bp, NULL, EIO); - request->psc->outstanding--; - } - mtx_unlock(&request->psc->mtx); } int @@ -315,7 +278,7 @@ pst_rw(struct pst_request *request) sgl_flag = I2O_SGL_DIR; break; default: - printf("pst: unknown command type\n"); + printf("pst: unknown command type 0x%02x\n", request->bp->bio_cmd); return -1; } msg->initiator_context = (u_int32_t)pst_done; @@ -323,21 +286,57 @@ pst_rw(struct pst_request *request) msg->time_multiplier = 1; msg->bytecount = request->bp->bio_bcount; msg->lba = ((u_int64_t)request->bp->bio_pblkno) * (DEV_BSIZE * 1LL); + if (!iop_create_sgl((struct i2o_basic_message *)msg, request->bp->bio_data, request->bp->bio_bcount, sgl_flag)) return -1; + request->psc->iop->reg->iqueue = request->mfa; + + if (dumping) + request->timeout_handle.callout = NULL; + else + request->timeout_handle = + timeout((timeout_t*)pst_timeout, request, 10 * hz); return 0; } static void +pst_timeout(struct pst_request *request) +{ + printf("pst: timeout mfa=0x%08x cmd=0x%02x\n", + request->mfa, request->bp->bio_cmd); + mtx_lock(&request->psc->iop->mtx); + iop_free_mfa(request->psc->iop, request->mfa); + if ((request->mfa = iop_get_mfa(request->psc->iop)) == 0xffffffff) { + printf("pst: timeout no mfa possible\n"); + biofinish(request->bp, NULL, EIO); + request->psc->iop->outstanding--; + mtx_unlock(&request->psc->iop->mtx); + return; + } + if (dumping) + request->timeout_handle.callout = NULL; + else + request->timeout_handle = + timeout((timeout_t*)pst_timeout, request, 10 * hz); + if (pst_rw(request)) { + iop_free_mfa(request->psc->iop, request->mfa); + biofinish(request->bp, NULL, EIO); + request->psc->iop->outstanding--; + } + mtx_unlock(&request->psc->iop->mtx); +} + +static void bpack(int8_t *src, int8_t *dst, int len) { int i, j, blank; int8_t *ptr, *buf = dst; for (i = j = blank = 0 ; i < len; i++) { - if (blank && src[i] == ' ') continue; + if (blank && src[i] == ' ') + continue; if (blank && src[i] != ' ') { dst[j++] = src[i]; blank = 0; |