Index: dmraid/1.0.0.rc15/lib/format/ataraid/isw.c =================================================================== --- dmraid.orig/1.0.0.rc15/lib/format/ataraid/isw.c 2009-05-12 09:54:56.000000000 +1000 +++ dmraid/1.0.0.rc15/lib/format/ataraid/isw.c 2009-05-12 09:54:56.000000000 +1000 @@ -307,6 +307,7 @@ enum convert { FULL, FIRST, LAST }; #if BYTE_ORDER == LITTLE_ENDIAN # define to_cpu(x, y) +# define CVT16(x) #else /* * We can differ from the read_raid_dev template here, @@ -503,15 +504,16 @@ } static void * -isw_read_metadata(struct lib_context *lc, struct dev_info *di, - size_t * sz, uint64_t * offset, union read_info *info) +isw_try_sboffset(struct lib_context *lc, struct dev_info *di, + size_t * sz, uint64_t * offset, union read_info *info, + uint64_t const isw_sboffset) { size_t size = ISW_DISK_BLOCK_SIZE; - uint64_t isw_sboffset = ISW_CONFIGOFFSET(di); struct isw *isw; + uint64_t temp_isw_sboffset = isw_sboffset; if (!(isw = alloc_private_and_read(lc, handler, size, - di->path, isw_sboffset))) + di->path, temp_isw_sboffset))) goto out; /* @@ -521,9 +523,15 @@ to_cpu(isw, FIRST); /* Check Signature and read optional extended metadata. */ - if (!is_isw(lc, di, isw) || - !isw_read_extended(lc, di, &isw, &isw_sboffset, &size)) + if (!is_isw(lc, di, isw)) { + log_dbg(lc, "not isw at %ld", isw_sboffset); goto bad; + } + if (!isw_read_extended(lc, di, &isw, &temp_isw_sboffset, &size)) { + log_err(lc, "isw metadata, but extended read failed at %ld", + isw_sboffset); + goto bad; + } /* * Now that we made sure, that we've got all the @@ -534,6 +542,8 @@ if (disk_ok(lc, di, isw)) { *sz = size; *offset = info->u64 = isw_sboffset; + log_dbg(lc, "isw metadata found at %ld from probe at %ld\n", + *offset, isw_sboffset); goto out; } @@ -545,6 +555,51 @@ return (void *) isw; } +/* Observation-engineered data-driven search-for-raid-signature for ICH10R + * option roms. + */ +static void * +isw_try_10(struct lib_context *lc, struct dev_info *di, + size_t * sz, uint64_t * offset, union read_info *info) +{ + struct isw10 *isw10; + void *result = NULL; + uint64_t actual_offset; + if (!(isw10 = alloc_private_and_read(lc, handler, ISW_DISK_BLOCK_SIZE, + di->path, ISW_10_CONFIGOFFSET(di)))) + goto out; + if (strncmp((const char *)isw10->sig, ISW10_SIGNATURE, ISW10_SIGNATURE_SIZE)) + goto out_free; + log_dbg(lc, "Found isw 10 gafr signature."); + CVT16(isw10->offset); + actual_offset = isw10->offset + 2; + log_dbg(lc, "isw 10 sector offset calculated at %hd.", actual_offset); + result = isw_try_sboffset(lc, di, sz, offset, info, + ISW_SECTOR_TO_OFFSET(di->sectors - actual_offset)); + out_free: + dbg_free(isw10); + out: + return result; +} + + +static void * +isw_read_metadata(struct lib_context *lc, struct dev_info *di, + size_t * sz, uint64_t * offset, union read_info *info) +{ + void *result; + if ((result = isw_try_sboffset( + lc, di, sz, offset, info, ISW_CONFIGOFFSET(di)))) + return result; + if ((result = isw_try_10(lc, di, sz, offset, info))) + return result; + log_dbg(lc, "isw trying hard coded -2115 offset."); + if ((result = isw_try_sboffset( + lc, di, sz, offset, info, (di->sectors - 2115)*512))) + return result; + return NULL; +} + static int setup_rd(struct lib_context *lc, struct raid_dev *rd, struct dev_info *di, void *meta, union read_info *info); static struct raid_dev * Index: dmraid/1.0.0.rc15/lib/format/ataraid/isw.h =================================================================== --- dmraid.orig/1.0.0.rc15/lib/format/ataraid/isw.h 2009-05-12 09:55:03.000000000 +1000 +++ dmraid/1.0.0.rc15/lib/format/ataraid/isw.h 2009-05-12 09:55:10.000000000 +1000 @@ -35,8 +35,11 @@ /* Intel metadata offset in bytes */ #define ISW_CONFIGSECTOR(di) ((di)->sectors - 2) -#define ISW_CONFIGOFFSET(di) (ISW_CONFIGSECTOR(di) << 9) +#define ISW_SECTOR_TO_OFFSET(sector) ((sector) << 9) +#define ISW_CONFIGOFFSET(di) (ISW_SECTOR_TO_OFFSET(ISW_CONFIGSECTOR(di))) #define ISW_DATAOFFSET 0 /* Data offset in sectors */ +#define ISW_10_CONFIGSECTOR(di) ((di)->sectors - 1) +#define ISW_10_CONFIGOFFSET(di) (ISW_SECTOR_TO_OFFSET(ISW_10_CONFIGSECTOR(di))) #define MPB_SIGNATURE "Intel Raid ISM Cfg Sig. " #define MPB_SIGNATURE_SIZE (sizeof(MPB_SIGNATURE) - 1) @@ -209,6 +212,14 @@ // here comes isw_dev[num_raid_devs] } __attribute__ ((packed)); +#define ISW10_SIGNATURE "$GAFR\x10" +#define ISW10_SIGNATURE_SIZE (sizeof(ISW10_SIGNATURE) - 1) +struct isw10 { + int8_t sig[ISW10_SIGNATURE_SIZE]; + uint32_t offset; /* offset to real data, in sectors back */ +} __attribute__ ((packed)); + + #endif int register_isw(struct lib_context *lc);