ibm.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:5k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * File...........: linux/fs/partitions/ibm.c      
  3.  * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com>
  4.  *                  Volker Sameske <sameske@de.ibm.com>
  5.  * Bugreports.to..: <Linux390@de.ibm.com>
  6.  * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
  7.  * History of changes (starts July 2000)
  8.  * 07/10/00 Fixed detection of CMS formatted disks     
  9.  * 02/13/00 VTOC partition support added
  10.  */
  11. #include <linux/config.h>
  12. #include <linux/fs.h>
  13. #include <linux/genhd.h>
  14. #include <linux/kernel.h>
  15. #include <linux/major.h>
  16. #include <linux/string.h>
  17. #include <linux/blk.h>
  18. #include <linux/slab.h>
  19. #include <linux/hdreg.h>
  20. #include <linux/ioctl.h>
  21. #include <linux/version.h>
  22. #include <asm/ebcdic.h>
  23. #include <asm/uaccess.h>
  24. #include <asm/dasd.h>
  25. #include "ibm.h"
  26. #include "check.h"
  27. #include <asm/vtoc.h>
  28. typedef enum {
  29.   ibm_partition_lnx1 = 0,
  30.   ibm_partition_vol1 = 1,
  31.   ibm_partition_cms1 = 2,
  32.   ibm_partition_none = 3
  33. } ibm_partition_t;
  34. static char* part_names[] = {   [ibm_partition_lnx1] = "LNX1",
  35.      [ibm_partition_vol1] = "VOL1",
  36.      [ibm_partition_cms1] = "CMS1",
  37.      [ibm_partition_none] = "(nonl)"
  38. };
  39. static ibm_partition_t
  40. get_partition_type ( char * type )
  41. {
  42. int i;
  43. for ( i = 0; i < 3; i ++) {
  44. if ( ! strncmp (type,part_names[i],4) ) 
  45. break;
  46. }
  47.         return i;
  48. }
  49. /*
  50.  * add the two default partitions
  51.  * - whole dasd
  52.  * - whole dasd without "offset"
  53.  */
  54. static inline void
  55. two_partitions(struct gendisk *hd,
  56.        int minor,
  57.        int blocksize,
  58.        int offset,
  59.        int size) {
  60.         add_gd_partition( hd, minor, 0, size);
  61. add_gd_partition( hd, minor+1, offset*blocksize, size-offset*blocksize);
  62. }
  63. /*
  64.  * compute the block number from a 
  65.  * cyl-cyl-head-head structure
  66.  */
  67. static inline int
  68. cchh2blk (cchh_t *ptr, struct hd_geometry *geo) {
  69.         return ptr->cc * geo->heads * geo->sectors +
  70.        ptr->hh * geo->sectors;
  71. }
  72. /*
  73.  * compute the block number from a 
  74.  * cyl-cyl-head-head-block structure
  75.  */
  76. static inline int
  77. cchhb2blk (cchhb_t *ptr, struct hd_geometry *geo) {
  78.         return ptr->cc * geo->heads * geo->sectors +
  79. ptr->hh * geo->sectors +
  80. ptr->b;
  81. }
  82. int 
  83. ibm_partition(struct gendisk *hd, struct block_device *bdev,
  84. unsigned long first_sector, int first_part_minor)
  85. {
  86. Sector sect, sect2;
  87. unsigned char *data;
  88. ibm_partition_t partition_type;
  89. char type[5] = {0,};
  90. char name[7] = {0,};
  91. struct hd_geometry *geo;
  92. int blocksize;
  93. int offset=0, size=0, psize=0, counter=0;
  94. unsigned int blk;
  95. format1_label_t f1;
  96. volume_label_t vlabel;
  97. dasd_information_t *info;
  98. kdev_t dev = to_kdev_t(bdev->bd_dev);
  99. if ( first_sector != 0 )
  100. BUG();
  101. info = (struct dasd_information_t *)kmalloc(sizeof(dasd_information_t),
  102.     GFP_KERNEL);
  103. if ( info == NULL )
  104. return 0;
  105. if (ioctl_by_bdev(bdev, BIODASDINFO, (unsigned long)(info)))
  106. return 0;
  107. geo = (struct hd_geometry *)kmalloc(sizeof(struct hd_geometry),
  108.     GFP_KERNEL);
  109. if ( geo == NULL )
  110. return 0;
  111. if (ioctl_by_bdev(bdev, HDIO_GETGEO, (unsigned long)geo);
  112. return 0;
  113. blocksize = hardsect_size[MAJOR(dev)][MINOR(dev)];
  114. if ( blocksize <= 0 ) {
  115. return 0;
  116. }
  117. blocksize >>= 9;
  118. data = read_dev_sector(bdev, inode->label_block*blocksize, &sect);
  119. if (!data)
  120. return 0;
  121. strncpy (type, data, 4);
  122. if ((!info->FBA_layout) && (!strcmp(info->type,"ECKD"))) {
  123. strncpy ( name, data + 8, 6);
  124. } else {
  125. strncpy ( name, data + 4, 6);
  126. }
  127. memcpy (&vlabel, data, sizeof(volume_label_t));
  128. EBCASC(type,4);
  129. EBCASC(name,6);
  130. partition_type = get_partition_type(type);
  131. printk ( "%4s/%8s:",part_names[partition_type],name);
  132. switch ( partition_type ) {
  133. case ibm_partition_cms1:
  134. if (* ((long *)data + 13) != 0) {
  135. /* disk is reserved minidisk */
  136. long *label=(long*)data;
  137. blocksize = label[3]>>9;
  138. offset = label[13];
  139. size = (label[7]-1)*blocksize; 
  140. printk ("(MDSK)");
  141. } else {
  142. offset = (info->label_block + 1);
  143. size = hd -> sizes[MINOR(dev)]<<1;
  144. }
  145. two_partitions( hd, MINOR(dev), blocksize, offset, size);
  146. break;
  147. case ibm_partition_lnx1: 
  148. case ibm_partition_none:
  149. offset = (info->label_block + 1);
  150. size = hd -> sizes[MINOR(dev)]<<1;
  151. two_partitions( hd, MINOR(dev), blocksize, offset, size);
  152. break;
  153. case ibm_partition_vol1: 
  154. size = hd -> sizes[MINOR(dev)]<<1;
  155. add_gd_partition(hd, MINOR(dev), 0, size);
  156. /* get block number and read then first format1 label */
  157. blk = cchhb2blk(&vlabel.vtoc, geo) + 1;
  158. data = read_dev_sector(bdev, blk * blocksize, &sect2);
  159. if (data) {
  160.         memcpy (&f1, data, sizeof(format1_label_t));
  161. put_dev_sector(sect2);
  162. }
  163. while (f1.DS1FMTID == _ascebc['1']) {
  164.         offset = cchh2blk(&f1.DS1EXT1.llimit, geo);
  165. psize  = cchh2blk(&f1.DS1EXT1.ulimit, geo) - 
  166. offset + geo->sectors;
  167. counter++;
  168. add_gd_partition(hd, MINOR(dev) + counter, 
  169.  offset * blocksize,
  170.  psize * blocksize);
  171. blk++;
  172. data = read_dev_sector(bdev, blk * blocksize, &sect2);
  173. if (data) {
  174.         memcpy (&f1, data, sizeof(format1_label_t));
  175. put_dev_sector(sect2);
  176. }
  177. }
  178. break;
  179. default:
  180. add_gd_partition( hd, MINOR(dev), 0, 0);
  181. add_gd_partition( hd, MINOR(dev) + 1, 0, 0);
  182. }
  183. printk ( "n" );
  184. put_dev_sector(sect);
  185. return 1;
  186. }