Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00045 #include <cfg/os.h>
00046 #include <cfg/memory.h>
00047
00048 #include <dev/blockdev.h>
00049 #include <sys/nutdebug.h>
00050 #include <fs/fs.h>
00051
00052 #include <stdlib.h>
00053 #include <errno.h>
00054 #include <memdebug.h>
00055
00059 typedef struct _BLOCKVOLUME BLOCKVOLUME;
00060
00064 struct _BLOCKVOLUME {
00067 NUTDEVICE *vol_fsdev;
00068
00071 uint32_t vol_blk_cnt;
00072
00075 int vol_blk_len;
00076
00079 uint32_t vol_blk_off;
00080
00088 uint32_t vol_blk_num;
00089
00099 uint8_t *vol_blk_buf;
00100 };
00101
00109 static NUTDEVICE *NutDeviceLookupType(uint_fast8_t type)
00110 {
00111 NUTDEVICE *dev;
00112
00113 for (dev = nutDeviceList; dev; dev = dev->dev_next) {
00114 if (dev->dev_type == type) {
00115 break;
00116 }
00117 }
00118 return dev;
00119 }
00120
00131 int NutBlockDeviceInit(NUTDEVICE * dev)
00132 {
00133 NUTASSERT(dev != NULL);
00134
00135 return 0;
00136 }
00137
00163 NUTFILE *NutBlockDeviceOpen(NUTDEVICE * dev, CONST char *name, int mode, int acc)
00164 {
00165 NUTDEVICE *fsdev;
00166
00167
00168 NUTASSERT(name != NULL);
00169 if (*name) {
00170 do {
00171 name++;
00172 } while (*name && *name != '/');
00173 if (*name == '/') {
00174 name++;
00175 }
00176 }
00177
00178
00179
00180
00181
00182
00183
00184 if (*name) {
00185 fsdev = NutDeviceLookup(name);
00186 } else {
00187 fsdev = NutDeviceLookupType(IFTYP_FS);
00188 }
00189
00190 if (fsdev == NULL) {
00191 errno = ENODEV;
00192 } else {
00193 BLOCKVOLUME *fcb = malloc(sizeof(BLOCKVOLUME));
00194
00195 if (fcb) {
00196 NUTBLOCKIO *blkio;
00197
00198 NUTASSERT(dev != NULL);
00199
00200 blkio = (NUTBLOCKIO *) (dev->dev_dcb);
00201 NUTASSERT(blkio != NULL);
00202
00203 fcb->vol_fsdev = fsdev;
00204 fcb->vol_blk_off = blkio->blkio_vol_bot;
00205 fcb->vol_blk_cnt = blkio->blkio_blk_cnt - blkio->blkio_vol_bot - blkio->blkio_vol_top;
00206 fcb->vol_blk_num = 0;
00207 fcb->vol_blk_len = blkio->blkio_blk_siz;
00208 fcb->vol_blk_buf = malloc(fcb->vol_blk_len);
00209 if (fcb->vol_blk_buf) {
00210 NUTFILE *nfp = malloc(sizeof(NUTFILE));
00211
00212 if (nfp) {
00213 FSCP_VOL_MOUNT mparm;
00214
00215 nfp->nf_next = NULL;
00216 nfp->nf_dev = dev;
00217 nfp->nf_fcb = fcb;
00218
00219 mparm.fscp_bmnt = nfp;
00220 mparm.fscp_part_type = 0;
00221 if (fsdev->dev_ioctl(fsdev, FS_VOL_MOUNT, &mparm) == 0) {
00222
00223 return nfp;
00224 }
00225 free(nfp);
00226 }
00227 }
00228 free(fcb);
00229 }
00230 }
00231 return NUTFILE_EOF;
00232 }
00233
00241 int NutBlockDeviceClose(NUTFILE * nfp)
00242 {
00243 int rc = -1;
00244 BLOCKVOLUME *fcb;
00245
00246 NUTASSERT(nfp != NULL);
00247 fcb = (BLOCKVOLUME *) nfp->nf_fcb;
00248 if (fcb) {
00249 NUTASSERT(fcb->vol_fsdev != NULL);
00250 NUTASSERT(fcb->vol_fsdev->dev_ioctl != NULL);
00251 rc = fcb->vol_fsdev->dev_ioctl(fcb->vol_fsdev, FS_VOL_UNMOUNT, NULL);
00252 free(fcb);
00253 }
00254 free(nfp);
00255
00256 return rc;
00257 }
00258
00280 int NutBlockDeviceIOCtl(NUTDEVICE * dev, int req, void *conf)
00281 {
00282 int rc = 0;
00283
00284 switch (req) {
00285 case NUTBLKDEV_SEEK:
00286 {
00287 BLKPAR_SEEK *par = (BLKPAR_SEEK *) conf;
00288 BLOCKVOLUME *fcb;
00289
00290
00291 NUTASSERT(conf != NULL);
00292 NUTASSERT(par->par_nfp != NULL);
00293 NUTASSERT(par->par_nfp->nf_fcb != NULL);
00294
00295 fcb = (BLOCKVOLUME *) par->par_nfp->nf_fcb;
00296 fcb->vol_blk_num = par->par_blknum;
00297 }
00298 break;
00299 case NUTBLKDEV_INFO:
00300 {
00301 BLKPAR_INFO *par;
00302 BLOCKVOLUME *fcb;
00303
00304 NUTASSERT(conf != NULL);
00305 par = (BLKPAR_INFO *) conf;
00306 NUTASSERT(par->par_nfp != NULL);
00307 NUTASSERT(par->par_nfp->nf_fcb != NULL);
00308 fcb = (BLOCKVOLUME *) par->par_nfp->nf_fcb;
00309
00310 par->par_nblks = fcb->vol_blk_cnt;
00311 par->par_blksz = fcb->vol_blk_len;
00312 par->par_blkbp = fcb->vol_blk_buf;
00313 }
00314 break;
00315 default:
00316 {
00317 NUTBLOCKIO *blkio;
00318
00319 NUTASSERT(dev != NULL);
00320 NUTASSERT(dev->dev_dcb != NULL);
00321 blkio = (NUTBLOCKIO *) (dev->dev_dcb);
00322
00323 NUTASSERT(blkio->blkio_ioctl != NULL);
00324 rc = blkio->blkio_ioctl(dev, req, conf);
00325 }
00326 break;
00327 }
00328 return rc;
00329 }
00330
00348 int NutBlockDeviceRead(NUTFILE * nfp, void *buffer, int num)
00349 {
00350 int rc;
00351 int cnt;
00352 uint8_t *bp = buffer;
00353 NUTBLOCKIO *blkio;
00354 BLOCKVOLUME *fcb;
00355
00356
00357 if (num == 0) {
00358 return 0;
00359 }
00360 NUTASSERT(buffer != NULL);
00361 NUTASSERT(nfp != NULL);
00362 NUTASSERT(nfp->nf_fcb != NULL);
00363 NUTASSERT(nfp->nf_dev != NULL);
00364 NUTASSERT(nfp->nf_dev->dev_dcb != NULL);
00365
00366 blkio = nfp->nf_dev->dev_dcb;
00367 fcb = (BLOCKVOLUME *) nfp->nf_fcb;
00368 NUTASSERT(blkio->blkio_read != NULL);
00369
00370 for (rc = 0; rc < num; rc++) {
00371 if (fcb->vol_blk_num >= fcb->vol_blk_cnt) {
00372 break;
00373 }
00374 cnt = (*blkio->blkio_read) (nfp->nf_dev, fcb->vol_blk_num + fcb->vol_blk_off, bp, fcb->vol_blk_len);
00375 if (cnt != fcb->vol_blk_len) {
00376 break;
00377 }
00378 fcb->vol_blk_num++;
00379 bp += fcb->vol_blk_len;
00380 }
00381 return rc ? rc : -1;
00382 }
00383
00400 int NutBlockDeviceWrite(NUTFILE * nfp, CONST void *buffer, int num)
00401 {
00402 int rc;
00403 int cnt;
00404 CONST uint8_t *bp = buffer;
00405 NUTBLOCKIO *blkio;
00406 BLOCKVOLUME *fcb;
00407
00408
00409 if (num == 0) {
00410 return 0;
00411 }
00412 NUTASSERT(nfp != NULL);
00413 NUTASSERT(nfp->nf_fcb != NULL);
00414 NUTASSERT(nfp->nf_dev != NULL);
00415 NUTASSERT(nfp->nf_dev->dev_dcb != NULL);
00416
00417 fcb = (BLOCKVOLUME *) nfp->nf_fcb;
00418 blkio = nfp->nf_dev->dev_dcb;
00419 NUTASSERT(blkio->blkio_write != NULL);
00420
00421 for (rc = 0; rc < num; rc++) {
00422 if (fcb->vol_blk_num >= fcb->vol_blk_cnt) {
00423 break;
00424 }
00425 cnt = (*blkio->blkio_write) (nfp->nf_dev, fcb->vol_blk_num + fcb->vol_blk_off, bp, fcb->vol_blk_len);
00426 if (cnt != fcb->vol_blk_len) {
00427 break;
00428 }
00429 fcb->vol_blk_num++;
00430 bp += fcb->vol_blk_len;
00431 }
00432 return rc ? rc : -1;
00433 }
00434
00435 #ifdef __HARVARD_ARCH__
00436
00452 int NutBlockDeviceWrite_P(NUTFILE * nfp, PGM_P buffer, int num)
00453 {
00454 int rc = 0;
00455 int cnt;
00456 PGM_P bp = buffer;
00457 NUTBLOCKIO *blkio;
00458 BLOCKVOLUME *fcb;
00459
00460
00461 if (num == 0) {
00462 return 0;
00463 }
00464 NUTASSERT(nfp != NULL);
00465 NUTASSERT(nfp->nf_fcb != NULL);
00466 NUTASSERT(nfp->nf_dev != NULL);
00467 NUTASSERT(nfp->nf_dev->dev_dcb != NULL);
00468
00469 fcb = (BLOCKVOLUME *) nfp->nf_fcb;
00470 blkio = nfp->nf_dev->dev_dcb;
00471 NUTASSERT(blkio->blkio_write != NULL);
00472
00473 for (rc = 0; rc < num; rc++) {
00474 if (fcb->vol_blk_num >= fcb->vol_blk_cnt) {
00475 break;
00476 }
00477 cnt = (*blkio->blkio_write_P) (nfp->nf_dev, fcb->vol_blk_num + fcb->vol_blk_off, bp, fcb->vol_blk_len);
00478 if (cnt != fcb->vol_blk_len) {
00479 break;
00480 }
00481 fcb->vol_blk_num++;
00482 bp += fcb->vol_blk_len;
00483 }
00484 return rc ? rc : -1;
00485 }
00486 #endif
00487
00495 long NutBlockDeviceSize(NUTFILE * nfp)
00496 {
00497 BLOCKVOLUME *fcb;
00498
00499 NUTASSERT(nfp != NULL);
00500 fcb = (BLOCKVOLUME *) nfp->nf_fcb;
00501 NUTASSERT(fcb != NULL);
00502
00503 return (long) fcb->vol_blk_cnt * (long) fcb->vol_blk_len;
00504 }