cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

arm_scsi.h (3157B)


      1/* SPDX-License-Identifier: GPL-2.0-only */
      2/*
      3 *  Copyright (C) 2002 Russell King
      4 *
      5 *  Commonly used functions by the ARM SCSI-II drivers.
      6 */
      7
      8#include <linux/scatterlist.h>
      9
     10#define BELT_AND_BRACES
     11
     12struct arm_cmd_priv {
     13	struct scsi_pointer scsi_pointer;
     14};
     15
     16static inline struct scsi_pointer *arm_scsi_pointer(struct scsi_cmnd *cmd)
     17{
     18	struct arm_cmd_priv *acmd = scsi_cmd_priv(cmd);
     19
     20	return &acmd->scsi_pointer;
     21}
     22
     23/*
     24 * The scatter-gather list handling.  This contains all
     25 * the yucky stuff that needs to be fixed properly.
     26 */
     27
     28/*
     29 * copy_SCp_to_sg() Assumes contiguous allocation at @sg of at-most @max
     30 * entries of uninitialized memory. SCp is from scsi-ml and has a valid
     31 * (possibly chained) sg-list
     32 */
     33static inline int copy_SCp_to_sg(struct scatterlist *sg, struct scsi_pointer *SCp, int max)
     34{
     35	int bufs = SCp->buffers_residual;
     36
     37	/* FIXME: It should be easy for drivers to loop on copy_SCp_to_sg().
     38	 * and to remove this BUG_ON. Use min() in-its-place
     39	 */
     40	BUG_ON(bufs + 1 > max);
     41
     42	sg_set_buf(sg, SCp->ptr, SCp->this_residual);
     43
     44	if (bufs) {
     45		struct scatterlist *src_sg;
     46		unsigned i;
     47
     48		for_each_sg(sg_next(SCp->buffer), src_sg, bufs, i)
     49			*(++sg) = *src_sg;
     50		sg_mark_end(sg);
     51	}
     52
     53	return bufs + 1;
     54}
     55
     56static inline int next_SCp(struct scsi_pointer *SCp)
     57{
     58	int ret = SCp->buffers_residual;
     59	if (ret) {
     60		SCp->buffer = sg_next(SCp->buffer);
     61		SCp->buffers_residual--;
     62		SCp->ptr = sg_virt(SCp->buffer);
     63		SCp->this_residual = SCp->buffer->length;
     64	} else {
     65		SCp->ptr = NULL;
     66		SCp->this_residual = 0;
     67	}
     68	return ret;
     69}
     70
     71static inline unsigned char get_next_SCp_byte(struct scsi_pointer *SCp)
     72{
     73	char c = *SCp->ptr;
     74
     75	SCp->ptr += 1;
     76	SCp->this_residual -= 1;
     77
     78	return c;
     79}
     80
     81static inline void put_next_SCp_byte(struct scsi_pointer *SCp, unsigned char c)
     82{
     83	*SCp->ptr = c;
     84	SCp->ptr += 1;
     85	SCp->this_residual -= 1;
     86}
     87
     88static inline void init_SCp(struct scsi_cmnd *SCpnt)
     89{
     90	struct scsi_pointer *scsi_pointer = arm_scsi_pointer(SCpnt);
     91
     92	memset(scsi_pointer, 0, sizeof(struct scsi_pointer));
     93
     94	if (scsi_bufflen(SCpnt)) {
     95		unsigned long len = 0;
     96
     97		scsi_pointer->buffer = scsi_sglist(SCpnt);
     98		scsi_pointer->buffers_residual = scsi_sg_count(SCpnt) - 1;
     99		scsi_pointer->ptr = sg_virt(scsi_pointer->buffer);
    100		scsi_pointer->this_residual = scsi_pointer->buffer->length;
    101		scsi_pointer->phase = scsi_bufflen(SCpnt);
    102
    103#ifdef BELT_AND_BRACES
    104		{	/*
    105			 * Calculate correct buffer length.  Some commands
    106			 * come in with the wrong scsi_bufflen.
    107			 */
    108			struct scatterlist *sg;
    109			unsigned i, sg_count = scsi_sg_count(SCpnt);
    110
    111			scsi_for_each_sg(SCpnt, sg, sg_count, i)
    112				len += sg->length;
    113
    114			if (scsi_bufflen(SCpnt) != len) {
    115				printk(KERN_WARNING
    116				       "scsi%d.%c: bad request buffer "
    117				       "length %d, should be %ld\n",
    118					SCpnt->device->host->host_no,
    119					'0' + SCpnt->device->id,
    120					scsi_bufflen(SCpnt), len);
    121				/*
    122				 * FIXME: Totaly naive fixup. We should abort
    123				 * with error
    124				 */
    125				scsi_pointer->phase =
    126					min_t(unsigned long, len,
    127					      scsi_bufflen(SCpnt));
    128			}
    129		}
    130#endif
    131	} else {
    132		scsi_pointer->ptr = NULL;
    133		scsi_pointer->this_residual = 0;
    134		scsi_pointer->phase = 0;
    135	}
    136}