static void browser(AvahiServiceBrowser *b, AvahiIfIndex interface, AvahiProtocol protocol, AvahiBrowserEvent event, const char *name, const char *type, const char *domain, AvahiLookupResultFlags flags, void *userdata) { service_aux_t *sa = userdata; service_instance_t *si; char fullname[256]; snprintf(fullname, sizeof(fullname), "%s.%s.%s.%d.%d", name, type, domain, interface, protocol); switch(event) { case AVAHI_BROWSER_NEW: si = calloc(1, sizeof(service_instance_t)); si->si_opaque = sa; si->si_id = strdup(fullname); LIST_INSERT_HEAD(&services, si, si_link); if(!(avahi_service_resolver_new(sa->sa_c, interface, protocol, name, type, domain, AVAHI_PROTO_INET, 0, resolve_callback, si))) { si_destroy(si); TRACE(TRACE_ERROR, "AVAHI", "Failed to resolve service '%s': %s\n", name, avahi_strerror(avahi_client_errno(sa->sa_c))); } break; case AVAHI_BROWSER_REMOVE: si = si_find(&services, fullname); if(si != NULL) si_destroy(si); break; default: break; } }
/* Pseudo strategy function * Called by scsipi_do_ioctl() via physio/physstrat if there is to * be data transfered, and directly if there is no data transfer. * * Should I reorganize this so it returns to physio instead * of sleeping in scsiio_scsipi_cmd? Is there any advantage, other * than avoiding the probable duplicate wakeup in iodone? [PD] * * No, seems ok to me... [JRE] * (I don't see any duplicate wakeups) * * Can't be used with block devices or raw_read/raw_write directly * from the cdevsw/bdevsw tables because they couldn't have added * the screq structure. [JRE] */ static void scsistrategy(struct buf *bp) { struct scsi_ioctl *si; scsireq_t *screq; struct scsipi_periph *periph; int error; int flags = 0; si = si_find(bp); if (si == NULL) { printf("scsistrategy: " "No matching ioctl request found in queue\n"); error = EINVAL; goto done; } screq = &si->si_screq; periph = si->si_periph; SC_DEBUG(periph, SCSIPI_DB2, ("user_strategy\n")); /* * We're in trouble if physio tried to break up the transfer. */ if (bp->b_bcount != screq->datalen) { scsipi_printaddr(periph); printf("physio split the request.. cannot proceed\n"); error = EIO; goto done; } if (screq->timeout == 0) { error = EINVAL; goto done; } if (screq->cmdlen > sizeof(struct scsipi_generic)) { scsipi_printaddr(periph); printf("cmdlen too big\n"); error = EFAULT; goto done; } if ((screq->flags & SCCMD_READ) && screq->datalen > 0) flags |= XS_CTL_DATA_IN; if ((screq->flags & SCCMD_WRITE) && screq->datalen > 0) flags |= XS_CTL_DATA_OUT; if (screq->flags & SCCMD_TARGET) flags |= XS_CTL_TARGET; if (screq->flags & SCCMD_ESCAPE) flags |= XS_CTL_ESCAPE; error = scsipi_command(periph, (void *)screq->cmd, screq->cmdlen, (void *)bp->b_data, screq->datalen, 0, /* user must do the retries *//* ignored */ screq->timeout, bp, flags | XS_CTL_USERCMD); done: if (error) bp->b_resid = bp->b_bcount; bp->b_error = error; biodone(bp); return; }
/* * We let the user interpret his own sense in the generic scsi world. * This routine is called at interrupt time if the XS_CTL_USERCMD bit was set * in the flags passed to scsi_scsipi_cmd(). No other completion processing * takes place, even if we are running over another device driver. * The lower level routines that call us here, will free the xs and restart * the device's queue if such exists. */ void scsipi_user_done(struct scsipi_xfer *xs) { struct buf *bp; struct scsi_ioctl *si; scsireq_t *screq; struct scsipi_periph *periph = xs->xs_periph; int s; bp = xs->bp; #ifdef DIAGNOSTIC if (bp == NULL) { scsipi_printaddr(periph); printf("user command with no buf\n"); panic("scsipi_user_done"); } #endif si = si_find(bp); #ifdef DIAGNOSTIC if (si == NULL) { scsipi_printaddr(periph); printf("user command with no ioctl\n"); panic("scsipi_user_done"); } #endif screq = &si->si_screq; SC_DEBUG(xs->xs_periph, SCSIPI_DB2, ("user-done\n")); screq->retsts = 0; screq->status = xs->status; switch (xs->error) { case XS_NOERROR: SC_DEBUG(periph, SCSIPI_DB3, ("no error\n")); screq->datalen_used = xs->datalen - xs->resid; /* probably rubbish */ screq->retsts = SCCMD_OK; break; case XS_SENSE: SC_DEBUG(periph, SCSIPI_DB3, ("have sense\n")); screq->senselen_used = min(sizeof(xs->sense.scsi_sense), SENSEBUFLEN); memcpy(screq->sense, &xs->sense.scsi_sense, screq->senselen); screq->retsts = SCCMD_SENSE; break; case XS_SHORTSENSE: SC_DEBUG(periph, SCSIPI_DB3, ("have short sense\n")); screq->senselen_used = min(sizeof(xs->sense.atapi_sense), SENSEBUFLEN); memcpy(screq->sense, &xs->sense.scsi_sense, screq->senselen); screq->retsts = SCCMD_UNKNOWN; /* XXX need a shortsense here */ break; case XS_DRIVER_STUFFUP: scsipi_printaddr(periph); printf("passthrough: adapter inconsistency\n"); screq->retsts = SCCMD_UNKNOWN; break; case XS_SELTIMEOUT: SC_DEBUG(periph, SCSIPI_DB3, ("seltimeout\n")); screq->retsts = SCCMD_TIMEOUT; break; case XS_TIMEOUT: SC_DEBUG(periph, SCSIPI_DB3, ("timeout\n")); screq->retsts = SCCMD_TIMEOUT; break; case XS_BUSY: SC_DEBUG(periph, SCSIPI_DB3, ("busy\n")); screq->retsts = SCCMD_BUSY; break; default: scsipi_printaddr(periph); printf("unknown error category %d from adapter\n", xs->error); screq->retsts = SCCMD_UNKNOWN; break; } if (xs->xs_control & XS_CTL_ASYNC) { s = splbio(); scsipi_put_xs(xs); splx(s); } }