1/*
2 * volume_id - reads filesystem label and uuid
3 *
4 * Copyright (C) 2005 Kay Sievers <kay.sievers@vrfy.org>
5 *
6 *	This program is free software; you can redistribute it and/or modify it
7 *	under the terms of the GNU General Public License as published by the
8 *	Free Software Foundation version 2 of the License.
9 */
10
11#ifndef _GNU_SOURCE
12#define _GNU_SOURCE 1
13#endif
14
15#ifdef HAVE_CONFIG_H
16#  include <config.h>
17#endif
18
19#include <stdio.h>
20#include <stdlib.h>
21#include <unistd.h>
22#include <string.h>
23#include <errno.h>
24#include <ctype.h>
25
26#include "libvolume_id.h"
27#include "util.h"
28
29struct promise_meta {
30	uint8_t	sig[24];
31} PACKED;
32
33#define PDC_CONFIG_OFF		0x1200
34#define PDC_SIGNATURE		"Promise Technology, Inc."
35
36int volume_id_probe_promise_fasttrack_raid(struct volume_id *id, uint64_t off, uint64_t size)
37{
38	const uint8_t *buf;
39	struct promise_meta *pdc;
40	unsigned int i;
41	static unsigned int sectors[] = {
42		63, 255, 256, 16, 399, 0
43	};
44
45	info("probing at offset 0x%llx, size 0x%llx",
46	    (unsigned long long) off, (unsigned long long) size);
47
48	if (size < 0x40000)
49		return -1;
50
51	for (i = 0; sectors[i] != 0; i++) {
52		uint64_t meta_off;
53
54		meta_off = ((size / 0x200) - sectors[i]) * 0x200;
55		buf = volume_id_get_buffer(id, off + meta_off, 0x200);
56		if (buf == NULL)
57			return -1;
58
59		pdc = (struct promise_meta *) buf;
60		if (memcmp(pdc->sig, PDC_SIGNATURE, sizeof(PDC_SIGNATURE)-1) == 0)
61			goto found;
62	}
63	return -1;
64
65found:
66	volume_id_set_usage(id, VOLUME_ID_RAID);
67	id->type = "promise_fasttrack_raid_member";
68
69	return 0;
70}
71