/* * blkif.c * * The blkif interface for blktap. A blkif describes an in-use virtual disk. */ #include #include #include #include #include #include "blktaplib.h" #if 1 #define DPRINTF(_f, _a...) printf ( _f , ## _a ) #else #define DPRINTF(_f, _a...) ((void)0) #endif #define BLKIF_HASHSZ 1024 #define BLKIF_HASH(_d,_h) (((int)(_d)^(int)(_h))&(BLKIF_HASHSZ-1)) static blkif_t *blkif_hash[BLKIF_HASHSZ]; blkif_t *blkif_find_by_handle(domid_t domid, unsigned int handle) { blkif_t *blkif = blkif_hash[BLKIF_HASH(domid, handle)]; while ( (blkif != NULL) && ((blkif->domid != domid) || (blkif->handle != handle)) ) blkif = blkif->hash_next; return blkif; } blkif_t *alloc_blkif(domid_t domid) { blkif_t *blkif; blkif = (blkif_t *)malloc(sizeof(blkif_t)); if (!blkif) return NULL; memset(blkif, 0, sizeof(*blkif)); blkif->domid = domid; return blkif; } static int (*new_blkif_hook)(blkif_t *blkif) = NULL; void register_new_blkif_hook(int (*fn)(blkif_t *blkif)) { new_blkif_hook = fn; } int blkif_init(blkif_t *blkif, long int handle, long int pdev, long int readonly) { domid_t domid; blkif_t **pblkif; if (blkif == NULL) return -EINVAL; domid = blkif->domid; blkif->handle = handle; blkif->pdev = pdev; blkif->readonly = readonly; /* * Call out to the new_blkif_hook. The tap application should define this, * and it should return having set blkif->ops * */ if (new_blkif_hook == NULL) { warn("Probe detected a new blkif, but no new_blkif_hook!"); return -1; } new_blkif_hook(blkif); /* Now wire it in. */ pblkif = &blkif_hash[BLKIF_HASH(domid, handle)]; while ( *pblkif != NULL ) { if ( ((*pblkif)->domid == domid) && ((*pblkif)->handle == handle) ) { DPRINTF("Could not create blkif: already exists\n"); return -1; } pblkif = &(*pblkif)->hash_next; } blkif->hash_next = NULL; *pblkif = blkif; return 0; } void free_blkif(blkif_t *blkif) { blkif_t **pblkif, *curs; pblkif = &blkif_hash[BLKIF_HASH(blkif->domid, blkif->handle)]; while ( (curs = *pblkif) != NULL ) { if ( blkif == curs ) { *pblkif = curs->hash_next; } pblkif = &curs->hash_next; } if (blkif != NULL) free(blkif); } void blkif_register_request_hook(blkif_t *blkif, char *name, int (*rh)(blkif_t *, blkif_request_t *, int)) { request_hook_t *rh_ent, **c; rh_ent = (request_hook_t *)malloc(sizeof(request_hook_t)); if (!rh_ent) { warn("couldn't allocate a new hook"); return; } rh_ent->func = rh; rh_ent->next = NULL; if (asprintf(&rh_ent->name, "%s", name) == -1) { free(rh_ent); warn("couldn't allocate a new hook name"); return; } c = &blkif->request_hook_chain; while (*c != NULL) { c = &(*c)->next; } *c = rh_ent; } void blkif_register_response_hook(blkif_t *blkif, char *name, int (*rh)(blkif_t *, blkif_response_t *, int)) { response_hook_t *rh_ent, **c; rh_ent = (response_hook_t *)malloc(sizeof(response_hook_t)); if (!rh_ent) { warn("couldn't allocate a new hook"); return; } rh_ent->func = rh; rh_ent->next = NULL; if (asprintf(&rh_ent->name, "%s", name) == -1) { free(rh_ent); warn("couldn't allocate a new hook name"); return; } c = &blkif->response_hook_chain; while (*c != NULL) { c = &(*c)->next; } *c = rh_ent; } void blkif_print_hooks(blkif_t *blkif) { request_hook_t *req_hook; response_hook_t *rsp_hook; DPRINTF("Request Hooks:\n"); req_hook = blkif->request_hook_chain; while (req_hook != NULL) { DPRINTF(" [0x%p] %s\n", req_hook->func, req_hook->name); req_hook = req_hook->next; } DPRINTF("Response Hooks:\n"); rsp_hook = blkif->response_hook_chain; while (rsp_hook != NULL) { DPRINTF(" [0x%p] %s\n", rsp_hook->func, rsp_hook->name); rsp_hook = rsp_hook->next; } } long int vbd_size(blkif_t *blkif) { return 1000000000; } long int vbd_secsize(blkif_t *blkif) { return 512; } unsigned vbd_info(blkif_t *blkif) { return 0; } void __init_blkif(void) { memset(blkif_hash, 0, sizeof(blkif_hash)); } >37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
/*
    ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

        http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.
*/

