Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
spi.c
Go to the documentation of this file.
1 /* Driver for Realtek PCI-Express card reader
2  *
3  * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License as published by the
7  * Free Software Foundation; either version 2, or (at your option) any
8  * later version.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along
16  * with this program; if not, see <http://www.gnu.org/licenses/>.
17  *
18  * Author:
19  * wwang ([email protected])
20  * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China
21  */
22 
23 #include <linux/blkdev.h>
24 #include <linux/kthread.h>
25 #include <linux/sched.h>
26 
27 #include "rtsx.h"
28 #include "rtsx_transport.h"
29 #include "rtsx_scsi.h"
30 #include "rtsx_card.h"
31 #include "spi.h"
32 
33 static inline void spi_set_err_code(struct rtsx_chip *chip, u8 err_code)
34 {
35  struct spi_info *spi = &(chip->spi);
36 
37  spi->err_code = err_code;
38 }
39 
40 static int spi_init(struct rtsx_chip *chip)
41 {
42  RTSX_WRITE_REG(chip, SPI_CONTROL, 0xFF,
45 
46  return STATUS_SUCCESS;
47 }
48 
49 static int spi_set_init_para(struct rtsx_chip *chip)
50 {
51  struct spi_info *spi = &(chip->spi);
52  int retval;
53 
54  RTSX_WRITE_REG(chip, SPI_CLK_DIVIDER1, 0xFF, (u8)(spi->clk_div >> 8));
55  RTSX_WRITE_REG(chip, SPI_CLK_DIVIDER0, 0xFF, (u8)(spi->clk_div));
56 
57  retval = switch_clock(chip, spi->spi_clock);
58  if (retval != STATUS_SUCCESS)
59  TRACE_RET(chip, STATUS_FAIL);
60 
61  retval = select_card(chip, SPI_CARD);
62  if (retval != STATUS_SUCCESS)
63  TRACE_RET(chip, STATUS_FAIL);
64 
67 
68  wait_timeout(10);
69 
70  retval = spi_init(chip);
71  if (retval != STATUS_SUCCESS)
72  TRACE_RET(chip, STATUS_FAIL);
73 
74  return STATUS_SUCCESS;
75 }
76 
77 static int sf_polling_status(struct rtsx_chip *chip, int msec)
78 {
79  int retval;
80 
81  rtsx_init_cmd(chip);
82 
86 
87  retval = rtsx_send_cmd(chip, 0, msec);
88  if (retval < 0) {
89  rtsx_clear_spi_error(chip);
90  spi_set_err_code(chip, SPI_BUSY_ERR);
91  TRACE_RET(chip, STATUS_FAIL);
92  }
93 
94  return STATUS_SUCCESS;
95 }
96 
97 static int sf_enable_write(struct rtsx_chip *chip, u8 ins)
98 {
99  struct spi_info *spi = &(chip->spi);
100  int retval;
101 
102  if (!spi->write_en)
103  return STATUS_SUCCESS;
104 
105  rtsx_init_cmd(chip);
106 
107  rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, ins);
111 
112  retval = rtsx_send_cmd(chip, 0, 100);
113  if (retval < 0) {
114  rtsx_clear_spi_error(chip);
115  spi_set_err_code(chip, SPI_HW_ERR);
116  TRACE_RET(chip, STATUS_FAIL);
117  }
118 
119  return STATUS_SUCCESS;
120 }
121 
122 static int sf_disable_write(struct rtsx_chip *chip, u8 ins)
123 {
124  struct spi_info *spi = &(chip->spi);
125  int retval;
126 
127  if (!spi->write_en)
128  return STATUS_SUCCESS;
129 
130  rtsx_init_cmd(chip);
131 
132  rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, ins);
136 
137  retval = rtsx_send_cmd(chip, 0, 100);
138  if (retval < 0) {
139  rtsx_clear_spi_error(chip);
140  spi_set_err_code(chip, SPI_HW_ERR);
141  TRACE_RET(chip, STATUS_FAIL);
142  }
143 
144  return STATUS_SUCCESS;
145 }
146 
147 static void sf_program(struct rtsx_chip *chip, u8 ins, u8 addr_mode, u32 addr, u16 len)
148 {
149  rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, ins);
151  rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_LENGTH0, 0xFF, (u8)len);
152  rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_LENGTH1, 0xFF, (u8)(len >> 8));
153  if (addr_mode) {
154  rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR0, 0xFF, (u8)addr);
155  rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR1, 0xFF, (u8)(addr >> 8));
156  rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR2, 0xFF, (u8)(addr >> 16));
158  } else {
160  }
162 }
163 
164 static int sf_erase(struct rtsx_chip *chip, u8 ins, u8 addr_mode, u32 addr)
165 {
166  int retval;
167 
168  rtsx_init_cmd(chip);
169 
170  rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, ins);
172  if (addr_mode) {
173  rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR0, 0xFF, (u8)addr);
174  rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR1, 0xFF, (u8)(addr >> 8));
175  rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR2, 0xFF, (u8)(addr >> 16));
177  } else {
179  }
181 
182  retval = rtsx_send_cmd(chip, 0, 100);
183  if (retval < 0) {
184  rtsx_clear_spi_error(chip);
185  spi_set_err_code(chip, SPI_HW_ERR);
186  TRACE_RET(chip, STATUS_FAIL);
187  }
188 
189  return STATUS_SUCCESS;
190 }
191 
192 static int spi_init_eeprom(struct rtsx_chip *chip)
193 {
194  int retval;
195  int clk;
196 
197  if (chip->asic_code)
198  clk = 30;
199  else
200  clk = CLK_30;
201 
202  RTSX_WRITE_REG(chip, SPI_CLK_DIVIDER1, 0xFF, 0x00);
203  RTSX_WRITE_REG(chip, SPI_CLK_DIVIDER0, 0xFF, 0x27);
204 
205  retval = switch_clock(chip, clk);
206  if (retval != STATUS_SUCCESS)
207  TRACE_RET(chip, STATUS_FAIL);
208 
209  retval = select_card(chip, SPI_CARD);
210  if (retval != STATUS_SUCCESS)
211  TRACE_RET(chip, STATUS_FAIL);
212 
215 
216  wait_timeout(10);
217 
220 
221  return STATUS_SUCCESS;
222 }
223 
224 static int spi_eeprom_program_enable(struct rtsx_chip *chip)
225 {
226  int retval;
227 
228  rtsx_init_cmd(chip);
229 
231  rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, 0x13);
234 
235  retval = rtsx_send_cmd(chip, 0, 100);
236  if (retval < 0)
237  TRACE_RET(chip, STATUS_FAIL);
238 
239  return STATUS_SUCCESS;
240 }
241 
243 {
244  int retval;
245 
246  retval = spi_init_eeprom(chip);
247  if (retval != STATUS_SUCCESS)
248  TRACE_RET(chip, STATUS_FAIL);
249 
250  retval = spi_eeprom_program_enable(chip);
251  if (retval != STATUS_SUCCESS)
252  TRACE_RET(chip, STATUS_FAIL);
253 
254  rtsx_init_cmd(chip);
255 
256  rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_GPIO_DIR, 0x01, 0);
258  rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, 0x12);
259  rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, 0x84);
262 
263  retval = rtsx_send_cmd(chip, 0, 100);
264  if (retval < 0)
265  TRACE_RET(chip, STATUS_FAIL);
266 
267  RTSX_WRITE_REG(chip, CARD_GPIO_DIR, 0x01, 0x01);
268 
269  return STATUS_SUCCESS;
270 }
271 
272 int spi_erase_eeprom_byte(struct rtsx_chip *chip, u16 addr)
273 {
274  int retval;
275 
276  retval = spi_init_eeprom(chip);
277  if (retval != STATUS_SUCCESS)
278  TRACE_RET(chip, STATUS_FAIL);
279 
280  retval = spi_eeprom_program_enable(chip);
281  if (retval != STATUS_SUCCESS)
282  TRACE_RET(chip, STATUS_FAIL);
283 
284  rtsx_init_cmd(chip);
285 
286  rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_GPIO_DIR, 0x01, 0);
288  rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, 0x07);
289  rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR0, 0xFF, (u8)addr);
290  rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR1, 0xFF, (u8)(addr >> 8));
291  rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, 0x46);
294 
295  retval = rtsx_send_cmd(chip, 0, 100);
296  if (retval < 0)
297  TRACE_RET(chip, STATUS_FAIL);
298 
299  RTSX_WRITE_REG(chip, CARD_GPIO_DIR, 0x01, 0x01);
300 
301  return STATUS_SUCCESS;
302 }
303 
304 
305 int spi_read_eeprom(struct rtsx_chip *chip, u16 addr, u8 *val)
306 {
307  int retval;
308  u8 data;
309 
310  retval = spi_init_eeprom(chip);
311  if (retval != STATUS_SUCCESS)
312  TRACE_RET(chip, STATUS_FAIL);
313 
314  rtsx_init_cmd(chip);
315 
316  rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_GPIO_DIR, 0x01, 0);
318  rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, 0x06);
319  rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR0, 0xFF, (u8)addr);
320  rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR1, 0xFF, (u8)(addr >> 8));
321  rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, 0x46);
322  rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_LENGTH0, 0xFF, 1);
325 
326  retval = rtsx_send_cmd(chip, 0, 100);
327  if (retval < 0)
328  TRACE_RET(chip, STATUS_FAIL);
329 
330  wait_timeout(5);
331  RTSX_READ_REG(chip, SPI_DATA, &data);
332 
333  if (val)
334  *val = data;
335 
336  RTSX_WRITE_REG(chip, CARD_GPIO_DIR, 0x01, 0x01);
337 
338  return STATUS_SUCCESS;
339 }
340 
341 int spi_write_eeprom(struct rtsx_chip *chip, u16 addr, u8 val)
342 {
343  int retval;
344 
345  retval = spi_init_eeprom(chip);
346  if (retval != STATUS_SUCCESS)
347  TRACE_RET(chip, STATUS_FAIL);
348 
349  retval = spi_eeprom_program_enable(chip);
350  if (retval != STATUS_SUCCESS)
351  TRACE_RET(chip, STATUS_FAIL);
352 
353  rtsx_init_cmd(chip);
354 
355  rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_GPIO_DIR, 0x01, 0);
357  rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, 0x05);
358  rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR0, 0xFF, val);
359  rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR1, 0xFF, (u8)addr);
360  rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR2, 0xFF, (u8)(addr >> 8));
361  rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, 0x4E);
364 
365  retval = rtsx_send_cmd(chip, 0, 100);
366  if (retval < 0)
367  TRACE_RET(chip, STATUS_FAIL);
368 
369  RTSX_WRITE_REG(chip, CARD_GPIO_DIR, 0x01, 0x01);
370 
371  return STATUS_SUCCESS;
372 }
373 
374 
375 int spi_get_status(struct scsi_cmnd *srb, struct rtsx_chip *chip)
376 {
377  struct spi_info *spi = &(chip->spi);
378 
379  RTSX_DEBUGP("spi_get_status: err_code = 0x%x\n", spi->err_code);
380  rtsx_stor_set_xfer_buf(&(spi->err_code), min((int)scsi_bufflen(srb), 1), srb);
381  scsi_set_resid(srb, scsi_bufflen(srb) - 1);
382 
383  return STATUS_SUCCESS;
384 }
385 
386 int spi_set_parameter(struct scsi_cmnd *srb, struct rtsx_chip *chip)
387 {
388  struct spi_info *spi = &(chip->spi);
389 
390  spi_set_err_code(chip, SPI_NO_ERR);
391 
392  if (chip->asic_code)
393  spi->spi_clock = ((u16)(srb->cmnd[8]) << 8) | srb->cmnd[9];
394  else
395  spi->spi_clock = srb->cmnd[3];
396 
397  spi->clk_div = ((u16)(srb->cmnd[4]) << 8) | srb->cmnd[5];
398  spi->write_en = srb->cmnd[6];
399 
400  RTSX_DEBUGP("spi_set_parameter: spi_clock = %d, clk_div = %d, write_en = %d\n",
401  spi->spi_clock, spi->clk_div, spi->write_en);
402 
403  return STATUS_SUCCESS;
404 }
405 
406 int spi_read_flash_id(struct scsi_cmnd *srb, struct rtsx_chip *chip)
407 {
408  int retval;
409  u16 len;
410  u8 *buf;
411 
412  spi_set_err_code(chip, SPI_NO_ERR);
413 
414  len = ((u16)(srb->cmnd[7]) << 8) | srb->cmnd[8];
415  if (len > 512) {
416  spi_set_err_code(chip, SPI_INVALID_COMMAND);
417  TRACE_RET(chip, STATUS_FAIL);
418  }
419 
420  retval = spi_set_init_para(chip);
421  if (retval != STATUS_SUCCESS) {
422  spi_set_err_code(chip, SPI_HW_ERR);
423  TRACE_RET(chip, STATUS_FAIL);
424  }
425 
426  rtsx_init_cmd(chip);
427 
429 
430  rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, srb->cmnd[3]);
431  rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR2, 0xFF, srb->cmnd[4]);
432  rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR1, 0xFF, srb->cmnd[5]);
433  rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR0, 0xFF, srb->cmnd[6]);
435  rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_LENGTH1, 0xFF, srb->cmnd[7]);
436  rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_LENGTH0, 0xFF, srb->cmnd[8]);
437 
438  if (len == 0) {
439  if (srb->cmnd[9]) {
442  } else {
445  }
446  } else {
447  if (srb->cmnd[9]) {
450  } else {
453  }
454  }
455 
457 
458  retval = rtsx_send_cmd(chip, 0, 100);
459  if (retval < 0) {
460  rtsx_clear_spi_error(chip);
461  spi_set_err_code(chip, SPI_HW_ERR);
462  TRACE_RET(chip, STATUS_FAIL);
463  }
464 
465  if (len) {
466  buf = kmalloc(len, GFP_KERNEL);
467  if (!buf)
468  TRACE_RET(chip, STATUS_ERROR);
469 
470  retval = rtsx_read_ppbuf(chip, buf, len);
471  if (retval != STATUS_SUCCESS) {
472  spi_set_err_code(chip, SPI_READ_ERR);
473  kfree(buf);
474  TRACE_RET(chip, STATUS_FAIL);
475  }
476 
477  rtsx_stor_set_xfer_buf(buf, scsi_bufflen(srb), srb);
478  scsi_set_resid(srb, 0);
479 
480  kfree(buf);
481  }
482 
483  return STATUS_SUCCESS;
484 }
485 
486 int spi_read_flash(struct scsi_cmnd *srb, struct rtsx_chip *chip)
487 {
488  int retval;
489  unsigned int index = 0, offset = 0;
490  u8 ins, slow_read;
491  u32 addr;
492  u16 len;
493  u8 *buf;
494 
495  spi_set_err_code(chip, SPI_NO_ERR);
496 
497  ins = srb->cmnd[3];
498  addr = ((u32)(srb->cmnd[4]) << 16) | ((u32)(srb->cmnd[5]) << 8) | srb->cmnd[6];
499  len = ((u16)(srb->cmnd[7]) << 8) | srb->cmnd[8];
500  slow_read = srb->cmnd[9];
501 
502  retval = spi_set_init_para(chip);
503  if (retval != STATUS_SUCCESS) {
504  spi_set_err_code(chip, SPI_HW_ERR);
505  TRACE_RET(chip, STATUS_FAIL);
506  }
507 
509  if (buf == NULL)
510  TRACE_RET(chip, STATUS_ERROR);
511 
512  while (len) {
513  u16 pagelen = SF_PAGE_LEN - (u8)addr;
514 
515  if (pagelen > len)
516  pagelen = len;
517 
518  rtsx_init_cmd(chip);
519 
521 
522  rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, ins);
523 
524  if (slow_read) {
525  rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR0, 0xFF, (u8)addr);
526  rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR1, 0xFF, (u8)(addr >> 8));
527  rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR2, 0xFF, (u8)(addr >> 16));
529  } else {
530  rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR1, 0xFF, (u8)addr);
531  rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR2, 0xFF, (u8)(addr >> 8));
532  rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR3, 0xFF, (u8)(addr >> 16));
534  }
535 
536  rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_LENGTH1, 0xFF, (u8)(pagelen >> 8));
537  rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_LENGTH0, 0xFF, (u8)pagelen);
538 
541 
542  rtsx_send_cmd_no_wait(chip);
543 
544  retval = rtsx_transfer_data(chip, 0, buf, pagelen, 0, DMA_FROM_DEVICE, 10000);
545  if (retval < 0) {
546  kfree(buf);
547  rtsx_clear_spi_error(chip);
548  spi_set_err_code(chip, SPI_HW_ERR);
549  TRACE_RET(chip, STATUS_FAIL);
550  }
551 
552  rtsx_stor_access_xfer_buf(buf, pagelen, srb, &index, &offset, TO_XFER_BUF);
553 
554  addr += pagelen;
555  len -= pagelen;
556  }
557 
558  scsi_set_resid(srb, 0);
559  kfree(buf);
560 
561  return STATUS_SUCCESS;
562 }
563 
564 int spi_write_flash(struct scsi_cmnd *srb, struct rtsx_chip *chip)
565 {
566  int retval;
567  u8 ins, program_mode;
568  u32 addr;
569  u16 len;
570  u8 *buf;
571  unsigned int index = 0, offset = 0;
572 
573  spi_set_err_code(chip, SPI_NO_ERR);
574 
575  ins = srb->cmnd[3];
576  addr = ((u32)(srb->cmnd[4]) << 16) | ((u32)(srb->cmnd[5]) << 8) | srb->cmnd[6];
577  len = ((u16)(srb->cmnd[7]) << 8) | srb->cmnd[8];
578  program_mode = srb->cmnd[9];
579 
580  retval = spi_set_init_para(chip);
581  if (retval != STATUS_SUCCESS) {
582  spi_set_err_code(chip, SPI_HW_ERR);
583  TRACE_RET(chip, STATUS_FAIL);
584  }
585 
586  if (program_mode == BYTE_PROGRAM) {
587  buf = kmalloc(4, GFP_KERNEL);
588  if (!buf)
589  TRACE_RET(chip, STATUS_ERROR);
590 
591  while (len) {
592  retval = sf_enable_write(chip, SPI_WREN);
593  if (retval != STATUS_SUCCESS) {
594  kfree(buf);
595  TRACE_RET(chip, STATUS_FAIL);
596  }
597 
598  rtsx_stor_access_xfer_buf(buf, 1, srb, &index, &offset, FROM_XFER_BUF);
599 
600  rtsx_init_cmd(chip);
601 
603  rtsx_add_cmd(chip, WRITE_REG_CMD, PPBUF_BASE2, 0xFF, buf[0]);
604  sf_program(chip, ins, 1, addr, 1);
605 
606  retval = rtsx_send_cmd(chip, 0, 100);
607  if (retval < 0) {
608  kfree(buf);
609  rtsx_clear_spi_error(chip);
610  spi_set_err_code(chip, SPI_HW_ERR);
611  TRACE_RET(chip, STATUS_FAIL);
612  }
613 
614  retval = sf_polling_status(chip, 100);
615  if (retval != STATUS_SUCCESS) {
616  kfree(buf);
617  TRACE_RET(chip, STATUS_FAIL);
618  }
619 
620  addr++;
621  len--;
622  }
623 
624  kfree(buf);
625 
626  } else if (program_mode == AAI_PROGRAM) {
627  int first_byte = 1;
628 
629  retval = sf_enable_write(chip, SPI_WREN);
630  if (retval != STATUS_SUCCESS)
631  TRACE_RET(chip, STATUS_FAIL);
632 
633  buf = kmalloc(4, GFP_KERNEL);
634  if (!buf)
635  TRACE_RET(chip, STATUS_ERROR);
636 
637  while (len) {
638  rtsx_stor_access_xfer_buf(buf, 1, srb, &index, &offset, FROM_XFER_BUF);
639 
640  rtsx_init_cmd(chip);
641 
643  rtsx_add_cmd(chip, WRITE_REG_CMD, PPBUF_BASE2, 0xFF, buf[0]);
644  if (first_byte) {
645  sf_program(chip, ins, 1, addr, 1);
646  first_byte = 0;
647  } else {
648  sf_program(chip, ins, 0, 0, 1);
649  }
650 
651  retval = rtsx_send_cmd(chip, 0, 100);
652  if (retval < 0) {
653  kfree(buf);
654  rtsx_clear_spi_error(chip);
655  spi_set_err_code(chip, SPI_HW_ERR);
656  TRACE_RET(chip, STATUS_FAIL);
657  }
658 
659  retval = sf_polling_status(chip, 100);
660  if (retval != STATUS_SUCCESS) {
661  kfree(buf);
662  TRACE_RET(chip, STATUS_FAIL);
663  }
664 
665  len--;
666  }
667 
668  kfree(buf);
669 
670  retval = sf_disable_write(chip, SPI_WRDI);
671  if (retval != STATUS_SUCCESS)
672  TRACE_RET(chip, STATUS_FAIL);
673 
674  retval = sf_polling_status(chip, 100);
675  if (retval != STATUS_SUCCESS)
676  TRACE_RET(chip, STATUS_FAIL);
677  } else if (program_mode == PAGE_PROGRAM) {
679  if (!buf)
680  TRACE_RET(chip, STATUS_NOMEM);
681 
682  while (len) {
683  u16 pagelen = SF_PAGE_LEN - (u8)addr;
684 
685  if (pagelen > len)
686  pagelen = len;
687 
688  retval = sf_enable_write(chip, SPI_WREN);
689  if (retval != STATUS_SUCCESS) {
690  kfree(buf);
691  TRACE_RET(chip, STATUS_FAIL);
692  }
693 
694  rtsx_init_cmd(chip);
695 
697  sf_program(chip, ins, 1, addr, pagelen);
698 
699  rtsx_send_cmd_no_wait(chip);
700 
701  rtsx_stor_access_xfer_buf(buf, pagelen, srb, &index, &offset, FROM_XFER_BUF);
702 
703  retval = rtsx_transfer_data(chip, 0, buf, pagelen, 0, DMA_TO_DEVICE, 100);
704  if (retval < 0) {
705  kfree(buf);
706  rtsx_clear_spi_error(chip);
707  spi_set_err_code(chip, SPI_HW_ERR);
708  TRACE_RET(chip, STATUS_FAIL);
709  }
710 
711  retval = sf_polling_status(chip, 100);
712  if (retval != STATUS_SUCCESS) {
713  kfree(buf);
714  TRACE_RET(chip, STATUS_FAIL);
715  }
716 
717  addr += pagelen;
718  len -= pagelen;
719  }
720 
721  kfree(buf);
722  } else {
723  spi_set_err_code(chip, SPI_INVALID_COMMAND);
724  TRACE_RET(chip, STATUS_FAIL);
725  }
726 
727  return STATUS_SUCCESS;
728 }
729 
730 int spi_erase_flash(struct scsi_cmnd *srb, struct rtsx_chip *chip)
731 {
732  int retval;
733  u8 ins, erase_mode;
734  u32 addr;
735 
736  spi_set_err_code(chip, SPI_NO_ERR);
737 
738  ins = srb->cmnd[3];
739  addr = ((u32)(srb->cmnd[4]) << 16) | ((u32)(srb->cmnd[5]) << 8) | srb->cmnd[6];
740  erase_mode = srb->cmnd[9];
741 
742  retval = spi_set_init_para(chip);
743  if (retval != STATUS_SUCCESS) {
744  spi_set_err_code(chip, SPI_HW_ERR);
745  TRACE_RET(chip, STATUS_FAIL);
746  }
747 
748  if (erase_mode == PAGE_ERASE) {
749  retval = sf_enable_write(chip, SPI_WREN);
750  if (retval != STATUS_SUCCESS)
751  TRACE_RET(chip, STATUS_FAIL);
752 
753  retval = sf_erase(chip, ins, 1, addr);
754  if (retval != STATUS_SUCCESS)
755  TRACE_RET(chip, STATUS_FAIL);
756  } else if (erase_mode == CHIP_ERASE) {
757  retval = sf_enable_write(chip, SPI_WREN);
758  if (retval != STATUS_SUCCESS)
759  TRACE_RET(chip, STATUS_FAIL);
760 
761  retval = sf_erase(chip, ins, 0, 0);
762  if (retval != STATUS_SUCCESS)
763  TRACE_RET(chip, STATUS_FAIL);
764  } else {
765  spi_set_err_code(chip, SPI_INVALID_COMMAND);
766  TRACE_RET(chip, STATUS_FAIL);
767  }
768 
769  return STATUS_SUCCESS;
770 }
771 
772 int spi_write_flash_status(struct scsi_cmnd *srb, struct rtsx_chip *chip)
773 {
774  int retval;
775  u8 ins, status, ewsr;
776 
777  ins = srb->cmnd[3];
778  status = srb->cmnd[4];
779  ewsr = srb->cmnd[5];
780 
781  retval = spi_set_init_para(chip);
782  if (retval != STATUS_SUCCESS) {
783  spi_set_err_code(chip, SPI_HW_ERR);
784  TRACE_RET(chip, STATUS_FAIL);
785  }
786 
787  retval = sf_enable_write(chip, ewsr);
788  if (retval != STATUS_SUCCESS)
789  TRACE_RET(chip, STATUS_FAIL);
790 
791  rtsx_init_cmd(chip);
792 
794 
795  rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, ins);
797  rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_LENGTH1, 0xFF, 0);
798  rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_LENGTH0, 0xFF, 1);
799  rtsx_add_cmd(chip, WRITE_REG_CMD, PPBUF_BASE2, 0xFF, status);
802 
803  retval = rtsx_send_cmd(chip, 0, 100);
804  if (retval != STATUS_SUCCESS) {
805  rtsx_clear_spi_error(chip);
806  spi_set_err_code(chip, SPI_HW_ERR);
807  TRACE_RET(chip, STATUS_FAIL);
808  }
809 
810  return STATUS_SUCCESS;
811 }
812