On Fri, 2010-06-18 at 03:19 +0300, Maxim Levitsky wrote: > Hi, > This is the patch implementing the detection in clean way. > Note that I call it smartmedia because xD is direct succesor of > smartmedia and other that different card package is equivalent to it. > ping > --- > > > commit 2599cabd36770785a13bf884049d649d385fd80c > Author: Maxim Levitsky <maximlevitsky@xxxxxxxxx> > Date: Fri Jun 18 02:08:48 2010 +0300 > > Add autodetection for xD/smartmedia cards > This can easily be extended for other types of FTL > Signed-off-by: Maxim Levitsky <maximlevitsky@xxxxxxxxx> > > diff --git a/Makefile.am b/Makefile.am > index bafe4c7..5e9234a 100644 > --- a/Makefile.am > +++ b/Makefile.am > @@ -467,6 +467,21 @@ dist_udevrules_DATA += \ > libexec_PROGRAMS += extras/mobile-action-modeswitch/mobile-action-modeswitch > > # ------------------------------------------------------------------------------ > +# mtd_probe - autoloads FTL module for mtd devices > +# ------------------------------------------------------------------------------ > +extras_mtd_probe_mtd_probe_SOURCES = \ > + extras/mtd_probe/mtd_probe.c \ > + extras/mtd_probe/mtd_probe.h \ > + extras/mtd_probe/probe_smartmedia.c > + > +extras_mtd_probe_mtd_probe_CPPFLAGS = $(AM_CPPFLAGS) > + > +dist_udevrules_DATA += extras/mtd_probe/75-probe_mtd.rules > + > +libexec_PROGRAMS += extras/mtd_probe/mtd_probe > + > + > +# ------------------------------------------------------------------------------ > # keymap - map custom hardware's multimedia keys > # ------------------------------------------------------------------------------ > extras_keymap_keymap_SOURCES = extras/keymap/keymap.c > diff --git a/extras/mtd_probe/75-probe_mtd.rules b/extras/mtd_probe/75-probe_mtd.rules > new file mode 100644 > index 0000000..1d1b398 > --- /dev/null > +++ b/extras/mtd_probe/75-probe_mtd.rules > @@ -0,0 +1,10 @@ > +#probe mtd devices for FTL > + > +ACTION!="add", GOTO="mtd_probe_end" > + > +KERNEL=="mtd*ro", IMPORT{program}="mtd_probe $tempnode" > +KERNEL=="mtd*ro", ENV{MTD_FTL}=="smartmedia", RUN+="/sbin/modprobe sm_ftl" > + > + > +LABEL="mtd_probe_end" > + > diff --git a/extras/mtd_probe/mtd_probe.c b/extras/mtd_probe/mtd_probe.c > new file mode 100644 > index 0000000..d335b06 > --- /dev/null > +++ b/extras/mtd_probe/mtd_probe.c > @@ -0,0 +1,54 @@ > +/* > + * mtd_probe.c > + * This file is part of mtd_probe > + * > + * Copyright (C) 2010 - Maxim Levitsky > + * > + * mtd_probe is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License as published by > + * the Free Software Foundation; either version 2 of the License, or > + * (at your option) any later version. > + * > + * mtd_probe is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + * > + * You should have received a copy of the GNU General Public License > + * along with mtd_probe; if not, write to the Free Software > + * Foundation, Inc., 51 Franklin St, Fifth Floor, > + * Boston, MA 02110-1301 USA > + */ > +#include "mtd_probe.h" > +#include <stdio.h> > +#include <sys/ioctl.h> > +#include <mtd/mtd-user.h> > +#include <sys/types.h> > +#include <sys/stat.h> > +#include <fcntl.h> > +#include <unistd.h> > +#include <stdlib.h> > + > +int main(int argc, char** argv) { > + > + if (argc != 2) { > + printf("usage: mtd_probe /dev/mtd[n]\n"); > + return 1; > + } > + > + int mtd_fd = open(argv[1], O_RDONLY); > + if (mtd_fd == -1) { > + perror("open"); > + exit(-1); > + } > + > + mtd_info_t mtd_info; > + int error = ioctl(mtd_fd, MEMGETINFO, &mtd_info); > + if (error == -1) { > + perror("ioctl"); > + exit(-1); > + } > + > + probe_smart_media(mtd_fd, &mtd_info); > + return -1; > +} > diff --git a/extras/mtd_probe/mtd_probe.h b/extras/mtd_probe/mtd_probe.h > new file mode 100644 > index 0000000..845a7a1 > --- /dev/null > +++ b/extras/mtd_probe/mtd_probe.h > @@ -0,0 +1,51 @@ > +/* > + * mtd_probe.h > + * This file is part of mtd_probe > + * > + * Copyright (C) 2010 - Maxim Levitsky > + * > + * mtd_probe is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License as published by > + * the Free Software Foundation; either version 2 of the License, or > + * (at your option) any later version. > + * > + * mtd_probe is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + * > + * You should have received a copy of the GNU General Public License > + * along with mtd_probe; if not, write to the Free Software > + * Foundation, Inc., 51 Franklin St, Fifth Floor, > + * Boston, MA 02110-1301 USA > + */ > +#include <mtd/mtd-user.h> > + > +/* Full oob structure as written on the flash */ > +struct sm_oob { > + uint32_t reserved; > + uint8_t data_status; > + uint8_t block_status; > + uint8_t lba_copy1[2]; > + uint8_t ecc2[3]; > + uint8_t lba_copy2[2]; > + uint8_t ecc1[3]; > +} __attribute__((packed)); > + > + > +/* one sector is always 512 bytes, but it can consist of two nand pages */ > +#define SM_SECTOR_SIZE 512 > + > +/* oob area is also 16 bytes, but might be from two pages */ > +#define SM_OOB_SIZE 16 > + > +/* This is maximum zone size, and all devices that have more that one zone > + have this size */ > +#define SM_MAX_ZONE_SIZE 1024 > + > +/* support for small page nand */ > +#define SM_SMALL_PAGE 256 > +#define SM_SMALL_OOB_SIZE 8 > + > + > +void probe_smart_media(int mtd_fd, mtd_info_t *info); > diff --git a/extras/mtd_probe/probe_smartmedia.c b/extras/mtd_probe/probe_smartmedia.c > new file mode 100644 > index 0000000..ab6edea > --- /dev/null > +++ b/extras/mtd_probe/probe_smartmedia.c > @@ -0,0 +1,99 @@ > +/* > + * probe_smartmedia.c > + * This file is part of mtd_probe > + * > + * Copyright (C) 2010 - Maxim Levitsky > + * > + * mtd_probe is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License as published by > + * the Free Software Foundation; either version 2 of the License, or > + * (at your option) any later version. > + * > + * mtd_probe is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + * > + * You should have received a copy of the GNU General Public License > + * along with mtd_probe; if not, write to the Free Software > + * Foundation, Inc., 51 Franklin St, Fifth Floor, > + * Boston, MA 02110-1301 USA > + */ > + > +#include <stdio.h> > +#include <stdlib.h> > +#include <mtd/mtd-user.h> > + > +#include <sys/types.h> > +#include <sys/stat.h> > +#include <fcntl.h> > +#include <unistd.h> > +#include <stdint.h> > +#include <stdlib.h> > +#include "mtd_probe.h" > + > +static const uint8_t cis_signature[] = { > + 0x01, 0x03, 0xD9, 0x01, 0xFF, 0x18, 0x02, 0xDF, 0x01, 0x20 > +}; > + > + > +void probe_smart_media(int mtd_fd, mtd_info_t* info) { > + > + char* cis_buffer = malloc(SM_SECTOR_SIZE); > + if (!cis_buffer) > + return; > + > + if (info->type != MTD_NANDFLASH) > + goto exit; > + > + int sector_size = info->writesize; > + int block_size = info->erasesize; > + int size_in_megs = info->size / (1024 * 1024); > + int spare_count; > + > + > + if (sector_size != SM_SECTOR_SIZE && sector_size != SM_SMALL_PAGE) > + goto exit; > + > + switch(size_in_megs) { > + case 1: > + case 2: > + spare_count = 6; > + break; > + case 4: > + spare_count = 12; > + break; > + default: > + spare_count = 24; > + break; > + } > + > + > + int offset; > + int cis_found = 0; > + > + for (offset = 0 ; offset < block_size * spare_count ; > + offset += sector_size) { > + > + lseek(mtd_fd, SEEK_SET, offset); > + if (read(mtd_fd, cis_buffer, SM_SECTOR_SIZE) == SM_SECTOR_SIZE){ > + cis_found = 1; > + break; > + } > + } > + > + if (!cis_found) > + goto exit; > + > + if (memcmp(cis_buffer, cis_signature, sizeof(cis_signature)) != 0 && > + (memcmp(cis_buffer + SM_SMALL_PAGE, cis_signature, > + sizeof(cis_signature)) != 0)) > + goto exit; > + > + printf("MTD_FTL=smartmedia\n"); > + free(cis_buffer); > + exit(0); > +exit: > + free(cis_buffer); > + return; > +} > > -- To unsubscribe from this list: send the line "unsubscribe linux-hotplug" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html