#include "ch.h"
#include "hal.h"

#define ADC_GRP1_NUM_CHANNELS   1
#define ADC_GRP1_BUF_DEPTH      8

#define ADC_GRP2_NUM_CHANNELS   4
#define ADC_GRP2_BUF_DEPTH      16

static adcsample_t samples1[ADC_GRP1_NUM_CHANNELS * ADC_GRP1_BUF_DEPTH];
static adcsample_t samples2[ADC_GRP2_NUM_CHANNELS * ADC_GRP2_BUF_DEPTH];

/*
 * ADC streaming callback.
 */
size_t nx = 0, ny = 0;
static void adccallback(ADCDriver *adcp, adcsample_t *buffer, size_t n) {

  (void)adcp;
  if (samples2 == buffer) {
    nx += n;
  }
  else {
    ny += n;
  }
}

static void adcerrorcallback(ADCDriver *adcp, adcerror_t err) {

  (void)adcp;
  (void)err;
}

/*
 * ADC conversion group.
 * Mode:        Linear buffer, 8 samples of 1 channel, SW triggered.
 * Channels:    IN10.
 */
static const ADCConversionGroup adcgrpcfg1 = {
  FALSE,
  ADC_GRP1_NUM_CHANNELS,
  NULL,
  adcerrorcallback,
  ADC_CFGR1_CONT | ADC_CFGR1_RES_12BIT,             /* CFGR1 */
  ADC_TR(0, 0),                                     /* TR */
  ADC_SMPR_SMP_1P5,                                 /* SMPR */
  ADC_CHSELR_CHSEL10                                /* CHSELR */
};

/*
 * ADC conversion group.
 * Mode:        Continuous, 16 samples of 8 channels, SW triggered.
 * Channels:    IN10, IN11, Sensor, VRef.
 */
static const ADCConversionGroup adcgrpcfg2 = {
  TRUE,
  ADC_GRP2_NUM_CHANNELS,
  adccallback,
  adcerrorcallback,
  ADC_CFGR1_CONT | ADC_CFGR1_RES_12BIT,             /* CFGR1 */
  ADC_TR(0, 0),                                     /* TR */
  ADC_SMPR_SMP_28P5,                                /* SMPR */
  ADC_CHSELR_CHSEL10 | ADC_CHSELR_CHSEL11 |
  ADC_CHSELR_CHSEL16 | ADC_CHSELR_CHSEL17           /* CHSELR */
};

/*
 * Red LEDs blinker thread, times are in milliseconds.
 */
static THD_WORKING_AREA(waThread1, 128);
static msg_t Thread1(void *arg) {

  (void)arg;
  chRegSetThreadName("blinker");
  while (TRUE) {
    palSetPad(GPIOC, GPIOC_LED4);
    chThdSleepMilliseconds(500);
    palClearPad(GPIOC, GPIOC_LED4);
    chThdSleepMilliseconds(500);
  }
}

/*
 * Application entry point.
 */
int main(void) {

  /*
   * System initializations.
   * - HAL initialization, this also initializes the configured device drivers
   *   and performs the board-specific initializations.
   * - Kernel initialization, the main() function becomes a thread and the
   *   RTOS is active.
   */
  halInit();
  chSysInit();

  /*
   * Setting up analog inputs used by the demo.
   */
  palSetGroupMode(GPIOC, PAL_PORT_BIT(0) | PAL_PORT_BIT(1),
                  0, PAL_MODE_INPUT_ANALOG);

  /*
   * Creates the blinker thread.
   */
  chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO, Thread1, NULL);

  /*
   * Activates the ADC1 driver and the temperature sensor.
   */
  adcStart(&ADCD1, NULL);
  adcSTM32SetCCR(ADC_CCR_VBATEN | ADC_CCR_TSEN | ADC_CCR_VREFEN);

  /*
   * Linear conversion.
   */
  adcConvert(&ADCD1, &adcgrpcfg1, samples1, ADC_GRP1_BUF_DEPTH);
  chThdSleepMilliseconds(1000);

  /*
   * Starts an ADC continuous conversion.
   */
  adcStartConversion(&ADCD1, &adcgrpcfg2, samples2, ADC_GRP2_BUF_DEPTH);

  /*
   * Normal main() thread activity, in this demo it does nothing.
   */
  while (TRUE) {
    if (palReadPad(GPIOA, GPIOA_BUTTON)) {
      adcStopConversion(&ADCD1);
      adcSTM32SetCCR(0);
    }
    chThdSleepMilliseconds(500);
  }
}