aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/ssfdc.c
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
commit8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch)
treea8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /drivers/mtd/ssfdc.c
parent406089d01562f1e2bf9f089fd7637009ebaad589 (diff)
Patched in Tegra support.
Diffstat (limited to 'drivers/mtd/ssfdc.c')
-rw-r--r--drivers/mtd/ssfdc.c58
1 files changed, 36 insertions, 22 deletions
diff --git a/drivers/mtd/ssfdc.c b/drivers/mtd/ssfdc.c
index ab2a52a039c..5cd18979333 100644
--- a/drivers/mtd/ssfdc.c
+++ b/drivers/mtd/ssfdc.c
@@ -122,9 +122,9 @@ static int get_valid_cis_sector(struct mtd_info *mtd)
122 * is not SSFDC formatted 122 * is not SSFDC formatted
123 */ 123 */
124 for (k = 0, offset = 0; k < 4; k++, offset += mtd->erasesize) { 124 for (k = 0, offset = 0; k < 4; k++, offset += mtd->erasesize) {
125 if (mtd_block_isbad(mtd, offset)) { 125 if (!mtd->block_isbad(mtd, offset)) {
126 ret = mtd_read(mtd, offset, SECTOR_SIZE, &retlen, 126 ret = mtd->read(mtd, offset, SECTOR_SIZE, &retlen,
127 sect_buf); 127 sect_buf);
128 128
129 /* CIS pattern match on the sector buffer */ 129 /* CIS pattern match on the sector buffer */
130 if (ret < 0 || retlen != SECTOR_SIZE) { 130 if (ret < 0 || retlen != SECTOR_SIZE) {
@@ -135,7 +135,8 @@ static int get_valid_cis_sector(struct mtd_info *mtd)
135 /* Found */ 135 /* Found */
136 cis_sector = (int)(offset >> SECTOR_SHIFT); 136 cis_sector = (int)(offset >> SECTOR_SHIFT);
137 } else { 137 } else {
138 pr_debug("SSFDC_RO: CIS/IDI sector not found" 138 DEBUG(MTD_DEBUG_LEVEL1,
139 "SSFDC_RO: CIS/IDI sector not found"
139 " on %s (mtd%d)\n", mtd->name, 140 " on %s (mtd%d)\n", mtd->name,
140 mtd->index); 141 mtd->index);
141 } 142 }
@@ -156,7 +157,7 @@ static int read_physical_sector(struct mtd_info *mtd, uint8_t *sect_buf,
156 size_t retlen; 157 size_t retlen;
157 loff_t offset = (loff_t)sect_no << SECTOR_SHIFT; 158 loff_t offset = (loff_t)sect_no << SECTOR_SHIFT;
158 159
159 ret = mtd_read(mtd, offset, SECTOR_SIZE, &retlen, sect_buf); 160 ret = mtd->read(mtd, offset, SECTOR_SIZE, &retlen, sect_buf);
160 if (ret < 0 || retlen != SECTOR_SIZE) 161 if (ret < 0 || retlen != SECTOR_SIZE)
161 return -1; 162 return -1;
162 163
@@ -169,13 +170,13 @@ static int read_raw_oob(struct mtd_info *mtd, loff_t offs, uint8_t *buf)
169 struct mtd_oob_ops ops; 170 struct mtd_oob_ops ops;
170 int ret; 171 int ret;
171 172
172 ops.mode = MTD_OPS_RAW; 173 ops.mode = MTD_OOB_RAW;
173 ops.ooboffs = 0; 174 ops.ooboffs = 0;
174 ops.ooblen = OOB_SIZE; 175 ops.ooblen = OOB_SIZE;
175 ops.oobbuf = buf; 176 ops.oobbuf = buf;
176 ops.datbuf = NULL; 177 ops.datbuf = NULL;
177 178
178 ret = mtd_read_oob(mtd, offs, &ops); 179 ret = mtd->read_oob(mtd, offs, &ops);
179 if (ret < 0 || ops.oobretlen != OOB_SIZE) 180 if (ret < 0 || ops.oobretlen != OOB_SIZE)
180 return -1; 181 return -1;
181 182
@@ -220,7 +221,8 @@ static int get_logical_address(uint8_t *oob_buf)
220 block_address >>= 1; 221 block_address >>= 1;
221 222
222 if (get_parity(block_address, 10) != parity) { 223 if (get_parity(block_address, 10) != parity) {
223 pr_debug("SSFDC_RO: logical address field%d" 224 DEBUG(MTD_DEBUG_LEVEL0,
225 "SSFDC_RO: logical address field%d"
224 "parity error(0x%04X)\n", j+1, 226 "parity error(0x%04X)\n", j+1,
225 block_address); 227 block_address);
226 } else { 228 } else {
@@ -233,7 +235,7 @@ static int get_logical_address(uint8_t *oob_buf)
233 if (!ok) 235 if (!ok)
234 block_address = -2; 236 block_address = -2;
235 237
236 pr_debug("SSFDC_RO: get_logical_address() %d\n", 238 DEBUG(MTD_DEBUG_LEVEL3, "SSFDC_RO: get_logical_address() %d\n",
237 block_address); 239 block_address);
238 240
239 return block_address; 241 return block_address;
@@ -247,7 +249,7 @@ static int build_logical_block_map(struct ssfdcr_record *ssfdc)
247 int ret, block_address, phys_block; 249 int ret, block_address, phys_block;
248 struct mtd_info *mtd = ssfdc->mbd.mtd; 250 struct mtd_info *mtd = ssfdc->mbd.mtd;
249 251
250 pr_debug("SSFDC_RO: build_block_map() nblks=%d (%luK)\n", 252 DEBUG(MTD_DEBUG_LEVEL1, "SSFDC_RO: build_block_map() nblks=%d (%luK)\n",
251 ssfdc->map_len, 253 ssfdc->map_len,
252 (unsigned long)ssfdc->map_len * ssfdc->erase_size / 1024); 254 (unsigned long)ssfdc->map_len * ssfdc->erase_size / 1024);
253 255
@@ -255,12 +257,13 @@ static int build_logical_block_map(struct ssfdcr_record *ssfdc)
255 for (phys_block = ssfdc->cis_block + 1; phys_block < ssfdc->map_len; 257 for (phys_block = ssfdc->cis_block + 1; phys_block < ssfdc->map_len;
256 phys_block++) { 258 phys_block++) {
257 offset = (unsigned long)phys_block * ssfdc->erase_size; 259 offset = (unsigned long)phys_block * ssfdc->erase_size;
258 if (mtd_block_isbad(mtd, offset)) 260 if (mtd->block_isbad(mtd, offset))
259 continue; /* skip bad blocks */ 261 continue; /* skip bad blocks */
260 262
261 ret = read_raw_oob(mtd, offset, oob_buf); 263 ret = read_raw_oob(mtd, offset, oob_buf);
262 if (ret < 0) { 264 if (ret < 0) {
263 pr_debug("SSFDC_RO: mtd read_oob() failed at %lu\n", 265 DEBUG(MTD_DEBUG_LEVEL0,
266 "SSFDC_RO: mtd read_oob() failed at %lu\n",
264 offset); 267 offset);
265 return -1; 268 return -1;
266 } 269 }
@@ -276,7 +279,8 @@ static int build_logical_block_map(struct ssfdcr_record *ssfdc)
276 ssfdc->logic_block_map[block_address] = 279 ssfdc->logic_block_map[block_address] =
277 (unsigned short)phys_block; 280 (unsigned short)phys_block;
278 281
279 pr_debug("SSFDC_RO: build_block_map() phys_block=%d," 282 DEBUG(MTD_DEBUG_LEVEL2,
283 "SSFDC_RO: build_block_map() phys_block=%d,"
280 "logic_block_addr=%d, zone=%d\n", 284 "logic_block_addr=%d, zone=%d\n",
281 phys_block, block_address, zone_index); 285 phys_block, block_address, zone_index);
282 } 286 }
@@ -300,8 +304,11 @@ static void ssfdcr_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
300 return; 304 return;
301 305
302 ssfdc = kzalloc(sizeof(struct ssfdcr_record), GFP_KERNEL); 306 ssfdc = kzalloc(sizeof(struct ssfdcr_record), GFP_KERNEL);
303 if (!ssfdc) 307 if (!ssfdc) {
308 printk(KERN_WARNING
309 "SSFDC_RO: out of memory for data structures\n");
304 return; 310 return;
311 }
305 312
306 ssfdc->mbd.mtd = mtd; 313 ssfdc->mbd.mtd = mtd;
307 ssfdc->mbd.devnum = -1; 314 ssfdc->mbd.devnum = -1;
@@ -312,7 +319,8 @@ static void ssfdcr_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
312 ssfdc->erase_size = mtd->erasesize; 319 ssfdc->erase_size = mtd->erasesize;
313 ssfdc->map_len = (u32)mtd->size / mtd->erasesize; 320 ssfdc->map_len = (u32)mtd->size / mtd->erasesize;
314 321
315 pr_debug("SSFDC_RO: cis_block=%d,erase_size=%d,map_len=%d,n_zones=%d\n", 322 DEBUG(MTD_DEBUG_LEVEL1,
323 "SSFDC_RO: cis_block=%d,erase_size=%d,map_len=%d,n_zones=%d\n",
316 ssfdc->cis_block, ssfdc->erase_size, ssfdc->map_len, 324 ssfdc->cis_block, ssfdc->erase_size, ssfdc->map_len,
317 DIV_ROUND_UP(ssfdc->map_len, MAX_PHYS_BLK_PER_ZONE)); 325 DIV_ROUND_UP(ssfdc->map_len, MAX_PHYS_BLK_PER_ZONE));
318 326
@@ -323,7 +331,7 @@ static void ssfdcr_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
323 ssfdc->cylinders = (unsigned short)(((u32)mtd->size >> SECTOR_SHIFT) / 331 ssfdc->cylinders = (unsigned short)(((u32)mtd->size >> SECTOR_SHIFT) /
324 ((long)ssfdc->sectors * (long)ssfdc->heads)); 332 ((long)ssfdc->sectors * (long)ssfdc->heads));
325 333
326 pr_debug("SSFDC_RO: using C:%d H:%d S:%d == %ld sects\n", 334 DEBUG(MTD_DEBUG_LEVEL1, "SSFDC_RO: using C:%d H:%d S:%d == %ld sects\n",
327 ssfdc->cylinders, ssfdc->heads , ssfdc->sectors, 335 ssfdc->cylinders, ssfdc->heads , ssfdc->sectors,
328 (long)ssfdc->cylinders * (long)ssfdc->heads * 336 (long)ssfdc->cylinders * (long)ssfdc->heads *
329 (long)ssfdc->sectors); 337 (long)ssfdc->sectors);
@@ -334,8 +342,11 @@ static void ssfdcr_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
334 /* Allocate logical block map */ 342 /* Allocate logical block map */
335 ssfdc->logic_block_map = kmalloc(sizeof(ssfdc->logic_block_map[0]) * 343 ssfdc->logic_block_map = kmalloc(sizeof(ssfdc->logic_block_map[0]) *
336 ssfdc->map_len, GFP_KERNEL); 344 ssfdc->map_len, GFP_KERNEL);
337 if (!ssfdc->logic_block_map) 345 if (!ssfdc->logic_block_map) {
346 printk(KERN_WARNING
347 "SSFDC_RO: out of memory for data structures\n");
338 goto out_err; 348 goto out_err;
349 }
339 memset(ssfdc->logic_block_map, 0xff, sizeof(ssfdc->logic_block_map[0]) * 350 memset(ssfdc->logic_block_map, 0xff, sizeof(ssfdc->logic_block_map[0]) *
340 ssfdc->map_len); 351 ssfdc->map_len);
341 352
@@ -360,7 +371,7 @@ static void ssfdcr_remove_dev(struct mtd_blktrans_dev *dev)
360{ 371{
361 struct ssfdcr_record *ssfdc = (struct ssfdcr_record *)dev; 372 struct ssfdcr_record *ssfdc = (struct ssfdcr_record *)dev;
362 373
363 pr_debug("SSFDC_RO: remove_dev (i=%d)\n", dev->devnum); 374 DEBUG(MTD_DEBUG_LEVEL1, "SSFDC_RO: remove_dev (i=%d)\n", dev->devnum);
364 375
365 del_mtd_blktrans_dev(dev); 376 del_mtd_blktrans_dev(dev);
366 kfree(ssfdc->logic_block_map); 377 kfree(ssfdc->logic_block_map);
@@ -376,7 +387,8 @@ static int ssfdcr_readsect(struct mtd_blktrans_dev *dev,
376 offset = (int)(logic_sect_no % sectors_per_block); 387 offset = (int)(logic_sect_no % sectors_per_block);
377 block_address = (int)(logic_sect_no / sectors_per_block); 388 block_address = (int)(logic_sect_no / sectors_per_block);
378 389
379 pr_debug("SSFDC_RO: ssfdcr_readsect(%lu) sec_per_blk=%d, ofst=%d," 390 DEBUG(MTD_DEBUG_LEVEL3,
391 "SSFDC_RO: ssfdcr_readsect(%lu) sec_per_blk=%d, ofst=%d,"
380 " block_addr=%d\n", logic_sect_no, sectors_per_block, offset, 392 " block_addr=%d\n", logic_sect_no, sectors_per_block, offset,
381 block_address); 393 block_address);
382 394
@@ -385,7 +397,8 @@ static int ssfdcr_readsect(struct mtd_blktrans_dev *dev,
385 397
386 block_address = ssfdc->logic_block_map[block_address]; 398 block_address = ssfdc->logic_block_map[block_address];
387 399
388 pr_debug("SSFDC_RO: ssfdcr_readsect() phys_block_addr=%d\n", 400 DEBUG(MTD_DEBUG_LEVEL3,
401 "SSFDC_RO: ssfdcr_readsect() phys_block_addr=%d\n",
389 block_address); 402 block_address);
390 403
391 if (block_address < 0xffff) { 404 if (block_address < 0xffff) {
@@ -394,7 +407,8 @@ static int ssfdcr_readsect(struct mtd_blktrans_dev *dev,
394 sect_no = (unsigned long)block_address * sectors_per_block + 407 sect_no = (unsigned long)block_address * sectors_per_block +
395 offset; 408 offset;
396 409
397 pr_debug("SSFDC_RO: ssfdcr_readsect() phys_sect_no=%lu\n", 410 DEBUG(MTD_DEBUG_LEVEL3,
411 "SSFDC_RO: ssfdcr_readsect() phys_sect_no=%lu\n",
398 sect_no); 412 sect_no);
399 413
400 if (read_physical_sector(ssfdc->mbd.mtd, buf, sect_no) < 0) 414 if (read_physical_sector(ssfdc->mbd.mtd, buf, sect_no) < 0)
@@ -410,7 +424,7 @@ static int ssfdcr_getgeo(struct mtd_blktrans_dev *dev, struct hd_geometry *geo)
410{ 424{
411 struct ssfdcr_record *ssfdc = (struct ssfdcr_record *)dev; 425 struct ssfdcr_record *ssfdc = (struct ssfdcr_record *)dev;
412 426
413 pr_debug("SSFDC_RO: ssfdcr_getgeo() C=%d, H=%d, S=%d\n", 427 DEBUG(MTD_DEBUG_LEVEL1, "SSFDC_RO: ssfdcr_getgeo() C=%d, H=%d, S=%d\n",
414 ssfdc->cylinders, ssfdc->heads, ssfdc->sectors); 428 ssfdc->cylinders, ssfdc->heads, ssfdc->sectors);
415 429
416 geo->heads = ssfdc->heads; 430 geo->heads = ssfdc->heads;